收藏
回答

支付回调验证 偶然失败 !!! 偶然失败!!!

PHP自己撸的代码.

搞不懂有些延签能过,有些验签不能过,多数都能过

这种偶然性的东西我真是头大了.....

公钥肯定是没问题的

从$_SERVER中取值出问题了?

还是$body取值有问题?

还是base64_decode有什么特殊隐藏技巧?



//这个有隐藏技巧?
$body=file_get_contents('php://input');
//还是我这里写的有毛病..?
$nonce=isset($_SERVER['HTTP_WECHATPAY_NONCE'])?$_SERVER['HTTP_WECHATPAY_NONCE']:'';
$wx_cert_no=isset($_SERVER['HTTP_WECHATPAY_SERIAL'])?$_SERVER['HTTP_WECHATPAY_SERIAL']:'';
$sign_base64_str=isset($_SERVER['HTTP_WECHATPAY_SIGNATURE'])?$_SERVER['HTTP_WECHATPAY_SIGNATURE']:'';
$timestamp=isset($_SERVER['REQUEST_TIME'])?$_SERVER['REQUEST_TIME']:'';
//公钥铁定没问题,不然延签也不会过啊
$wx_key=file_get_contents('下载的微信公钥');
//这个很少用.不确定. 反正我整了一晚上 愣是没搞明白 这种偶然性
$res=openssl_verify($message,base64_decode($sign_base64_str),$wx_key,'sha256WithRSAEncryption');
if ($res=="1"){
    return true;
}else{
    return false;
}
回答关注问题邀请回答
收藏

1 个回答

  • 北望沣渭
    北望沣渭
    2021-12-30

    援引自: https://packagist.org/packages/wechatpay/wechatpay

    回调通知

    回调通知受限于开发者/商户所使用的`WebServer`有很大差异,这里只给出开发指导步骤,供参考实现。

    1. 从请求头部`Headers`,拿到`Wechatpay-Signature`、`Wechatpay-Nonce`、`Wechatpay-Timestamp`、`Wechatpay-Serial`及`Request-ID`,商户侧`Web`解决方案可能有差异,请求头可能大小写不敏感,请根据自身应用来定;

    2. 获取请求`body`体的`JSON`纯文本;

    3. 检查通知消息头标记的`Wechatpay-Timestamp`偏移量是否在5分钟之内;

    4. 调用`SDK`内置方法,[构造验签名串](https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml)然后经`Rsa::verfify`验签;

    5. 消息体需要解密的,调用`SDK`内置方法解密;

    6. 如遇到问题,请拿`Request-ID`点击[这里](https://support.pay.weixin.qq.com/online-service?utm_source=github&utm_medium=wechatpay-php&utm_content=apiv3),联系官方在线技术支持;

    样例代码如下:

    <?php
    use WeChatPay\Crypto\Rsa;
    use WeChatPay\Crypto\AesGcm;
    use WeChatPay\Formatter;
    
    $inWechatpaySignature = '';// 请根据实际情况获取
    $inWechatpayTimestamp = '';// 请根据实际情况获取
    $inWechatpaySerial = '';// 请根据实际情况获取
    $inWechatpayNonce = '';// 请根据实际情况获取
    $inBody = '';// 请根据实际情况获取,例如: file_get_contents('php://input');
    
    $apiv3Key = '';// 在商户平台上设置的APIv3密钥
    
    // 根据通知的平台证书序列号,查询本地平台证书文件,
    // 假定为 `/path/to/wechatpay/inWechatpaySerial.pem`
    $platformPublicKeyInstance = Rsa::from('file:///path/to/wechatpay/inWechatpaySerial.pem', Rsa::KEY_TYPE_PUBLIC);
    
    // 检查通知时间偏移量,允许5分钟之内的偏移
    $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
    $verifiedStatus = Rsa::verify(
        // 构造验签名串
        Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody),
        $inWechatpaySignature,
        $platformPublicKeyInstance
    );
    if ($timeOffsetStatus && $verifiedStatus) {
        // 转换通知的JSON文本消息为PHP Array数组
        $inBodyArray = (array)json_decode($inBody, true);
        // 使用PHP7的数据解构语法,从Array中解构并赋值变量
        ['resource' => [
            'ciphertext'      => $ciphertext,
            'nonce'           => $nonce,
            'associated_data' => $aad
        ]] = $inBodyArray;
        // 加密文本消息解密
        $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad);
        // 把解密后的文本转换为PHP Array数组
        $inBodyResourceArray = (array)json_decode($inBodyResource, true);
        // print_r($inBodyResourceArray);// 打印解密后的结果
    }
    
    2021-12-30
    有用
    回复
登录 后发表内容