当前位置: 首页 > article >正文

微信V3支付报错 平台证书及平台证书序列号

1.平台证书及平台证书序列号设置错误报错:

  • 错误1:

Verify the response’s data with: timestamp=1735184656, nonce=a5806b8cabc923299f8db1a174f3a4d0, signature=FZ5FgD/jtt4J99GKssKWKA/0buBSOAbWcu6H52l2UqqaJKvrsNxvodB569ZFz5G3fbassOQcSh5BFq6hvEMjQ2U3gKyF1muqsX8oufN4pLQpO+SO5CM7q8y/jIiYG18Kn3Iss7jbG/qGTsssscN98tfpUAb3TCWSQB1mVXUgSDWsROthYfduUgsNMC/xe1z1f2Os9L8fYWjqv8Fr5W5sL7+jFzSTibu7XcietZ+G1MusHC606ncF8MU9cNEf5QRHqgkril3e5IEesssEud6bp35sss0I87wgU5eMDZJp2hw==, cert=[2sssssss1FCC3BBA284F5C7889BCD7B47 => …] failed

  • 错误2:

certs(175BxxxxE4507EA22FFD9D8B7CCD0218F1E3xxxx) contains the merchant’s certificate serial number(175BxxxxE4507EA22FFD9D8B7CCD0218F1E3xxxx) which is not allowed here.

  • 错误3:

Cannot found the serial(2sssssss1FCC3BBA284F5C7889BCD7B47)'s configuration, which’s from the response(header:Wechatpay-Serial), your’s 5B1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A

2.重点介绍平台证书 及序列号获取方法

选择 “验证微信支付身份” 管理证书
2.1选择商户后台 “验证微信支付身份” 管理证书。
平台证书的序列号
拿到 平台证书的序列号,

2.2 点击 “右上角” 下载证书
在这里插入图片描述
获取证书相关链接:https://pay.weixin.qq.com/doc/v3/merchant/4012068814

打开链接后按照提示下载jar包,
jdk下载地址:https://repo.huaweicloud.com/java/jdk/ windows配置环境变量JAVA_HOME:C:\Program Files\Java\jdk-13
path增加:%JAVA_HOME%\bin
java -jar CertificateDownloader.jar -k a3F7t8L2x9K5xxxxx -m 1xxxxxx -f D:\program\WXCertUtil\WXCertUtil\cert\1700367105_20241225_cert\apiclient_key.pem -s 11111122E5678EA22xxxx18F1cdEab3 -o d:
在d盘生成wechatpay开头的pem文件,就是我们要的平台证书。上传到服务器/data/wechat_cert/wechatpay_platform_create_at_202412.pem下

下属代码中的
WECHAT_PAY_PLATFORM_CERTIFICATE=/data/wechat_cert/wechatpay_platform_create_at_202412.pem
WECHAT_PAY_PLATFORM_CERTIFICATE_SERIAL=11D1111B23D5BFD1FddbBBA111F5C7889BC11111

3.支付完整代码

<?php

namespace app\common\util;


use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Formatter;


//参考 微信支付文档:https://pay.weixin.qq.com/docs/merchant/apis/in-app-payment/direct-jsons/app-prepay.html
class WeChatPayUtil
{
    /**
     * 微信开发平台审核通过的应用ID
     * @var string
     */
    protected $appid = 'xxx';

    /**
     * 商户ID
     * @var string
     */
    protected $merchantId = 'xxx';

    /**
     * 商户v3版本私钥
     * @var string
     */
    protected $merchantV3PrivateKey = 'xx';


    /**
     * 「商户API私钥」文件的绝对路径
     * @var string
     */
    protected $merchantPrivatePath = '\v3_apiclient_key.pem';

    /**
     * 「商户API证书」的「证书序列号」
     * @var string
     */
    protected $merchantCertificateSerial = 'xxx';

    /**
     * 「微信支付平台证书」文件的绝对路径
     * @var string
     */
    protected $platformCertificate = '\platform_key.pem';

    /**
     * 「微信支付平台证书」的「证书序列号」
     * @var string
     */
    protected $platformCertificateSerial = 'xx';

    /**
     * APIv3 客户端实例
     * @var \WeChatPay\BuilderChainable
     */
    protected $instance;


    public function getMerchantV3PrivateKey(): string
    {
        return $this->merchantV3PrivateKey;
    }


    public function __construct()
    {
        $this->appid = getenv('WECHAT_PAY_APPID');
        $this->merchantId = getenv('WECHAT_PAY_MERCHANT_ID');
        $this->merchantV3PrivateKey = getenv('WECHAT_PAY_MERCHANT_V3_PRIVATE_KEY');
        $this->merchantPrivatePath = getenv('WECHAT_PAY_MERCHANT_PRIVATE_PATH');
        $this->merchantCertificateSerial = getenv('WECHAT_PAY_MERCHANT_CERTIFICATE_SERIAL');
        $this->platformCertificate = getenv('WECHAT_PAY_PLATFORM_CERTIFICATE');
        $this->platformCertificateSerial = getenv('WECHAT_PAY_PLATFORM_CERTIFICATE_SERIAL');
        // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
        $merchantPrivateKeyInstance = Rsa::from("file://" . $this->merchantPrivatePath, Rsa::KEY_TYPE_PRIVATE);
        // 从本地文件中加载「微信支付平台证书」或者「微信支付平台公钥」,用来验证微信支付应答的签名
        $platformPublicKeyInstance = Rsa::from("file://" . $this->platformCertificate, Rsa::KEY_TYPE_PUBLIC);
        // 构造一个 APIv3 客户端实例
        $instance = Builder::factory([
            'mchid' => $this->merchantId,
            'serial' => $this->merchantCertificateSerial,
            'privateKey' => $merchantPrivateKeyInstance,
            'certs' => [
                $this->platformCertificateSerial => $platformPublicKeyInstance,
            ],
        ]);
        $this->instance = $instance;
    }


    /**
     *  APP下单
     * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_1.shtml
     * @param $out_trade_no string 在自己系统中唯一的订单号
     * @param $body string  商品描述
     * @param $amount number 订单金额,单位为元
     * @param $notify_url string 支付回调地址,必须是https开头。例如:https://www.xxx.com/xxx/xxx
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function appPay($out_trade_no, $body, $amount, $notify_url)
    {
        return $this->instance
            ->chain('v3/pay/transactions/app')
            ->post(['json' => [
                'mchid' => $this->merchantId,
                'out_trade_no' => $out_trade_no,
                'appid' => $this->appid,
                'description' => $body,
                'notify_url' => $notify_url,
                'amount' => [
                    'total' => $amount * 100,
                    'currency' => 'CNY'
                ],
                'time_expire' => date('Y-m-d\TH:i:sP', time() + 20 * 60) // 订单未支付20分钟过期
            ]]);
    }


    /**
     * 生成支付签名
     * @param $result_data
     * @return array
     */
    public function generateSignature($result_data)
    {
        // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
        // 文件路径例如:D:\EMin\xxx\cert\wx_v3\v3_apiclient_key.pem
        $merchantPrivateKeyInstance = Rsa::from('file://' . $this->merchantPrivatePath, Rsa::KEY_TYPE_PRIVATE);
        $arouse_data = [
            'appId' => $this->appid,
            'timeStamp' => strval(Formatter::timestamp()),
            'nonceStr' => Formatter::nonce(),
            //'package' => 'prepay_id=' . $result_data['prepay_id'],  // JSAPI下单
            'prepay_id' => $result_data['prepay_id'], // APP下单
        ];
        $arouse_data += ['paySign' => Rsa::sign(
            Formatter::joinedByLineFeed(...array_values($arouse_data)),
            $merchantPrivateKeyInstance
        ), 'signType' => 'RSA'];
        return $arouse_data;
    }


    /**
     *签名验签
     * @date 2024/11/28
     * @param array $header 请求头
     * @param string $body 请求参数
     * @return bool
     */
    public function signVerify(array $header, string $body)
    {
        $inWechatPaySignature = $header['wechatpay-signature'];// 请根据实际情况获取 微信方的签名
        $inWechatPayTimestamp = $header['wechatpay-timestamp'];// 请根据实际情况获取 微信方的时间戳
        $inWechatPayNonce = $header['wechatpay-nonce'];// 请根据实际情况获取 微信方的随机字符串

        // 根据通知的平台证书序列号,查询本地平台证书文件,
        $platformPublicKeyInstance = Rsa::from('file://' . $this->platformCertificate, Rsa::KEY_TYPE_PUBLIC);

        // 检查通知时间偏移量,允许5分钟之内的偏移
        $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatPayTimestamp);
        $verifiedStatus = Rsa::verify(
        // 构造验签名串
            Formatter::joinedByLineFeed($inWechatPayTimestamp, $inWechatPayNonce, $body),
            $inWechatPaySignature,
            $platformPublicKeyInstance
        );

        if ($timeOffsetStatus && $verifiedStatus) {
            return true;
        }
        return false;
    }


}

配置文件如下:
WECHAT_PAY_APPID=wxd11111111111111
WECHAT_PAY_MERCHANT_ID=1700111111
WECHAT_PAY_MERCHANT_V3_PRIVATE_KEY=aaaaaaaaa9K5p1Q4w6R3s2c7u4bbbbbb
WECHAT_PAY_MERCHANT_PRIVATE_PATH=/data/wechat_cert/wechat_apiclient_key.pem
WECHAT_PAY_MERCHANT_CERTIFICATE_SERIAL=175BC000E45tytr22eeD9d8B7BBD6666F1E3E749
WECHAT_PAY_PLATFORM_CERTIFICATE=/data/wechat_cert/wechatpay_platform_create_at_202412.pem
WECHAT_PAY_PLATFORM_CERTIFICATE_SERIAL=11D1111B23D5BFD1dddbBBA111F5r7889vb11111


http://www.kler.cn/a/454135.html

相关文章:

  • 浅谈下雪花算法的原理,及在项目中使用需要注意哪些事项
  • node-js Express防盗链
  • 【Python运维】自动化备份与恢复系统的实现:Python脚本实战
  • 分布式光纤传感|分布式光纤测温|线型光纤感温火灾探测器DTS|DTS|DAS|BOTDA的行业16年的总结【2024年】
  • 深入解析 Tengine:高性能 Web 服务器与反向代理的企业级应用
  • 论文解读——掌纹生成网络 RPG-Palm升级版PCE-Palm
  • iviewui Message/Notice 设置居顶高度方法
  • Linux中设置终端窗口大小
  • Pytorch | 利用SMI-FGRM针对CIFAR10上的ResNet分类器进行对抗攻击
  • Java小公司面试
  • 关于studywolf_control动态运动原语
  • redis 缓存雪崩
  • 重装荣耀X14笔记本电脑踩坑记
  • Linux 线程池
  • RocketMQ的集群架构是怎样的?
  • 深度学习中的并行策略概述:4 Tensor Parallelism
  • 【ES6复习笔记】模板字符串(3)
  • 运行Zr.Admin项目(前端)
  • C++软件设计模式之类型模式和对象型模式
  • PDF书籍《手写调用链监控APM系统-Java版》第9章 插件与链路的结合:Mysql插件实现
  • 基于 Python 大数据的拼团购物数据分析系统的设计与实现
  • 路由器的原理
  • Axure10
  • 【无标题】学生信息管理系统界面
  • GitLab安装及使用
  • C++打造局域网聊天室第十三课: 任务栏托盘功能的实现