需求:
微信公众号支付 H5 + JSAPI 拉起支付
解析:
1、需要服务端使用JSAPI 下单的方式进行下单
2、前端在H5中拉起微信的JSAPI支付,不能直接使用链接的方式拉起
3、前端JSAPI 微信支付,可使用的方式:WeixinJSBridge.invoke、wx.chooseWXPay
4、因为原来已经写过了微信小程序的支付了,可以复用 服务端的代码 直接使用WeixinJSBridge.invoke方式拉起微信公众号H5的支付
具体的代码:
1、服务端代码
$param = [
'appid'=>Config::appid,//string merchantId 商户id
'mch_id'=>Config::mch_id,//string merchantKey
'sub_appid'=>'这里是公众号的APPID',
'sub_mch_id'=>Config::sub_mch_id,//商户号
'out_trade_no'=>$this->pay->get_created_sup_sn(),//提交给供应商的订单编号
'nonce_str'=>Helper::getQyPayId(),
'sign_type'=>'MD5',
//商品简单描述,该字段须严格按照规范传递,具体请见参数规定
'body'=>$this->order->get_title(),
'total_fee'=>$this->order->get_price(),
//支持IPV4和IPV6两种格式的IP地址。调用微信支付API的机器IP
'spbill_create_ip'=>$this->order->get_client_ip(),
//
'notify_url'=>Config::jsapi_notify_url,
'trade_type'=>'JSAPI',
//trade_type=JSAPI,此参数必传,用户在子商户appid下的唯一标识。openid和sub_openid可以选传其中之一,
//如果选择传sub_openid,则必须传sub_appid。下单前需要调用【获取openid】接口获取到用户的Openid。
// 'openid'=>$this->order->get_open_id(),
'sub_openid'=>$this->order->get_open_id()
];
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
ksort($param);
$enString = '';
foreach ($param as $item=>$value){
$enString .= $item.'='.$value.'&';
}
$enString .= 'key='.Config::api_key;
$param['sign'] = strtoupper(md5($enString));
$post = Helper::array_to_xml($param);
$resp = $this->curl($url,$post);
$jsonDada = json_encode(simplexml_load_string($resp, 'SimpleXMLElement', LIBXML_NOCDATA));
$data_arr = json_decode($jsonDada,true);
if(isset($data_arr['result_code']) && $data_arr['result_code'] == 'SUCCESS'){
// jsapi 调起支付返回数据
$prepay_id = $data_arr['prepay_id'];
$app_id = '';//公众号的APPID
$app_data = [
'nonceStr'=>Helper::getQyPayId(),
'package'=>'prepay_id='.$prepay_id,
'appId'=>$app_id,
'timeStamp'=>time(),
'signType'=>'MD5',
];
ksort($app_data);
$enString = '';
foreach ($app_data as $item=>$value){
$enString .= $item.'='.$value.'&';
}
$enString .= 'key='.Config::api_key;
$app_data['paySign'] = strtoupper(md5($enString));
$this->pay->set_h5_url(
$app_data
);
return true;
}
2、服务端返回前端的数据:
"appId": "", //公众号ID,由商户传入
"timeStamp": res.data.data.h5_url.timeStamp + "", //时间戳,自1970年以来的秒数
"nonceStr": res.data.data.h5_url.nonceStr, //随机串
"package": res.data.data.h5_url.package,
"signType": res.data.data.h5_url.signType, //微信签名方式:
"paySign": res.data.data.h5_url.paySign //微信签名
3、前端拉起微信公众号支付的代码
var payParams = {
"appId": "", //公众号ID,由商户传入
"timeStamp": res.data.data.h5_url.timeStamp + "", //时间戳,自1970年以来的秒数
"nonceStr": res.data.data.h5_url.nonceStr, //随机串
"package": res.data.data.h5_url.package,
"signType": res.data.data.h5_url.signType, //微信签名方式:
"paySign": res.data.data.h5_url.paySign //微信签名
// "redirectUrl": encodeURIComponent('')
};
WeixinJSBridge.invoke('getBrandWCPayRequest', payParams,
function(res) {
if (res.err_msg === "get_brand_wcpay_request:ok") {
// 支付成功,可以添加一些用户反馈
// uni.showToast({
// title: '购买成功',
// icon: 'none',
// duration: 1500
// });
wx.showModal({
title: '支付结果',
content: '购买成功!',
showCancel: false,
success (res) {
if (res.confirm) {
// 用户确认后可以进行页面跳转或其他操作
//更新会员信息
if (uni.getStorageSync('phone') && uni.getStorageSync('authorization')) {
queryUserPage();
}
}
}
});
} else {
// 支付失败,可以提示用户重新尝试
uni.showToast({
title: '支付失败,请重新拉起支付!',
icon: 'none',
duration: 2000
});
// 可以在这里添加重试支付的逻辑
}
}
);
4、拉起支付完成 点击完成结束整个流程,但是点击完成没有回到原始公众号H5页面,可以参考文档:juejin.cn/post/747850…