最近开发了小程序版的微信支付,遇到的情况与之前h5 略有不同。 其流程大致为:前端wx.login() 获得code ,后端通过code 获取openid 并利用openid 生成预支编号prepay_id ,前端wx.requestPayment() 利用prepay_id 执行支付。 因为之前已写过二期native 和h5 的开发,所以本篇直接按照流程来写一写小程序支付的开发。
参考前两篇: 微信开发 ━━ 微信商户v3微信支付H5方式开发之php篇 微信开发 ━━ 微信商户v3微信支付Navive方式开发之php篇
一、获取code(前端)
小程序支付所用openid 只能由后端利用前端提供的code 向微信索取。
wx.login({
success: (res) => {
const code = res.code;
}
});
二、获取openid(后端)
将code 传入服务端,服务端向微信索取openid ,这里用php 举例。
$appid = 'wxaaabbbcccddd';
$secret = '123456789abcdefghijklmn';
$code = $_POST['code'];
$openid = getUserOpenid($appid, $secret, $code);
function getUserOpenid($appid, $secret, $code)
{
$url = "https://api.weixin.qq.com/sns/jscode2session?".
"grant_type=authorization_code&appid=$appid&secret=$secret&js_code=$code";
$res = httpRequest($url);
$data = json_decode($res,true);
$openid = $data['openid'];
return $openid;
}
三、获取预支编号 - 生成签名 - 返回支付参数(后端)
这一步主要目的就是把金额等信息加密后提交给微信,生成一个等待支付的id号(预支编号:prepay_id )。 其中的加密签名标准需要严格符合要求。
$openid = 'ab1234567890abcdefghijklmn';
$appid = 'wxaaabbbcccddd';
$mchid= '123456789abcdefghijklmn';
$xlid = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
$apiclient_key = 'apiclient_key.pem';
$time = time();
$orderid = 'orderid_1234567890abcdefghijklmn';
$noncestr = $orderid;
$ordertotal = 123.45*100;
$url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi';
$urlarr = parse_url($url);
$data = array();
$data['appid'] = $appid;
$data['mchid'] = $mchid;
$data['description'] = '我的商品大又壮';
$data['out_trade_no'] = $orderid;
$data['notify_url'] = "http://www.csdn.net/notify.html";
$data['amount']['total'] = (integer)$ordertotal;
$data['scene_info']['payer_client_ip'] = '0.0.0.0';
$data['payer']['openid'] =$openid;
$jsonData = json_encode($data);
$str = "POST"."\n".$urlarr['path']."\n".$time."\n".$noncestr."\n".$jsonData."\n";
$signHead = getSign($str);
$token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%d",signature="%s"',$mchid,$xlid,$noncestr,$time,$signHead);
$header = array(
'Content-Type:application/json; charset=UTF-8',
'Accept:application/json',
'User-Agent:*/*',
'Authorization:WECHATPAY2-SHA256-RSA2048 '.$token
);
$res = httpRequest($url,$jsonData,$header);
$data = json_decode($res,true);
$prepayID = $data['prepay_id'];
$prepay = 'prepay_id='.$prepayID;
$str = $appid."\n".$time."\n".$noncestr."\n".$prepay."\n";
$signPay = getSign($str);
return array(
'paySign' => $signPay;
'nonceStr' => $noncestr;
'timeStamp' => $time;
'package' => $prepay;
);
function httpRequest($url='',$data='',$header='')
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
if(!empty($data)){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
if(!empty($header)){
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
}
$response = curl_exec($curl);
if (curl_errno($curl)){
echo 'Error:'.curl_error($curl);
}
curl_close($curl);
return $response;
}
function getSign($content)
{
$binary_signature = "";
$key = file_get_contents($apiclient_key);
$algo = "SHA256";
openssl_sign($content, $binary_signature, $privateKey, $algo);
return base64_encode($binary_signature);
}
- 第一次签名将订单号含在其中;
- 第二次签名将预支编号含在其中;
四、支付(前端)
前端将回传的预支编号和签名等参数提交给微信,即可实现支付。
<button @click="click">点击支付</button>
用wx.requestPayment 打开支付界面
function click()
{
wx.requestPayment({
timeStamp: pay.timeStamp,
nonceStr: pay.nonceStr,
package: pay.package,
paySign: pay.paySign,
signType: 'RSA',
success (res) {},
fail (res) {}
})
}
知识点:
|