当前位置:   article > 正文

Thinkphp6微信App支付APIV3对接流程_wechatpay-php thinkphp

wechatpay-php thinkphp
  1. 安装微信支付sdk我这里使用的是wechatpay-php。
    直接使用命令:composer require wechatpay/wechatpay
    安装php微信支付sdk
  2. 生成平台证书,这里取参考微信支付github文档说明
    下载证书工具
    在这里插入图片描述
    生成平台证书
    生成文件
  3. 创建唤起微信支付数据以api接口方式返回给app端。
    public function wechatArousePay()
    {
        $order_id     = $this->request->post('order_id/d', null);
        $order_number = $this->request->post('order_number/s', null);
        if (!$order_id and !$order_number) {
            return self::fail('订单ID或订单号必须存在其中一个');
        }
        $order_map = array(
            ['uid', '=', $this->userinfo['account']],
            ['pay_state', '<>', 20]
        );
        if ($order_id) {//订单ID
            $order_map[] = ['order_id', '=', $order_id];
        }
        if ($order_number) {//订单号
            $order_map[] = ['order_number', '=', $order_number];
        }
        $order_info = Order::where($order_map)->find();
        if (!$order_info) {
            return self::fail('该项目不存在或已支付');
        }
        if ($order_info['total_price'] <= 0) {
            return self::fail('订单支付金额不合法!');
        }
        $PaymentAmount = bcmul($order_info['total_price'], 100, 0);
        // 商户号,假定为`1000100`
        $merchantId = config('wechatpay.mch_id');
        // 商户私钥,文件路径假定为 `/path/to/merchant/apiclient_key.pem`
        // 这里是微信商户端生成的私钥将整个文件放在wechatpay文件夹下
        $merchantPrivateKeyFilePath = public_path() . 'wechatpay/apiclient_key.pem';
        // 加载商户私钥
        $merchantPrivateKeyInstance = PemUtil::loadPrivateKey($merchantPrivateKeyFilePath);
        // 商户证书,文件路径假定为 `/path/to/merchant/apiclient_cert.pem`
        // 这里是微信商户端生成的公钥将整个文件放在wechatpay文件夹下
        $merchantCertificateFilePath = public_path() . 'wechatpay/apiclient_cert.pem';
        // 加载商户证书
        $merchantCertificateInstance = PemUtil::loadCertificate($merchantCertificateFilePath);
        // 解析商户证书序列号
        $merchantCertificateSerial = PemUtil::parseCertificateSerialNo($merchantCertificateInstance);
        // 平台证书,可由下载器 `./bin/CertificateDownloader.php` 生成并假定保存为 `/path/to/wechatpay/cert.pem`
        $platformCertificateFilePath = public_path() . 'wechatpay/cert.pem';
        // 加载平台证书
        $platformCertificateInstance = PemUtil::loadCertificate($platformCertificateFilePath);
        // 解析平台证书序列号
        $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateInstance);
        // 工厂方法构造一个实例
        $instance = Builder::factory([
            'mchid'      => $merchantId,
            'serial'     => $merchantCertificateSerial,
            'privateKey' => $merchantPrivateKeyInstance,
            'certs'      => [
                $platformCertificateSerial => $platformCertificateInstance,
            ],
        ]);
        try {
            $resp        = $instance
                ->v3->pay->transactions->app
                ->post(['json' => [
                    'appid'        => config('wechatpay.wchat_app_id'),
                    'mchid'        => $merchantId,
                    'description'  => $order_info['remark'],
                    'out_trade_no' => $order_info['order_number'],
                    'notify_url'   => config('wechatpay.notify_url') . '/client/xxxx.ClientPay/weiChatNotify',
                    'amount'       => [
                        'total'    => (int)$PaymentAmount,
                        'currency' => 'CNY'
                    ],
                ]]);
            $result_code = $resp->getStatusCode();
            if ($result_code == 200) {
                $result_data         = json_decode($resp->getBody(), true);
                $arouse_data         = [
                    'appid'     => config('wechatpay.wchat_app_id'),
                    'partnerid' => $merchantId,
                    'prepayid'  => $result_data['prepay_id'],
                    'package'   => "Sign=WXPay",
                    'noncestr'  => MD5($order_info['order_number']),
                    'timestamp' => get_now_time(),
                ];
                $arouse_data['sign'] = Rsa::sign(
                    Formatter::joinedByLineFeed(...array_values($arouse_data)),
                    $merchantPrivateKeyInstance
                );
                return self::successful('success', $arouse_data);
            }
        } catch (\Exception $exception) {
            // 进行错误处理
            if ($exception instanceof \GuzzleHttp\Exception\RequestException && $exception->hasResponse()) {
                $r = $exception->getResponse();
                return self::result($r->getStatusCode(), $r->getReasonPhrase());
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  1. ApiPost模拟数据。
    在这里插入图片描述
  2. 数据回调。
    public function weiChatNotify()
    {
        //接收返回参数json数据转数组
        $get_content = json_decode(file_get_contents('php://input'), true);
        //将接收到的数据存入文件中
        $file_directory3 = public_path() . '/wei_chat_notify.txt';
        file_put_contents($file_directory3, file_get_contents('php://input'));
        //将接收到的数据解密
        $result_content = AesGcm::decrypt($get_content['resource']['ciphertext'], config('wechatpay.apiv3'), $get_content['resource']['nonce'], $get_content['resource']['associated_data']);
        //将json数据转数组
        $content = json_decode($result_content, true);
        //验签订单
        $result_data = $this->authWeiChatOrder($content);
        if (!$result_data) {
            exit('FAIL');
        }
        $Order = new Order();
        $Order::startTrans();
        $order_info   = $result_data['order'];//订单信息
        $payment_info = $result_data['body'];//订单支付信息
        try {
            $chang_data               = array(
                'pay_state'      => 20,//支付状态
                'pay_style'      => 20,//支付方式
                'pay_time'       => strtotime($payment_info['time_end']),//支付完成时间
                'payment_price'  => bcdiv($payment_info['total_fee'], 100, 2),//支付金额
                'transaction_id' => $payment_info['transaction_id'],//微信支付订单号
                'openid'         => $payment_info['openid'],//微信用户openid
                'notify_json'    => $payment_info
            );
            $chang_data['need_price'] = bcsub($order_info['total_price'], $chang_data['payment_price'], 2);
            $result                   = $Order->where([['order_id', '=', $order_info['order_id']]])->update($chang_data);
            if ($result) {
                $Order::commitTrans();
                exit("SUCCESS");
            }
            throw new Exception('操作失败');
        } catch (\Exception $exception) {
            $Order::rollbackTrans();
            exit("FAIL");
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  1. 订单校验。
    public function authWeiChatOrder(array $arr)
    {
        if (!$arr) {
            return null;
        }
        $order_info = Order::where([['order_number', '=', $arr['out_trade_no']]])->find();
        if (!$order_info) {
            return null;
        }
        $OrderQueryUrl  = 'https://api.mch.weixin.qq.com/pay/orderquery';
        $OrderQueryBody = array_filter([
            'appid'          => config('wechatpay.wchat_app_id'),//String(32) # 必填 # 微信分配的小程序ID',
            'mch_id'         => config('wechatpay.mch_id'),//String(32) # 必填 # 微信支付分配的商户号',
            'transaction_id' => $arr['transaction_id'], // String(32) # 与 out_trade_no 二选一 # 微信的订单号,优先使用',
            'out_trade_no'   => $arr['out_trade_no'],//String(32)#与transaction_id二选一#商户系统内部订单号详见商户订单号',
            'nonce_str'      => MD5($arr['out_trade_no']), // String(32) # 必填 # 随机字符串,不长于32位。推荐随机数生成算法',
            'sign_type'      => 'MD5', // String(32) # 选填 # 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5',
        ]);
        // 生成验证签名
        $OrderQueryBody['sign'] = $this->genSign($OrderQueryBody, config('wechatpay.key'));
        //将数组转xml数据
        $xmlContext = $this->ArrayToXml($OrderQueryBody);
        //post发送请求
        $request = $this->ConnCurlSend($OrderQueryUrl, '', $xmlContext, 'POST');
        //将xml数据转数组
        $reqContext = $this->XmlToArray($request);
        if ($reqContext['return_code'] == 'SUCCESS' && $reqContext['result_code'] == 'SUCCESS' && $reqContext['return_msg'] == 'OK') {
            return [
                'order' => $order_info,
                'body'  => $reqContext,
            ];
        }
        return null;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号