微信小程序支付

微信官方支付文档
 
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
原文地址:https://www.cnblogs.com/pangxiaox/p/7802815.html