当前位置 博文首页 > 文章内容

    一文详解PHP如何接入微信支付分(代码示例)

    作者:shunshunshun18 栏目:未分类 时间:2021-09-17 10:43:06

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    一、微信支付分介绍及开通

    1. 产品介绍:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_0.shtml
    2. 接入前准备:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_1.shtml
    3. 测试号配置:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_5.shtml

    二、免确认模式开发

    参考网址:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_1_3.shtml

    • 步骤1 用户在商户侧下单购买产品或服务,此时,我们需要先对用户的授权状态进行查询
    • 步骤2 引导用户开启授权服务
    • 步骤3 创建支付分订单
    • 步骤4 商户为用户提供服务,待服务结束后,商户调用完结订单接口完结当前订单。
    • 步骤5 收到用户扣款成功通知,业务流程结束

    三、SDK相关

    1. 官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml
    2. wechatpay-php(推荐):https://github.com/wechatpay-apiv3/wechatpay-php

    四、代码示例

    /**
         * 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 '';
            }
        }

    完结支付分订单、取消支付分订单、查询支付分订单 类似,这里不再写出来。

    /**
         * 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',
                ];
            }
        }

    五、注意事项

    1. 严格遵循文档中的参数要求,出现问题第一时间比较传入参数和官方示例的区别
    2. 支付分订单必须取消,或完结

    推荐学习:《》