记录一下PHP使用微信小程序支付

news2025/2/25 19:59:23

记录一下PHP使用微信小程序支付V3版本经历

官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_0.shtml

请详细查看文档中小程序支付接入前准备(https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml)

注意:配置好需要将已生成的证书下载放在自己的项目中
示例:
在这里插入图片描述

配置好后需要拿到以下参数:

  1. 小程序appid
  2. 商户号
  3. 微信支付API证书序列号
  4. 微信支付v3密钥(回调时需要)

支付大概流程:
1.小程序端提交订单

小程序端提交的订单就不做示例了

2.后端根据订单信息生成预订单通过小程序JSAPI下单返回预支付交易会话标识

	  private $appid = '**********';//应用ID
    private $mchid = '************';//商户号
    private $serial_number = '***********';//微信支付API证书序列号
    private $v3_key = '***********';//微信支付v3密钥

    public function placeOrder()
    {
        //通过jsapi下单所需参数
        $pay_info = [
            'out_trade_no' => '',//自己平台的订单号
            'total' => '',//付款金额,单位为分
            'openid' => '',//付款用户的openid
        ];
        // 1、请求参数
        $postJson = [
            "appid" => $this->appid,
            "mchid" => $this->mchid,
            "description" => '商品信息',//商品信息
            "out_trade_no" => $pay_info['out_trade_no'],//自己平台的订单号
            //用于接收微信支付结果的回调接口(注意回调接口不能加什么是否登录验证信息,需要外网能直接访问的地址)
            "notify_url" => 'https://ffe8-113-249-28-138.ngrok-free.app/api/Pay/payBack',
            "amount" => [
                "total" => $pay_info['total'] //付款金额,单位为分
            ],
            "payer" => [
                "openid" => $pay_info['openid'],//付款用户的openid
            ],
        ];
        $time = time();
        // 2、头部签名
        $url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
        $urlarr = parse_url($url);
        $data = json_encode($postJson);
        $noncestr = randstrpay();//签名所需随机字符串
        $key = $this->getSign($data, $urlarr['path'], $noncestr, $time);//签名

//        $token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%d",signature="%s"', '商户号', '微信支付API证书序列号', $noncestr, $time, $key);//头部信息
        $token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%d",signature="%s"', $this->mchid, $this->serial_number, $noncestr, $time, $key);//头部信息
        $header = [
            'Content-Type:' . 'application/json; charset=UTF-8',
            'Accept:application/json',
            'User-Agent:*/*',
            'Authorization: WECHATPAY2-SHA256-RSA2048 ' . $token
        ];
        $resp = postCurl($url, $data, $header);
        $resp = json_decode($resp, true);
        if (isset($resp['prepay_id'])) {
            $return = [
                "appId" => $this->appid,
                "timeStamp" => $time,
                'prepay_id' => 'prepay_id=' . $resp['prepay_id'],
                'paySign' => $this->getWechartSign('wxf1edd999226319ea', $time, $noncestr, 'prepay_id=' . $resp['prepay_id']),//微信支付(小程序)签名
                "nonceStr" => $noncestr
            ];
            return $return;
        } else {
            //apiReturn是我自己封装的返回的json格式
            apiReturn(303, '支付订单创建失败!', $resp);
        }

    }


    /**
     *Api Name:生成微信支付签名
     *Developer:TH
     *Time:2024年05月30日 09:31
     */
    public function getSign($data = [], $url, $randstr, $time)
    {
        $str = "POST" . "\n" . $url . "\n" . $time . "\n" . $randstr . "\n" . $data . "\n";
        $key = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/apiclient_key.pem');//在商户平台下载的秘钥
        $str = $this->getSha256WithRSA($str, $key);
        return $str;
    }


    /**
     *Api Name:调起支付的签名
     *Developer:TH
     *Time:2024年05月30日 09:32
     */
    public function getWechartSign($appid, $timeStamp, $noncestr, $prepay_id)
    {
        $str = $appid . "\n" . $timeStamp . "\n" . $noncestr . "\n" . $prepay_id . "\n";

        $key = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/apiclient_key.pem');
        $str = $this->getSha256WithRSA($str, $key);
        return $str;
    }


    public function getSha256WithRSA($content, $privateKey)
    {
        $binary_signature = "";
        $algo = "SHA256";
        openssl_sign($content, $binary_signature, $privateKey, $algo);
        $sign = base64_encode($binary_signature);
        return $sign;
    }

JSAPI下单成功后会返回以下参数
在这里插入图片描述

3.小程序端根据预支付交易会话标识 调起支付API

小程序端示例:

		// 模拟支付
		pay: function() {
			
			wx.requestPayment
			(
				{
					"timeStamp": "1718348859",
					"nonceStr": "R5AK20MQQZIZFMAD170J2124CE6WLJ1J",
					"package": "prepay_id=wx14150738126675942c8a76a8a13b8a0000",
					"signType": "RSA",
					"paySign": "q2ZVp5DUpYSxgUu5aCNrlLj7m81mL9GDMw0TE2EkYvqAI29/jFKP9FctE0f78S+qs1p3STaHKpOnHc6gy0K4FOW7CO8tER00FlNyxVYwhTOV0SsGwLaKV239iizt3iYVQS2VkfwdyH3mTn27PHyBdww1LvDLLlXdLCmdrcE4OM5VGemAHgJuPR0PcZC19ufweC8ALoKF/FHYra9uX3Rbph1LVeu6VpB2nCDO6fVR5TpY27cehJY7tGemar/f+9NAMvmgIZOpFps4kUNOV1wqcDjAkTJYIb5LmVdgiZbUwJYz9LCxvXEjXpsrj9VvTrwjyLc1Ifvj4JPzNlfIrf0fzw==",
					"success":function(res){
						console.log(res);
					},
					"fail":function(res){},
					"complete":function(res){}
				}
			)
			},

4.支付成功后通过第二步设置的回调地址进行支付成功后订单逻辑支付
示例:

    /**
     *Api Name:支付回调结果处理
     *Developer:TH
     *Time:2024年06月14日 10:06
     */
    public function payBack()
    {
        $xml = file_get_contents('php://input');//微信回调返回的结果

        $post = json_decode($xml, true);

        $text = base64_decode($post['resource']['ciphertext']);
        //对加密数据解密 注:sodium_crypto_aead_aes256gcm_decrypt需要你运行的PHP版本>=7.1
        $str = sodium_crypto_aead_aes256gcm_decrypt($text, $post['resource']['associated_data'], $post['resource']['nonce'], '微信支付v3密钥');
        $res = json_decode($str, true);
        if ($res['trade_state'] == 'SUCCESS') {
            //按照自己的需求,进行订单逻辑处理
            
        } else {
            apiReturn(303, '发生未知错误,请联系管理员处理');
        }
    }

小程序支付到这基本就算完成了,中途发生问题可以百度解决,实际请按自己的需求进行代码完善

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

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

相关文章

计算机系统的主要概念

这篇文章通过研究“hello,world”这个简单程序的生命周期来介绍计算机系统的主要概念。 1. 信息就是位 上下文 我们以 hello 程序为例,在 linux 系统中,我们编辑文本文件 hello.c,使用编译器将其编译成可执行的 源程序&#xf…

618有什么值得推荐?2024数码产品推荐,轻松拿捏选购!

随着618购物节即将来临,你是否已被琳琅满目的商品所吸引,难以抉择?团团特意为你筛选出一系列经过亲身试验的优质好物,旨在帮助你在这场购物盛宴中迅速锁定心仪之选。这些推荐不仅走在时尚的前沿,更能满足你日常生活的各…

任务3.8.2 利用RDD计算总分与平均分

实战:使用RDD 计算学生成绩的总分与平均分 项目背景 本项目旨在利用 Apache Spark 的强大数据处理能力,对存储在 HDFS 上的学生成绩文件进行处理,计算每个学生的总分和平均分。 项目目标 读取存储在 HDFS 上的成绩文件。计算每个学生的总…

波卡近期活动一览| Polkadot Decoded 2024 重磅来袭,300 万 DOT 将用于 DeFi 增长

Polkadot 生态近期活动精彩纷呈,线上线下火热进行中!此外,Polkadot 2.0 的关键升级即将到来,Gavin Wood 博士也将在最新访谈节目中分享更多关于波卡的未来发展蓝图。波卡 DAO 通过提案,分配 300 万 DOT 支持 DeFi 生态…

双向转发检测BFD(学习笔记)

定义 双向转发检测BFD(Bidirectional Forwarding Detection)是一种全网统一的检测机制,用于快速检测、监控网络中链路或者IP路由的转发连通状况 BFD检测机制 BFD的检测机制是两个系统建立BFD会话,并沿它们之间的路径周期性发送B…

企业如何抓住“AI+出海”新机遇?2024光亚展现场,全屋智能出海AI营销第一课行业大咖齐聚点拨

2024年6月9日至12日,第29届广州国际照明展览会(光亚展)于在中国进出口商品交易会展馆举办。连同同期举行的第21届广州国际建筑电气技术展览会(GEBT),雄据广州中国进出口商品交易会展馆A及B区的26个展馆&…

技术速递|介绍 .NET API 文档的源代码链接

作者:Min Huang,Matt Trilby-Bassett 排版:Alan Wang 开发人员在阅读 API 参考文档时,有时会需要或希望查看相应的源代码。直到不久之前,.NET API 参考文档还没有提供指向源代码的链接,这引起社区添加这一功…

【Python】Numpy的使用

文章目录 数组创建数组属性ndarray数组索引ndarray数组的基本索引和切片ndarray数组的布尔索引ndarray数组的花式索引 ndarray数组的转置和轴对换ndarray通用函数一元ufunc二元ufunc NumPy的where函数使用常用统计函数排序 ndarray数组的去重以及集合运算numpy中的线性代数nump…

优思学院|如何选择六西格玛黑带的项目?

不管六西格玛的实施着重于变革式的还是渐进式的目标,项目都是六西格玛最核心的部分。选择和使用组织中最好的人才本身并不一定能保证达到最好的结果,项目的选取是领导层无可推卸的责任。选择一个项目意味着什么?领导团队必须将无数的问题、困…

DAC测试实验——FPGA学习比

一、DAC简介 DAC全称Digital to Analog Converter,即数模转换器。它用于将主控芯片产生的数字值(0和1)转换为模拟值(电压值)。 1、DAC参数指标 2、DAC类型 常用的DAC可大致分为权电阻网络DAC、T型电阻网络DAC、倒T型电阻网络DAC以及权电流型DAC。 3、AD9708/3PD9…

html中a标签的多用性

在HTML中&#xff0c;<a> 标签&#xff08;通常称为锚标签或链接标签&#xff09;具有多种用途和强大的功能。以下是<a>标签的一些主要多用性&#xff1a; 网页间的导航&#xff1a; 这是<a>标签最常见的用途。通过href属性&#xff0c;可以指定一个URL&am…

【问题解决】国际化messages_zh_CN.properties中乱码问题

打开 messages_zh_CN.properties 文件 之前用中文写的现在都是各种各样的符号 解决方法&#xff1a; 打开idea 找到File>Settings>Editor>File Encodings 确定这三个地方是否都是utf-8&#xff0c;改好之后点确定&#xff0c;就能正常显示了

吴恩达深度学习笔记:机器学习(ML)策略(1)(ML strategy(1))1.9-1.10

这里写自定义目录标题 第三门课 结构化机器学习项目&#xff08;Structuring Machine Learning Projects&#xff09;第一周 机器学习&#xff08;ML&#xff09;策略&#xff08;1&#xff09;&#xff08;ML strategy&#xff08;1&#xff09;&#xff09;1.9 可避免偏差&am…

红队内网攻防渗透:内网渗透之Linux内网权限提升技术:udf提权Capability权限LD_PRELOAD环境变量

红队内网攻防渗透 1. 内网权限提升技术1.1 Linux系统提权-Web&用户-数据库udf提权1.1.1 信息收集1.1.2 Web权限获取1.1.3 MYSQL-UDF提权1.1.4 下载到目标上1.1.5 连接确认是否有条件进行导出调用1.1.6 开始进行写入导出调用1.2 Linux系统提权-Web&用户-Capability能力1…

高分论文密码---大尺度空间模拟预测与数字制图

大尺度空间模拟预测和数字制图技术和不确定性分析广泛应用于高分SCI论文之中&#xff0c;号称高分论文密码。大尺度模拟技术可以从不同时空尺度阐明农业生态环境领域的内在机理和时空变化规律&#xff0c;又可以为复杂的机理过程模型大尺度模拟提供技术基础。我们将结合一些经典…

JDK8时间类,时区,时间和格式化

一.时间类 二.获取所有的时区 1.获取所有的时区Set<String> zoneIds ZoneId.getAvailableZoneIds();System.out.println(zoneIds.size()); 根据打印的结果可以看到java类中一共有603个时区。 三.获取当前系统默认的时区 ZoneId zoneId ZoneId.systemDefault();Syste…

测试基础13:测试用例设计方法-错误推断、因果图判定表

课程大纲 1、错误推测法 靠主观经验和直觉来推测可能容易出现问题的功能或场景&#xff0c;设计相关测试用例进行验证。 2、因果图&判定表 2.1定义 因果图和判定表是分析和表达多逻辑条件下&#xff0c;执行不同操作的情况的工具。 &#xff08;因果图和判定表配合使用&a…

20.2 JSON-JSON解码、映射数据类型、处理JSON响应

1. JSON解码 JSON解码&#xff0c;即将JSON格式在字符串转换为Go语言数据类型的变量。 函数Unmarshal接受一个JSON字节切片和一个指定目标格式的接口。而这个借口即与JSON字符串中的结果相匹配的结构体类型的变量。 定义结构体类型 type Person struct { ... }创建结构体变量…

Internet Download Manager(IDM6.41)安装教程+软件安装包下载

IDM是一款多线程下载工具&#xff0c;全称InternetDownloadManager。IDM的多线程加速功能&#xff0c;能够充分利用宽带&#xff0c;所以下载速度会比较快&#xff0c;而且它支持断点续传。它的网站音视频捕获、站点抓取、静默下载等功能&#xff0c;也特别实用。 安 装 包 获 …

堆的实现及其应用

堆的概念 堆是完全二叉树&#xff0c;分为大堆和小堆。大堆&#xff1a;任何一个父亲都大于等于孩子&#xff0c;小堆&#xff1a;任何一个父亲都小于等于孩子。 堆的实现 目录 typedef int HPDataType;typedef struct Heap { HPDataType* a;int size;int capacity; }HP;//交…