统一下单
private $appid;
private $secret;
private $mch_id;
private $key;
private $serial_no;
const KEY_LENGTH_BYTE = 32;
const AUTH_TAG_LENGTH_BYTE = 16;
protected function _initialize()
{
$this->appid = config('xj_mp.appid');
$this->secret = config('xj_mp.secret');
$this->mch_id = config('xj_mp.mch_id');
$this->key = config('xj_mp.key');
$this->serial_no = config('xj_mp.serial_no');
}
public function unifiedOrder($product_type = 1, $openid = '', $phone = '')
{
$total_fee = 79900;
if ($product_type == 1) {
$total_fee = 79900;
}
if ($product_type == 2) {
$total_fee = 99900;
}
$money = $total_fee;
$url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
$urlarr = parse_url($url);
$appid = $this->appid;
$mchid = $this->mch_id;;
$xlid = $this->serial_no;
$data = [];
$time = time();
$data['appid'] = $appid;
$data['mchid'] = $mchid;
$data['description'] = '描述';
$data['out_trade_no'] = $phone . '_' . time() . '_xingji';
$data['notify_url'] = $this->request()->domain() . "api/xjmpzl/notify";
$data['amount']['total'] = $money;
$data['payer']['openid'] = $openid;
$data = json_encode($data);
$noncestr = $time;
$key = $this->getSign($data, $urlarr['path'], $noncestr, $time);
$token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%d",signature="%s"', $mchid, $xlid, $noncestr, $time, $key);
$header = [
'Content-Type:' . 'application/json; charset=UTF-8',
'Accept:application/json',
'User-Agent:*/*',
'Authorization: WECHATPAY2-SHA256-RSA2048 ' . $token
];
$ret = $this->curl_post_https($url, $data, $header);
$ret = ltrim($ret, '{"prepay_id":"');
$ret = rtrim($ret, '}"');
$str = $this->getWechartSign($appid, time(), $noncestr, 'prepay_id=' . $ret);
$arr = [
'appId' => $appid,
'timeStamp' => time() . "",
'package' => 'prepay_id=' . $ret,
'paySign' => $str,
'nonceStr' => $noncestr . ""
];
$this->success('success', $arr);
}
public function getSign($data = [], $url, $randstr, $time)
{
$str = "POST" . "\n" . $url . "\n" . $time . "\n" . $randstr . "\n" . $data . "\n";
$key = file_get_contents('apiclient_key.pem');
$str = $this->getSha256WithRSA($str, $key);
return $str;
}
public function getWechartSign($appid, $timeStamp, $noncestr, $prepay_id)
{
$str = $appid . "\n" . $timeStamp . "\n" . $noncestr . "\n" . $prepay_id . "\n";
$key = file_get_contents('apiclient_key.pem');
$str = $this->getSha256WithRSA($str, $key);
return $str;
}
public function getSha256WithRSA($content, $privateKey)
{
$binary_signature = "";
$algo = "SHA256";
openssl_sign($content, $binary_signature, $privateKey, $algo);
$sign = base64_encode($binary_signature);
return $sign;
}
public function curl_post_https($url, $data, $header)
{
$action = curl_init();
curl_setopt($action, CURLOPT_URL, $url);
curl_setopt($action, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($action, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($action, CURLOPT_HEADER, 0);
curl_setopt($action, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($action, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($action, CURLOPT_POST, 1);
curl_setopt($action, CURLOPT_POSTFIELDS, $data);
curl_setopt($action, CURLOPT_HTTPHEADER, $header);
$result = curl_exec($action);
curl_close($action);
return $result;
}
public function notify()
{
$testxml = file_get_contents("php://input");
$res = json_decode($testxml, true);
$decode_data = $res['resource'];
$associatedData = $decode_data['associated_data'];
$nonceStr = $decode_data['nonce'];
$ciphertext = $decode_data['ciphertext'];
$ciphertext = \base64_decode($ciphertext);
if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
$ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);
$authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);
$result = \openssl_decrypt($ctext, 'aes-256-gcm', $this->key, \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData);
}
file_log("mp_pay_notify_content.log", $result);
$result = json_decode($result,true);
echo ' ';
}
小程序端
uni.request({
url: '后端下单地址',
method: 'GET',
data: {
product_type: this.product_type,
openid: this.openid,
phone: this.phone
},
success: (cts) => {
var result = cts.data.data
let that = this
uni.requestPayment({
appId: result.appId,
timeStamp: result.timeStamp,
nonceStr: result.nonceStr,
package: result.package,
signType: 'RSA',
paySign: result.paySign,
success(res) {
if (res.errMsg === 'requestPayment:ok') {
uni.navigateTo({
url: "/pages/index/order?phone=" + that.phone
})
}
},
fail(err) {
console.log("支付失败", err)
}
})
}
});