最近模板兔在给一个客户做小程序里的支付,基于erphpdown插件的功能,小程序里实现微信支付升级VIP。
整个流程
1.打开某小程序,点击直接下单。
2.wx.login获取用户临时登录凭证code,发送到后端服务器换取openId。
3.在下单时,小程序需要将购买的商品Id,商品数量,以及用户的openId传送到服务器。
4.服务器在接收到商品Id、商品数量、openId后,生成服务期订单数据,同时经过一定的签名算法,向微信支付发送请求,获取预付单信息(prepay_id),
同时将获取的数据再次进行相应规则的签名,向小程序端响应必要的信息。
5.小程序端在获取对应的参数后,调用wx.requestPayment()发起微信支付,唤醒支付工作台,进行支付。
6.接下来的一些列操作都是由用户来操作的包括了微信支付密码,指纹等验证,确认支付之后执行鉴权调起支付。
7.鉴权调起支付:在微信后台进行鉴权,微信后台直接返回给前端支付的结果,前端收到返回数据后对支付结果进行展示。
8.推送支付结果:微信后台在给前端返回支付的结果后,也会向后台也返回一个支付结果,后台通过这个支付结果来更新订单的状态。
小程序支付申请条件:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_11&index=2
注意:
appid与appsecret必须为最后拉起收银台的小程序appid与appsecret;
mch_id为和appid成对绑定的支付商户号,收款资金会进入该商户号;
trade_type请填写JSAPI;
openid为appid对应的用户标识,即使用wx.login接口获得的openid
支付填写的接口是小程序绑定的商户号接口(进小程序后台后开通支付,绑定商户号),不是erphpdown里设置的接口(公众号绑定的商户号)。不过你可以都绑定同一个商户号,那商户号就是一样,商户支付密钥(KEY)也就是一样了!
在开发的过程中遇到了验签错误的Bug,困扰了几个小时,就是wx.requestPayment请求时会提示支付验证签名失败。
逻辑就是在小程序里请求服务端,传uid以及openid以及VIP类型。
服务端代码
require_once "weixin/lib/WxPay.Api.php"; require_once "weixin/lib/WxPay.JsApiPay.php"; $date = date("YmdHis"); //$tools = new JsApiPay(); //$openId = $tools->GetOpenid(); $input = new WxPayUnifiedOrder(); $input->SetBody('VIP订单'); $input->SetAttach("ERPHP"); $input->SetOut_trade_no($out_trade_no); $input->SetTotal_fee($price*100); $input->SetTime_start($date); //$input->SetTime_expire(date("YmdHis", time() + 600)); $input->SetGoods_tag("MBT"); $input->SetNotify_url(你的notify地址); $input->SetTrade_type("JSAPI"); $input->SetOpenid($openid);//注意这里的openid是小程序里传过来的 $order = WxPayApi::unifiedOrder($input); //echo json_encode($order);exit; $payNewSign = strtoupper(md5('appId='.$order['appid'].'&nonceStr='.$order['nonce_str'].'&package='.'prepay_id='.$order['prepay_id'].'&signType=MD5&timeStamp='.strtotime($date).'&key='.get_option('ice_weixin_key')));//这个paySign重新生成,不能直接用$order['sign'] echo json_encode(array_merge($order,array("timeStamp"=>strtotime($date),"payNewSign"=>$payNewSign)));exit;
小程序端代码
wx.requestPayment({ timeStamp: res.data.timeStamp.toString(), nonceStr: res.data.nonce_str, package: 'prepay_id='+res.data.prepay_id, signType: 'MD5', paySign: res.data.payNewSign, //不是res.data.sign 巨坑 success (res) { wx.showModal({ title: '温馨提示', content: '升级VIP成功!', confirmText: '好的', showCancel: false, success (res) { if (res.confirm) { that.onLoad(); } } }) }, fail (res) { wx.showToast({ title: '支付失败', icon: 'none', duration: 2000 }) } })
0 个评论