Skip to content

Commit

Permalink
fix: 支付宝响应空签名时签名验证逻辑错误的问题 (#998)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: yansongda <me@yansongda.cn>
  • Loading branch information
lazychanger and yansongda committed Jun 12, 2024
1 parent 3683c69 commit 3d79403
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 3 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
## TBD - v3.7.5
## v3.7.5

### fixed

- fix: 支付宝响应空签名时签名验证逻辑错误的问题(#998)

### optimized

Expand Down
2 changes: 2 additions & 0 deletions src/Exception/Exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class Exception extends \Exception

public const RESPONSE_MISSING_NECESSARY_PARAMS = 9305;

public const RESPONSE_BUSINESS_CODE_WRONG = 9306;

/*
* 关于配置.
*/
Expand Down
16 changes: 14 additions & 2 deletions src/Plugin/Alipay/V2/ResponsePlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@

use Closure;
use Yansongda\Artful\Contract\PluginInterface;
use Yansongda\Artful\Exception\InvalidResponseException;
use Yansongda\Artful\Logger;
use Yansongda\Artful\Rocket;
use Yansongda\Pay\Exception\Exception;
use Yansongda\Supports\Collection;

use function Yansongda\Artful\should_do_http_request;

class ResponsePlugin implements PluginInterface
{
/**
* @throws InvalidResponseException
*/
public function assembly(Rocket $rocket, Closure $next): Rocket
{
/* @var Rocket $rocket */
Expand All @@ -26,9 +31,16 @@ public function assembly(Rocket $rocket, Closure $next): Rocket
$resultKey = str_replace('.', '_', $payload->get('method')).'_response';

if (should_do_http_request($rocket->getDirection()) && $destination instanceof Collection) {
$sign = $destination->get('sign', '');
$response = $destination->get($resultKey, $destination->all());

if (empty($sign) && '10000' !== ($response['code'] ?? 'null')) {
throw new InvalidResponseException(Exception::RESPONSE_BUSINESS_CODE_WRONG, '支付宝网关响应异常: '.($response['sub_msg'] ?? $response['msg'] ?? '未知错误,请查看支付宝原始响应'), $rocket->getDestination());
}

$rocket->setDestination(new Collection(array_merge(
['_sign' => $destination->get('sign', '')],
$destination->get($resultKey, $destination->all())
['_sign' => $sign],
$response
)));
}

Expand Down
25 changes: 25 additions & 0 deletions tests/Plugin/Alipay/V2/ResponsePluginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Yansongda\Pay\Tests\Plugin\Alipay\V2;

use Yansongda\Artful\Exception\InvalidResponseException;
use Yansongda\Pay\Exception\Exception;
use Yansongda\Pay\Plugin\Alipay\V2\ResponsePlugin;
use Yansongda\Artful\Rocket;
use Yansongda\Pay\Tests\TestCase;
Expand Down Expand Up @@ -82,4 +84,27 @@ public function testErrorResponseWithNoMethodKey()

self::assertEquals(array_merge(['_sign' => '123'], $destination), $result->getDestination()->all());
}

public function testErrorResponseWithEmptySignKey()
{
self::expectException(InvalidResponseException::class);
self::expectExceptionCode(Exception::RESPONSE_BUSINESS_CODE_WRONG);
self::expectExceptionMessage('支付宝网关响应异常: 无效的AppID参数');

$destination = [
'alipay_fund_trans_uni_transfer_response' => [
'code' => '40002',
'msg' => 'Invalid Arguments',
'sub_code' => 'isv.invalid-app-id',
'sub_msg' => '无效的AppID参数',
],
'sign' => ''
];

$rocket = (new Rocket())
->mergePayload(['method' => 'alipay_fund_trans_uni_transfer'])
->setDestination(new Collection($destination));

$this->plugin->assembly($rocket, function ($rocket) {return $rocket; });
}
}

0 comments on commit 3d79403

Please sign in to comment.