站长资讯网
最全最丰富的资讯网站

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

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

  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 PsrHttpMessageResponseInterface && $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. 支付分订单必须取消,或完结

推荐学习:《PHP视频教程》

赞(0)
分享到: 更多 (0)