微信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 复制代码
<?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

相关推荐
狂团商城小师妹3 天前
智慧废品回收小程序php+uniapp
大数据·微信·微信小程序·小程序·uni-app·微信公众平台
EasyNVR3 天前
基于WebRTC与AI大模型接入EasyRTC:打造轻量级、高实时、强互动的嵌入式音视频解决方案
运维·服务器·微信·小程序·webrtc·p2p·智能硬件
Stara05116 天前
AI客服-接入deepseek大模型到微信(本地部署deepseek集成微信自动收发消息)
微信·node·ollama·deepseek
亚历山大海7 天前
uniapp基于JSSDK 开发微信支付(php后端)
微信·uni-app·php
初尘屿风8 天前
小程序类毕业设计选题题目推荐 (29)
spring boot·后端·学习·微信·小程序·课程设计
Qwdl19699 天前
健康的生活方式小结---秋浦四郎
经验分享·笔记·百度·微信·twitter·微信开放平台
京河小蚁9 天前
微信云开发小程序音频播放踩坑记录 - 从熄屏播放到iOS静音
微信·小程序·音视频
dennyz10 天前
MMKV和SP、DataStore对比
android·微信·面试
陕西颜值扛把子11 天前
如何在啥也不懂的情况下将你的公众号接入DeepSeek或其它大模型
python·ai·微信
家里有只小肥猫13 天前
微信服务号推送消息
微信