今天博主用了一波微信的v3版本的支付,支付成功后發現回調跟v2的完全不一樣,於是去看了了一波v3的文檔,發現信息是經過加密的,需要解密才能獲取的到
但是最悲催的是文檔上沒寫怎么解密的,經過了一下午的百度,找論壇,終於找到了文檔地址,成功的拿到了我想要的信息,記錄分享一波
1.支付成功,拿到回調信息后,轉成數組后信息如下
$xml = ['id' => 'xxx',
'create_time' => '2020-08-19T12:16:56+08:00',
'resource_type' => 'xxx',
'event_type' => 'TRANSACTION.SUCCESS',
'summary' => '支付成功',
'resource' => [
'original_type' => 'xxxx',
'algorithm' => 'AEAD_AES_256_GCM',
'ciphertext' => 'xxx',
'associated_data' => 'xxxx',
'nonce' => 'xxx',]
];
2.你想要的信息在 resource 里面,但是是經過加密的,接下來需要解密一波
先創建一個 AesUtil.php,復制以下代碼粘進去
<?php class AesUtil { /** * AES key * * @var string */ private $aesKey; const KEY_LENGTH_BYTE = 32; const AUTH_TAG_LENGTH_BYTE = 16; /** * Constructor */ public function __construct($aesKey) { if (strlen($aesKey) != self::KEY_LENGTH_BYTE) { throw new InvalidArgumentException('無效的ApiV3Key,長度應為32個字節'); } $this->aesKey = $aesKey; } /** * Decrypt AEAD_AES_256_GCM ciphertext * * @param string $associatedData AES GCM additional authentication data * @param string $nonceStr AES GCM nonce * @param string $ciphertext AES GCM cipher text * * @return string|bool Decrypted string on success or FALSE on failure */ public function decryptToString($associatedData, $nonceStr, $ciphertext) { $ciphertext = \base64_decode($ciphertext); if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) { return false; } // ext-sodium (default installed on >= PHP 7.2) if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) { return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey); } // ext-libsodium (need install libsodium-php 1.x via pecl) if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) { return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey); } // openssl (PHP >= 7.1 support AEAD) if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) { $ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE); $authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE); return \openssl_decrypt($ctext, 'aes-256-gcm', $this->aesKey, \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData); } throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安裝libsodium-php'); } }
3.接下來就是解密了
var_dump((new AesUtil('你的APIv3秘鑰'))->decryptToString($xml['resource']['associated_data'],$xml['resource']['nonce'],$xml['resource']['ciphertext']));
文檔地址:https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/zheng-shu-he-hui-tiao-bao-wen-jie-mi
