Home >Backend Development >PHP Tutorial >An article explaining in detail how to access WeChat payment points with PHP (code example)

An article explaining in detail how to access WeChat payment points with PHP (code example)

藏色散人
藏色散人forward
2021-09-16 14:02:314721browse

1. Introduction and activation of WeChat payment

  1. Product introduction: https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay /chapter3_1_0.shtml
  2. Preparation before access: https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_1.shtml
  3. Test number configuration: https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_5.shtml

2. Confirmation-free model development

Reference URL: https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_3.shtml

  • Step 1 The user places an order to purchase the product on the merchant side or service, at this time, we need to query the user's authorization status first
  • Step 2 Guide the user to open the authorization service
  • Step 3 Create a payment sub-order
  • Step 4 The merchant is The user provides the service, and after the service is completed, the merchant calls the order completion interface to complete the current order.
  • Step 5: Receive notification of successful deduction from the user, and the business process ends

3. SDK related

  1. Official documents: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml
  2. wechatpay-php (recommended): https://github.com/wechatpay-apiv3/wechatpay- php

4. Code example

/**
     * Notes: 步骤1 用户在商户侧下单购买产品或服务,此时,我们需要先对用户的授权状态进行查询
     * User: XXX
     * DateTime: 2021/7/27 9:59
     */
    public function getAuthStatus(string $cid)
    {
        $openid = $this->getOpenid($cid);
        if (!$openid) {
            return false;
        }
        try {
            $resp = $this->instance->v3->payscore->permissions->openid->{'{openid}'}
                ->get(
                    [
                        'query'  => [
                            'appid'      => $this->appid,
                            'service_id' => $this->serviceId,
                        ],
                        // uri_template 字面量参数
                        'openid' => $openid,
                    ]
                );
            $res = json_decode($resp->getBody()->getContents(), true);
            if ($res['authorization_state'] == 'AVAILABLE') {
                return true;
            } else {
                return false;
            }
        } catch (\Exception $e) {
            return false;
            /*echo($e->getResponse()->getStatusCode());
            // 进行错误处理
            echo $e->getMessage()->getReasonPhrase(), PHP_EOL;
            if ($e instanceof \Psr\Http\Message\ResponseInterface && $e->hasResponse()) {
                echo $e->getResponse()->getStatusCode() . ' ' . $e->getResponse()->getReasonPhrase(), PHP_EOL;
                echo $e->getResponse()->getBody();
            }*/
        }
    }
/**
     * Notes:步骤2 引导用户开启授权服务-获取预授权码
     * User: XXX
     * DateTime: 2021/7/27 18:37
     */
    public function openAuthStatus()
    {
        try {
            $resp = $this->instance->v3->payscore->permissions->post(
                [
                    'json' => [
                        'service_id'         => $this->serviceId,
                        'appid'              => $this->appid,
                        'authorization_code' => $this->getRandStr(12), // 授权协议号,类似订单号
                        //'notify_url'         => 'https://weixin.qq.com/',
                    ]
                ]
            );
            $res = json_decode($resp->getBody(), true);
            return $res['apply_permissions_token'];
        } catch (\Exception $e) {
            // 进行错误处理
            /*if ($e->hasResponse()) {
                echo $e->getResponse()->getBody();
            }*/
            return false;
        }
    }
/**
     * Notes: 步骤3 创建支付分订单
     * User: xxx
     * DateTime: 2021/7/27 19:21
     * @param string $cid     用户ID
     * @param string $orderSn 订单号
     */
    public function makeOrder(string $cid, string $orderSn)
    {
        // 订单信息
        ....
        $openid = $this->getOpenid($cid);
        if (!$openid) {
            return [
                'code' => -1,
                'msg'  => 'openid不可以为空',
            ];
        }

        // 异步通知地址,有时候发现莫名的变成了localhost,这里先固定
        $notiryUrl = route('api.v1.wxpayPointsNotify');

        $json = [
            'out_order_no'         => $orderSn,                                                        // 商户服务订单号
            'appid'                => $this->appid,                                                    // 应用ID
            'service_id'           => $this->serviceId,                                                // 服务ID
            'service_introduction' => '换电费用',                                                          // 服务信息,用于介绍本订单所提供的服务 ,当参数长度超过20个字符时,报错处理
            'time_range'           => [
                'start_time' => $startTime, //'20210729160710',
            ],
            'risk_fund'            => [
                'name'   => 'ESTIMATE_ORDER_COST',         // 风险金名称
                'amount' => 300,                           // 风险金额 数字,必须>0(单位分)
            ],
            'attach'               => $orderSn,// 商户数据包
            'notify_url'           => $notiryUrl,
            'openid'               => $openid,// 用户标识
            'need_user_confirm'    => false,// 是否需要用户确认
        ];

        try {
            $resp = $this->instance->v3->payscore->serviceorder->post(
                [
                    'json' => $json
                ]
            );
            $res = json_decode($resp->getBody(), true);

            // 入库支付分订单
            ...
            return [
                'code' => 0,
                'msg'  => '支付分订单创建完成',
            ];
        } catch (\Exception $e) {
            // 进行错误处理
            if ($e->hasResponse()) {
                $body = $e->getResponse()->getBody();
                if ($body) {
                    return [
                        'code' => -1,
                        'msg'  => (string)$body,
                    ];
                }
            }
            return '';
        }
    }

Completing payment sub-orders, canceling payment sub-orders, and querying payment sub-orders are similar and will not be written out here.

/**
     * Notes: 异步通知
     * User: XXX
     * DateTime: 2021/8/3 14:20
     */
    public function notify()
    {
        // 获取返回的信息
        $responseBody = file_get_contents("php://input");
        $responseArr = json_decode($responseBody, true);
        if ($responseArr) {
            $res = AesGcm::decrypt($responseArr['resource']['ciphertext'], 'xxxapi密钥', $responseArr['resource']['nonce'], $responseArr['resource']['associated_data']);
            $resArr = json_decode($res, true);
            if ($resArr) {
                // 记录日志
                ...
                // 业务逻辑处理
                ...
                // 订单日志记录
               ...
            } else {
                return [
                    'code' => -1,
                    'msg'  => '解析有误',
                ];
            }
        } else {
            return [
                'code' => -1,
                'msg'  => 'nothing post',
            ];
        }
    }

5. Precautions

  1. Strictly follow the parameter requirements in the document, and compare the differences between the incoming parameters and the official examples as soon as possible if there is a problem
  2. Payment points orders must be canceled or completed

Recommended learning: "PHP Video Tutorial"

The above is the detailed content of An article explaining in detail how to access WeChat payment points with PHP (code example). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:learnku.com. If there is any infringement, please contact admin@php.cn delete