微信小程序支付
微信官方支付文档
1、后台统一下单接口
** * 微信小程序支付统一下单获取支付参数方法 * 在微信小程序前端需要进行微信支付的地方通过request接口调用/mp_id/公众号表mp_id字段/id/ * id参数带上order表的order_id参数请求此地址即可。 * @return json */ public function wxpay($id) { $orderData = ShopOrder::get(['order_sn'=>$id]); trace($orderData,'wxpayorder'); // $mp_id = $params['mp_id'] = $map['mp_id'] = get_mpid(); $mp_id = input('mp_id'); $appinfo = get_mpid_appinfo ( $mp_id ); //获取公众号信息 $cfg = array( 'APPID' => $appinfo['appid'], 'MCHID' => $appinfo['mchid'], 'KEY' => $appinfo['mchkey'], 'APPSECRET' => $appinfo['secret'], 'NOTIFY_URL' => $appinfo['notify_url'], ); WxPayConfig::setConfig($cfg); if (isset($id) && $id != 0) { //商户订单 $outid = $orderData->id.date("YmdHis",time()).rand(0,9); $price = intval($orderData->goods_price*100); //获取用户openid $tools = new JsApiPay(); trace($tools,'wxpayJsApiPay'); //统一下单 $input = new WxPayUnifiedOrder(); $input->setBody($orderData->goods_name); $input->setAttach($orderData->user_id); $input->setOutTradeNo($orderData->order_sn); //建议默认的预支付交易单商户订单号由date("YmdHis").'_'.order_id组成 $input->setTotalFee($price); $input->setTimeStart(date("YmdHis")); $input->setTimeExpire(date("YmdHis", time() + 600)); $input->setGoodsTag("Reward"); $input->setNotifyUrl($appinfo['notify_url']);//设置支付成功回调函数接口 //trace($input,'wxpaynotify_url'); $input->setTradeType("JSAPI"); $input->setOpenid($orderData->pay_code);
//统一下单 $order = WxPayApi::unifiedOrder($input);
//预支付数据生成 $jsApiParameters = $tools->getJsApiParameters($order); //trace($order,'wxpayorder'); //trace($jsApiParameters,'wxpayjsApiParameters'); //写进数据库一些数据 $orderData->prepay_id = $order['prepay_id']; $orderData->save(); return $jsApiParameters;//返回数据给小程序端 } }
2、改写支付成功后的回调函数
//重写回调处理方法,成功的时候返回true,失败返回false,处理商城订单 public function NotifyProcess($data, &$msg) { if(!array_key_exists("transaction_id", $data)){ $msg = "输入参数不正确"; return false; } //查询订单,判断订单真实性 if(!$this->Queryorder($data["transaction_id"])){ $msg = "订单查询失败"; return false; } //以上的代码都是相同的,以下代码写定制业务逻辑,这里实现一个通用订单处理逻辑 $transaction = model('transaction'); // 保存微信支付订单流水 trace($data,'NotifyProcess'); trace($msg,'NotifyProcessmsg'); $transaction->data($data); $transaction->save(); $map["out_trade_no"] = $data["out_trade_no"]; $omap["order_sn"] = $data["out_trade_no"]; trace($omap,'omap111'); // $data["paySta"] = 1; $order = model('shop_order'); $order-> where($omap)->setField(["transaction_id"=>$data["transaction_id"],'order_status'=>1,'add_time'=>date('Y-m-d H:i:S')]); //支付流水号写入订单 SendBuy($omap); return true; }
3、在小程序端向支付接口传递订单参数,并获得返回值调起支付
//生成订单 function generateOrder() { var that = this //统一支付 wx.showToast({ title: '正在处理订单,请稍候...', icon: 'loading', duration: 10000 }) var login = wx.getStorageSync('login') var orderidStorage = wx.getStorageSync('orderid') setTimeout(function () { wx.request({ url: `${app.globalData.API_URL}/id/` + orderidStorage, method: 'post', success: function (res) { //var pay = JSON.parse(res.data); var pay = res.data; //发起支付 console.log(typeof res.data,'支付参数1'); //支付 payFn(pay); }, }) }, 2000) } /* 支付 */ function payFn(param) { wx.hideToast(); wx.requestPayment({ timeStamp: param.timeStamp, nonceStr: param.nonceStr, package: param.package, signType: param.signType, paySign: param.paySign, success: function (res) { wx.navigateBack({ delta: 1, // 回退前 delta(默认为1) 页面 success: function (res) { wx.showToast({ title: '支付成功', icon: 'success', duration: 2000 }) }, fail: function () { // fail }, complete: function () { // complete } }) }, fail: function (res) { // fail console.log("支付失败") console.log(res) wx.showModal({ title: '提示', content: '支付失败', }) return }, complete: function () { } }) }
注意:
1、签名MD5加密,网上有些算法是错误的,自己写完还需要在线MD5加密工具进行校验(
2、签名规则注意事项(must)
◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
3、统一下单签名appid,wx.requestPayment签名appId(大小写必须区分,真是找瞎我钛合金狗眼- - )
4、wx.requestPayment中package参数必须是package:"prepay_id=wx21**************",不然,会出现调用支付JSAPI缺少appid/total_fee
5、total_fee为分,并且是int
6、生成随机数和时间戳一定要保证签名与上传参数一致。
7、大小写。。一定要注意
8、微信小程序trade_type=JSAPI,openid参数必传
9、wx.requestPayment生成签名有appId,请求的时候没有appId