微信小程序-微信支付详细介绍(Thinkphp后端代码)

版权声明:来自MarieDreamer https://blog.csdn.net/qq_33514421/article/details/83108506

流程

如微信支付的文档,不再多说

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=3

一一分析一下每一步我们具体要做什么:

1、小程序内调用登录接口,获取到用户的openid,api参见公共api【小程序登录API

一般我们在数据库保存了用户openid,所以我们是去数据库取。

2、商户server调用支付统一下单,api参见公共api【统一下单API

 这一步是拿到用户openid、订单详情等文档中要求的信息后,转换成xml格式(转换格式是有微信接口的),调用微信封装好的统一下单接口,便会返回包含prepay_id的一些参数。

3、商户server调用再次签名,api参见公共api【再次签名

 我认为这个步骤名称写的不好,“再次签名”的链接打开,标题写的却是调起支付API。实际上分两步:再次签名、调起支付API。就是说,获取到上一步的一些参数后,按照签名算法处理数据,然后调用微信API再次签名,这样就有了签名参数。最后将被要求的参数填入调起支付API就可以了。

4、商户server接收支付通知,api参见公共api【支付结果通知API

在第二步的xml中要求填入我们服务器上的通知地址,这样第三步的微信支付结果就会发送到这个地址。 在这个方法里面,我们要校对微信发来的支付结果是哪个订单的,然后可以修改订单的支付状态,还要返回给微信接受成功的xml信息,不然微信会一直发通知过来。

扫描二维码关注公众号,回复: 3639887 查看本文章

5、商户server查询支付结果,api参见公共api【查询订单API

查询支付订单详情见文章最后一块代码。

准备工作

首先小程序要绑定商户,不然没法做也没法测试。

开通微信支付后,下载微信支付API的包(我用的是PHP)

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

前端

用户已下单(还未付款),当用户点击付款时,执行PayOrder函数。

函数主要有三个请求接口:Order/get获取订单详情(省略)、Order/getPrepay(统一下单/再次签名/支付通知)、wx.requestPayment(发起微信支付)。

PayOrder: function(t) {
        var that = this;
        var order_id = t.currentTarget.dataset.id;//订单id
        wx.request({
          url: 'https://XX.com/Order/get',//这是获取订单详情的请求
          data:{
            id:order_id 
          },
          success:function(a){
            //统一下单并再次签名
            wx.request({
              url: 'https://wechat.cdd.jianfengweb.com/Order/getPrepay',
              data: {
                total_fee: a.data.data.total_price*100,
                order_number: a.data.data.order_number,
              },
              success: function (res) {
                // 返回参数和sign后调起微信支付
                wx.requestPayment(
                  {
                    'timeStamp': new Date().getTime().toString(),
                    'nonceStr': res.data.data['nonce_str'],
                    'package': "prepay_id=" + res.data.data['prepay_id'],
                    'signType': 'MD5',
                    'paySign': res.data.data['sign'],
                    'success': function (e) {
                      console.log('success')
                    },
                    'fail': function (e) {
                      console.log(e)
                    },
                    'complete': function (e) { }
                  })
              }
            })
          }
        })
    }

后端

Order/getPrepay方法(统一下单、再次签名)

public function getPrepay()
    {
        extract(generateRequestParamVars());
        //获取openid
        $user = D(self::$WECHAT_USER_MODEL)->find($user_id);
        $openid = $user['openid'];

        //引用微信支付API
        require_once C('APPLICATION_DIR') . '/Home/Libs/WechatPay/lib/WxPay.Api.php';
        require_once C('APPLICATION_DIR') . '/Home/Libs/WechatPay/lib/WxPay.Notify.php';
        require_once C('APPLICATION_DIR') . '/Home/Libs/WechatPay/lib/WxPay.Data.php';
        require_once C('APPLICATION_DIR') . '/Home/Libs/WechatPay/example/log.php';
        require_once C('APPLICATION_DIR') . '/Home/Libs/WechatPay/example/WxPay.NativePay.php';
        require_once C('APPLICATION_DIR') . '/Home/Libs/WechatPay/example/WxPay.JsApiPay.php';

        // WxPayUnifiedOrder类会直接设置xml
        $xml = new \WxPayUnifiedOrder();
        $xml->SetBody("购买商品");
        $xml->SetAttach("attach");
        $xml->SetOpenid($openid);
        $xml->SetOut_trade_no($product_id);
        $xml->SetTotal_fee($total_fee * 100);
        $xml->SetTime_start(date("YmdHis", time()));
        $xml->SetTime_expire(date("YmdHis", time() + 600));
        $xml->SetNotify_url("https://XX.com/Order/getNotify");
        $xml->SetGoods_tag("goods_tag");
        $xml->SetTrade_type("JSAPI");

        //统一下单(获取prepay_id)
        $nativepay = new \NativePay();
        $result = $nativepay->GetPayUrl($xml);

        //再次签名
        $sign_array = array();
        $sign_array['appId'] = $result['appid'];
        $sign_array['nonceStr'] = $result['nonce_str'];
        $sign_array['package'] = 'prepay_id=' . $result['prepay_id'];
        $sign_array['signType'] = 'MD5';
        $sign_array['timeStamp'] = floor($result['startTimeStamp'] / 1000);

        $sign = new \WxPayDataBase();
        $sign_two = $sign->MakeSigns($sign_array);
        $result['paySign'] = $sign_two;

        $ajaxReturnData['data'] = $result;
        $this->ajaxReturn($ajaxReturnData);
    }

Order/getNotify方法(接收微信通知)

public function getNotify()
    {
        $xmlData = file_get_contents('php://input');
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xmlData, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        ksort($data);
        $buff = '';
        foreach ($data as $k => $v) {
            if ($k != 'sign') {
                $buff .= $k . '=' . $v . '&';
            }
        }

        $save = [];
        foreach ($data as $k => $v) {
            $save['key'] = $k . '';
            $save['value'] = $v . '';
            D(self::$NOTIFY_TEST)->add($save);
        }

        $stringSignTemp = $buff . 'key=1d8r14jiu58fs12qsd824j1o52d8r14c';//key为证书密钥
        $sign = strtoupper(md5($stringSignTemp));

        $conditions = [];
        $conditions['order_number'] = $data['out_trade_no'];
        $order = D(self::$ORDER_MODEL)->where($conditions)->find();

        //判断算出的签名和通知信息的签名是否一致
        if ($order && $sign == $data['sign'] && $order['total_price']*100 == $data['total_fee']) {
            $test = [];
            $test['key'] = '校验是否成功';
            $test['value'] = 'yes';
            D(self::$NOTIFY_TEST)->add($test);

            $order_data = [];
            $order_data['shop_status'] = 1;
            D(self::$ORDER_MODEL)->where($conditions)->save($order_data);

            //处理完成之后,告诉微信成功结果
            echo '<xml>
                    <return_code><![CDATA[SUCCESS]]></return_code>
                    <return_msg><![CDATA[OK]]></return_msg>
                  </xml>';
            exit();
        }else{
            echo '<xml>
                    <return_code><![CDATA[FAIL]]></return_code>
                    <return_msg><![CDATA[FAIL]]></return_msg>
                  </xml>';
            exit();
        }
    }

 Order/findOrder方法(查询支付订单)

public function findOrder()
    {
        try{
            extract(generateRequestParamVars());
            require_once C('APPLICATION_DIR') . '/Home/Libs/WechatPay/lib/WxPay.Api.php';
            $input = new \WxPayOrderQuery();
            $input->SetOut_trade_no($order_number); // 设置好要查询的订单
            $order = \WxPayApi::orderQuery($input); // 进行查询

            $ajaxReturnData['status'] = 1;
            $ajaxReturnData['message'] = '操作成功';
            $ajaxReturnData['data'] = $order;
        }catch (\Exception $e){
            $ajaxReturnData['status'] = 0;
            $ajaxReturnData['message'] = '操作失败' . $e->getMessage();
        }
        $this->ajaxReturn($ajaxReturnData);
    }

猜你喜欢

转载自blog.csdn.net/qq_33514421/article/details/83108506