支付宝支付回调的处理

支付宝异步通知会有很多参数,正常POST接收就行

注意:支付的异步通知和退款的异步通知是同一个url

$data=$_POST;

验证签名

其验签步骤为:
第一步: 在通知返回参数列表中,除去sign、sign_type两个参数外,凡是通知返回回来的参数皆是待验签的参数。
TIPS: 生活号异步通知组成的待验签串里需要保留sign_type参数。
第二步: 将剩下参数进行url_decode, 然后进行字典排序,组成字符串,得到待签名字符串:
第三步: 将签名参数(sign)使用base64解码为字节码串。
第四步: 使用RSA的验签方法,通过签名字符串、签名参数(经过base64解码)及支付宝公钥验证签名。
第五步:在步骤四验证签名正确后,必须再严格按照如下描述校验通知数据的正确性。

$signature=$data['sign'];
unset($data['sign_type'], $data['sign']);
ksort($data);

$verify=$this->_sign_verify(urldecode(http_build_query($data)), $signature);
if ($verify==1){
    echo 'ok';
}else echo 'failure';

    /**
     * 支付回调(验证签名 RSA2
     * @param $data
     * @param $signature
     * @return bool
     */
    public function _sign_verify($data, $signature): bool {
        $alipay_public_key = '';//支付宝公钥
        $res = "-----BEGIN PUBLIC KEY-----\n" .
            wordwrap($alipay_public_key, 64, "\n", true) .
            "\n-----END PUBLIC KEY-----";
        //调用openssl内置方法验签,返回bool值
        return (openssl_verify($data, base64_decode($signature), $res, OPENSSL_ALGO_SHA256) === 1);
    }

其他

异步通知返回的数据是明文的,无需解密

    //验证交易状态$data['trade_status']是否为TRADE_SUCCESS
    //验证$data['app_id']是否正确
    //通过我们的支付单号$data['out_trade_no']来处理后续流程
    //通知应答
    echo 'success';

if ($data['app_id'] == $config['app_id'] && !empty($data['out_trade_no'])) {
    if (in_array($data['trade_status'], ['TRADE_SUCCESS'])){//支付成功或部分退款
        if (empty($data['out_biz_no'])){
            //支付成功
            echo "success";
        }else{
            //部分退款
            //out_biz_no为退款编号
            echo 'success';
        }
    }
}elseif (in_array($data['trade_status'], ['TRADE_CLOSED']) && !empty($data['out_biz_no'])){
    //全额退款
    echo 'success';
}

参考

支付宝异步通知说明

https://opensupport.alipay.com/support/helpcenter/193/201602472200

交易退款接口是否会触发异步通知

https://opensupport.alipay.com/support/helpcenter/193/201602484851?ant_source=zsearch#

感谢阅读这篇文章,如果你喜欢,或者遇到了问题,可以关注我的公众号