PHP 接入微信支付分

news2024/11/20 9:13:53

♦ 背景

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

    实现语言:PHP

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


☞ 前期准备

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

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

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

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

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


☛ 开发指引

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

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

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

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

▷ 第二步 签名生成

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

  • 请求签名串的构造规则如下:

  • 通过参考文档,可以封装出一个方法,方便后期接口请求的使用
    如下,即为鄙人整理的 HTTP Header 头 封装方法:

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

▷ 第三步 接口请求用例

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

  • 基本的接口调用用例如下:
		$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 请求处理方法
 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,方便后期的退款操作


▶ 附录

  • 简单场景中,常用的功能就是:
  创建支付分订单
  取消支付分订单
  完结支付分订单
  支付成功回调通知
  申请退款、退款结果通知

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/955338.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【NLP】手把手使用PyTorch实现Transformer以及Transformer-XL

手把手使用PyTorch实现Transformer以及Transformer-XL Abstract of Attention is all you need使用PyTorch实现Transformer1. 构建Encoder-Decoder模型1.1 导入依赖库1.2 创建Encoder-Decoder类1.3 创建Generator类 2. 构建Encoder2.1 定义复制模块的函数2.2 创建Encoder2.3 构…

语言基础篇3——学习第一步,Python环境搭建

环境搭建 基础环境搭建 https://www.python.org/downloads/&#xff0c;以Python3.11.5为例&#xff1a; Install for Windows 提供安装程序或者压缩包&#xff0c;安装程序点击下一步即可&#xff0c;压缩包解压即可&#xff0c;注意配置根目录到系统环境变量PATH。 Ins…

uniapp项目实战系列(3):底部导航栏与头部导航栏的配置

目录 系列往期文章&#xff08;点击跳转&#xff09;uniapp项目实战系列(1)&#xff1a;导入数据库&#xff0c;启动后端服务&#xff0c;开启代码托管&#xff08;点击跳转&#xff09;uniapp项目实战系列(2)&#xff1a;新建项目&#xff0c;项目搭建&#xff0c;微信开发工具…

MySQL— 基础语法大全及操作演示!!!(事务)

MySQL—— 基础语法大全及操作演示&#xff08;事务&#xff09; 六、事务6.1 事务简介6.2 事务操作6.2.1 未控制事务6.2.2 控制事务一6.2.3 控制事务二 6.3 事务四大特性6.4 并发事务问题6.5 事务隔离级别 MySQL— 基础语法大全及操作演示&#xff01;&#xff01;&#xff01…

docker 部署springboot(成功、截图)

1.新建sringboot工程并打包 2.编写Dockerfile文件 # 基础镜像使用java FROM openjdk:8 # 作者 MAINTAINER feng # VOLUME 指定了临时文件目录为/tmp。 # 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件&#xff0c;并链接到容器的/tmp VOLUME /tmp # 将jar包添加…

什么是数据丢失防护(DLP)

数据丢失防护 &#xff08;DLP&#xff09; 是一种安全策略&#xff0c;旨在保护企业的关键数据免遭未经授权的用户盗窃、丢失或访问。一个好的 DLP 系统是用于数据发现和分类、数据传输和访问控制、策略和事件管理以及细致的审核和警报的工具的组合。 数据丢失的原因是什么 …

Databricks 入门之sql(二)常用函数

1.类型转换函数 使用CAST函数转换数据类型&#xff08;可以起别名&#xff09; SELECTrating,CAST(timeRecorded as timestamp) FROMmovieRatings; 支持的数据类型有&#xff1a; BIGINT、BINARY、BOOLEAN、DATE 、DECIMAL(p,s)、 DOUBLE、 FLOAT、 INT、 INTERVAL interva…

嵌入式学习之popen函数

相比于system输出的好处&#xff0c;popen可以直接输出运行结果 14.进程总结 需要重点掌握进程配合相关概念&#xff0c;创建进程函数fork的使用&#xff0c;理解进程创建发生了什么事&#xff0c;exec族函数&#xff0c;exec族函数配合fork使用。

2009-2022年商业银行资产利息相关数据

2009-2022年商业银行资产利息相关数据 1、时间&#xff1a;2009-2022年 2、来源&#xff1a;整理自wind 3、指标&#xff1a;利息支出、资产总计、员工总数、固定资产、存款总额、应付职工薪酬、营业支出、营业收入、扣除人员开支后的营业支出 银行&#xff1a;平安银行兰州…

富而喜悦九仔短短10秒的拥抱让百万网友直呼“太可爱!”

现如今网络发展速度非常快&#xff0c;各种各样的走红层出不穷&#xff0c;甚至有很多人都是一夜之间爆红的&#xff0c;出名的速度非常快。近期&#xff0c;在新浪微博的热榜中&#xff0c;有一个富而喜悦九仔的话题横空出世&#xff0c;微博博主富而喜悦外事部小九&#xff0…

取暖器UL1278测试项目及注意事项!!!

UL1278是可移动的挂墙式或吊顶式室内电暖器的标准&#xff0c;适用于额定电压不超过600V的可移动的且挂墙式或吊顶式的电暖器。不适用于固定式电暖器&#xff0c; 管道式电暖器&#xff0c;中心加热的炉。 取暖器UL认证UL1278标准测试项目&#xff1a; 泄露电流试验&#xff…

8月编程排行榜榜首还是它?敬了不起的Python

近日 TIOBE 公布了2023年8月的编程指数信息&#xff0c;跟着战战一起看看排行详情吧~ 全球知名编程社区TIOBE&#xff0c;每月都会公布编程语言的最新变化&#xff0c;8月编程语言排行榜已出&#xff01;话不多说&#xff0c;一起来看看吧&#xff01; TIOBE 8 月 TOP 15 编程…

Plasticine: 面向并行模式的可重配架构

本文基于对并行模式的分层架构、数据局部性和控制流的抽象&#xff0c;提出了Plasticine架构&#xff0c;从而为并行模式计算提供更好的灵活性和更低的能耗支持。原文: Plasticine: A Reconfigurable Architecture For Parallel Patterns 摘要 近年来&#xff0c;由于可重配架构…

深度解读智能媒体服务的重组和进化

统一“顶设”的智能媒体服务。 邹娟&#xff5c;演讲者 大家好&#xff0c;首先欢迎各位来到LVS的阿里云专场&#xff0c;我是来自阿里云视频云的邹娟。我本次分享的主题为《从规模化到全智能&#xff1a;智能媒体服务的重组与进化》。 本次分享分为以上四部分&#xff0c;一是…

可输入的下拉框

项目场景&#xff1a; 问题描述 可以输入的下拉框&#xff0c;在element-ui中 可以找到的是 input 组件 中-带输入建议 的可以达到效果 当是下拉框时&#xff0c;匹配输入的值与下拉框的数据&#xff0c;如果可以匹配&#xff0c;那么就选择那条&#xff0c;如果不能匹配那么&…

Springboot 接口方式硬通知实现 动态刷新配置值,@ConfigurationProperties 、@Value 都可以

前言 看到这个文章标题&#xff0c;也许有的看官就觉得很多余&#xff0c; 因为Nacos 可以设置 NacosValue(value "${XXX}",autoRefreshed true) 实现动态刷新&#xff1b; 又因为cloud config的RefreshScope 实现动态刷新&#xff1b; 还有阿波罗...等 这…

SurfaceFlinger中Binder案例

SurfaceFlinger中Binder案例 1、SurfaceFlinger服务init启动2、SurfaceFlinger服务继承BnSurfaceComposer端2.1 Code标签扩展2.2 Code标签扩展对应调用 3、SurfaceFlinger服务的BpSurfaceComposer端3.1 FWK使用案例3.2 Native使用案例 android12-release 1、SurfaceFlinger服务…

PieChart示例

PieChart是JavaFX中的饼图&#xff0c;示例如下&#xff1a; PieChartUtil.java文件&#xff0c;饼图数据设置。 package javafx8.ch29;import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.chart.PieChart;/*** copyr…

油画|《凤尾山中》听竹涛,阅山水

《凤尾山中》 陈可之2021年绘 油画《凤尾山中》以竹下仰望山林的视角&#xff0c;描绘出桂林山水在自然光影中的秀美姿态&#xff0c;迤逦风光似乎让心灵都得到自然的洗礼。 画中没有构建明显的前景边框&#xff0c;但上半部分垂下的翠竹枝叶、下部分的江水&#xff0c;以及画…

使用C++操作Redis客户端

"Who can say where the path will go?" 前面我们花了很大的篇幅&#xff0c;讲解了redis中常见常使用的五种数据结构&#xff0c;以及五种数据结构的操作和redis命令。不过在日常开发中&#xff0c;我们的这些操作都是在redis为我们提供的客户端中的&#xff0c;就…