微信公众号支付 H5 + JSAPI 拉起支付

667 阅读2分钟

需求:

微信公众号支付 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…