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.支付完整代碼
<?phpnamespace 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