微信开发 ━━ 微信商户v3微信支付回调之php篇

开发内容都在这里:
微信支付API v3
证书和回调报文解密

在微信支付时提供一个回调地址,支付完成后微信会向这个回调地址发送一个json格式的报文,将报文内容解密后获取订单号等数据

报文内容:

{
	"original_type": "transaction", // 加密前的对象类型
	"algorithm":"AEAD_AES_256_GCM", // 加密算法
	
	// Base64编码后的密文
	"ciphertext": "...", 
	// 加密使用的随机串初始化向量)
	"nonce": "...", 
	// 附加数据包(可能为空字符串)
	"associated_data": "" 
}

解密函数:

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');
    }
}

执行函数:

$mchkey = 'aabbccddeeffgghhiijjkkllmmnn'; //API密钥
//获得内容
$post = file_get_contents("php://input");
//转数组
$arr_post = json_decode($post,true);
//解密
$ciphertext=(new AesUtil($mchkey))->decryptToString($arr_post['resource']['associated_data'],$arr_post['resource']['nonce'],$arr_post['resource']['ciphertext']); 
//转数组
$arr_ciphertext = json_decode($ciphertext,true);

if(!empty($arr_ciphertext['out_trade_no']) and isset($arr_ciphertext['trade_state']) and $arr_ciphertext['trade_state']=='SUCCESS')
{
	//成功回调
	var_dump($arr_ciphertext);
}

注意:
通知签名,加密不能保证通知请求来自微信。微信会对发送给商户的通知进行签名,并将签名值放在通知的HTTP头Wechatpay-Signature。商户应当验证签名,以确认请求来自微信,而不是其他的第三方。签名验证的算法请参考 《微信支付API v3签名验证》。

你可能感兴趣的:(PHP,App,php,微信,开发语言,微信支付,支付)