yansongda / pay

可能是我用过的最优雅的 Alipay/WeChat/Douyin/Unipay/江苏银行 的支付 SDK 扩展包了
http://pay.yansongda.cn
MIT License
5.02k stars 1.03k forks source link

退款的异步通知(验证报错) #132

Closed scbing closed 6 years ago

scbing commented 6 years ago

包版本号

"yansongda/laravel-pay": "^2.0"

问题描述

退款指定了通知地址,增加参数: notify_url,

之后的2种 验证都不能通过

Pay::wechat()->verify(); 签名异常
Pay::wechat()->verify(null, true);  无效xml

代码 重现过程

订单的退款流程

public function refund(Order $order)
    {
        if ($order->type === 'alipay') {
            $attributes = [
                'out_trade_no' => $order->orderNo,
                'refund_amount' => $order->money,
                'notify_url' => action('RefundNotifyController@alipay')
            ];

            return Pay::alipay()->refund($attributes);
        }

        $out_trade_no = date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
        $attributes = [
            'out_refund_no' => $out_trade_no,
            'out_trade_no' => $order->orderNo,
            'total_fee' => $order->money * 100,
            'refund_fee' => $order->money * 100,
            'notify_url' => action('RefundNotifyController@weixin')
        ];

        return Pay::wechat()->refund($attributes);
    }

退款的异步通知


 public function weixin()
    {
        info('微信退款通知:Start');

        $result = Pay::wechat()->verify(null, true);

        info('微信退款通知:', $result->toArray());

        $order = Order::where('orderNo', $result->out_trade_no)->latest()->first();
        if (!$order) {
            return 'Order does not exist';
        }

        if ($order->refund_at) {
            return Pay::wechat()->success();
        }

        $order->fill([
            'status' => $result->refund_status === 'SUCCESS' ? 'refund' : 'fail',
            'refund_at' => now(),
        ])->save();

        return Pay::wechat()->success();
    }

    public function alipay()
    {
        info('支付宝退款:Start');

        $result = Pay::alipay()->verify(null, true);

        info('支付宝退款通知:', $result->toArray());

        $order = Order::where('orderNo', $result->out_trade_no)->latest()->first();
        if (!$order) {
            return 'Order does not exist';
        }

        if ($order->refund_at) {
            return Pay::alipay()->success();
        }

        $order->fill([
            'status' => $result->trade_status === 'TRADE_SUCCESS' ? 'refund' : 'fail',
            'refund_at' => now(),
        ])->save();

        return Pay::alipay()->success();
    }

报错详情

[2018-07-25 10:38:39] local.INFO: 微信退款通知:Start  
[2018-07-25 10:38:39] local.ERROR: Convert To Array Error! Invalid Xml! {"exception":"[object] (Yansongda\\Pay\\Exceptions\\InvalidArgumentException(code: 3): Convert To Array Error! Invalid Xml! at /www/wwwroot/hua20.cn/vendor/yansongda/pay/src/Gateways/Wechat/Support.php:223)
[stacktrace]
#0 /www/wwwroot/hua20.cn/vendor/yansongda/pay/src/Gateways/Wechat.php(138): Yansongda\\Pay\\Gateways\\Wechat\\Support::fromXml('')
#1 /www/wwwroot/hua20.cn/app/Http/Controllers/RefundNotifyController.php(14): Yansongda\\Pay\\Gateways\\Wechat->verify('<xml><return_co...', true)
#2 [internal function]: App\\Http\\Controllers\\RefundNotifyController->weixin()
yansongda commented 6 years ago

0 /www/wwwroot/hua20.cn/vendor/yansongda/pay/src/Gateways/Wechat.php(138): Yansongda\Pay\Gateways\Wechat\Support::fromXml('')

1 /www/wwwroot/hua20.cn/app/Http/Controllers/RefundNotifyController.php(14): Yansongda\Pay\Gateways\Wechat->verify('<return_co...', true)

verify 函数中 第一个参数有传递内容?

scbing commented 6 years ago

@yansongda https://yansongda.gitbooks.io/pay/docs/wechat/verify.html 和这里的文档一样, 是 异步通知,

你在文档中这样写道: 退款异步通知验证

$result = $wechat->verify(null, true);

我在laravel 也是这样用的

use Yansongda\LaravelPay\Facades\Pay;

$result = Pay::wechat()->verify(null, true);
scbing commented 6 years ago

@yansongda 我猜测 是在 发起 退款请求的时候 增加了notify_url 参数, 不知道是不是它引起的?

yansongda commented 6 years ago

最新版本已经解决,麻烦 composer update 到最新版。

感谢支持