前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP 接入微信支付分

PHP 接入微信支付分

作者头像
泥豆芽儿 MT
发布2023-10-16 19:19:41
2760
发布2023-10-16 19:19:41
举报
文章被收录于专栏:木头编程 - moTzxx

♦ 背景

  • 最近项目中需要接入【微信支付分】的服务, 本文以 【免确认订单模式】:即先享模式(评估不通过不可使用服务)的使用 在此做一下实现步骤,希望能对小伙伴有所帮助,欢迎指摘 … 实现语言:PHP

官方文档,请参考:【>>> 微信支付分产品介绍】


☞ 前期准备

可直接参考指导文档 【>>>接入前准备】

    1. 首先商户向 weixinpay_scoreBD@tencent.com 发送邮件接入申请 一般都由 产品负责人员进行申请, 作为开发人员,重点在于阅读开发文档,编写测试用例
    1. 接口调用权限说明 此处引用官方解释如下:
代码语言:javascript
复制
【免确认订单模式】是高级接口权限,需特殊申请才能使用。
 使用支付分的行业/场景,目前只能调用【需确认订单模式】接口。
 
 接口调用权限与服务id相关,在申请服务id时,只有上述场景下的服务 id,才有权限调用【免确认订单模式】接口。
 即只有在上述场景下,创建支付分订单 api 接口中 need_user_confirm 字段才能传。
 false:免确认订单。

以【免确认订单模式】为例,用户使用流程如下:

代码语言:javascript
复制
首次使用,用户先从商户端(小程序/app/H5),跳入微信支付分页面,进行商户服务的授权
授权成功后,商户即可通过后台接口,进行支付分订单的创建和完结。用户无需再进入支付分授权页面进行授权。
    1. 测试号配置指引

一般正式开发前,需进行 【>>> 微信支付分测试号配置指引】


☛ 开发指引

再次提醒,以【免确认模式】开发操作为例

  • 流程分析
代码语言:javascript
复制
1. 首先,用户在商户侧下单购买产品或服务,此时,我们需要先对用户的授权状态进行查询
2. 引导用户开启授权服务
	这一步需要根据实际场景,比如:APP场景调起支付分-授权服务、H5场景调起支付分-授权服务、小程序调起支付分-授权服务
3. 创建支付分订单
4. 商户为用户提供服务,待服务结束后,商户调用完结订单接口完结当前订单
5. 收到用户扣款成功通知,业务流程结束

▷ 第一步 引导用户开启授权服务

这一步需要前端的页面设计,主要在于引导开启授权服务

▷ 第二步 签名生成

服务端接口编写前,我们需要成功使用 微信官方要求的 >>>【签名规则】

  • 请求签名串的构造规则如下:
  • 通过参考文档,可以封装出一个方法,方便后期接口请求的使用 如下,即为鄙人整理的 HTTP Header 头 封装方法:
代码语言:javascript
复制
	/**
     * @Notes:	签名封装方法
     * @param $url      请求接口链接地址
     * @param $type     请求方法 GET/POST
     * @param $bodys    请求主体 json_encode() 处理后的字符串
     * @return mixed
     * @User: zhanghj
     * @DateTime: 2023-08-31 18:18
     */
    public function getToken($url,$type,$bodys= ''){
        //请求头
        $arr_header[] = "Content-Type: application/json";
        $arr_header[] = "Accept: application/json";
        $arr_header[] = "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36" ;
        //生成签名
        $http_method = $type;
        $timestamp = time();
        $nonce = $this->createNoncestr(32);
        $body = $bodys;
        $merchant_id = "XXXXXXXXXXXXXXXXX";  //商户号
        $serial_no = "NNNNNNNNNNNNNNNNNNNNNNNNNN"; //这个是证书号  这个必须使用新版证书
        $url_parts = parse_url($url);
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        $message = $http_method . "\n" .
            $canonical_url . "\n" .
            $timestamp . "\n" .
            $nonce . "\n" .
            $body . "\n";
        openssl_sign($message, $raw_sign, PayConfig::PrivateKey, 'sha256WithRSAEncryption');
        $sign = base64_encode($raw_sign);
        $schema = 'WECHATPAY2-SHA256-RSA2048 ';
        $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
            $merchant_id, $nonce, $timestamp, $serial_no, $sign);
        $arr_header[] = "Authorization:" . $schema . $token;
        return $arr_header;
    }
    
    //作用:产生随机字符串,不长于 32 位
    public function createNoncestr($length = 32) {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        $result_ = strtoupper($str);
        return $result_;
    }

▷ 第三步 接口请求用例

以 “创建支付分订单” 为例,代码参考如下:

  • 基本的接口调用用例如下:
代码语言:javascript
复制
		$url = 'https://api.mch.weixin.qq.com/v3/payscore/serviceorder';
		$data = array(
            'out_order_no'=>$orderSn,
            'appid' => PayConfig::AppId,//公众号
            'service_id' =>$wxPayConf['service_id'],//服务id
            'service_introduction'=>'智慧零售',
            'risk_fund'=>array(
                'name'=>'ESTIMATE_ORDER_COST',
                'amount'=>20000,
            ),
            'location'=>array(
                'start_location'=>'江苏省苏州市创意产业园15-303',
            ),
            'time_range'=>array(
                'start_time'=>'OnAccept',
            ),
            'need_user_confirm'=>false,
            'notify_url'=>'http://xxxxxxxxxxxxx/order/wx_pay_notify', //回调地址
        );
		$arr_header = $this->getToken($url,'POST',json_encode($data,JSON_UNESCAPED_UNICODE));
        $res = $this->posturl($url, json_encode($data,JSON_UNESCAPED_UNICODE), $arr_header);
        $res_arr = json_decode($res, true);

【提示】:可根据返回参数 "state",对支付分订单作符合业务的处理

  • 此处提供一个 CURL POST 请求处理方法
代码语言:javascript
复制
 public function posturl($url, $data = null, $arr_header = []){
        $curl = curl_init();
        // curl 设置
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        // 判断 $data get  or post
        if ( !empty($data) ) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }

        if (!empty($arr_header)) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $arr_header);
        }

        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        // 执行
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

▷ 第四步 支付成功回调通知 API

微信支付分通过支付成功通知接口将用户支付成功消息通知给商户

  • 【提示】 一般在此回调接口位置, 根据返回的订单号out_order_no,以及状态 state="DONE" 对商家应用的订单,处理最后的更新操作逻辑 同时,注意保存 微信服务端返回的支付信息,比如字段:transaction_id,方便后期的退款操作

▶ 附录

  • 简单场景中,常用的功能就是:
代码语言:javascript
复制
  创建支付分订单
  取消支付分订单
  完结支付分订单
  支付成功回调通知
  申请退款、退款结果通知
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ♦ 背景
  • ☞ 前期准备
  • ☛ 开发指引
    • ▷ 第一步 引导用户开启授权服务
      • ▷ 第二步 签名生成
        • ▷ 第三步 接口请求用例
          • ▷ 第四步 支付成功回调通知 API
          • ▶ 附录
          相关产品与服务
          云开发 CloudBase
          云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档