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

---------

Co-authored-by: yansongda <me@yansongda.cn>
This commit is contained in:
嗯嗯 2024-06-12 09:47:48 +08:00 committed by GitHub
parent 3683c69c1a
commit 3d79403bc0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 46 additions and 3 deletions

View File

@ -1,4 +1,8 @@
## TBD - v3.7.5
## v3.7.5
### fixed
- fix: 支付宝响应空签名时签名验证逻辑错误的问题(#998)
### optimized

View File

@ -44,6 +44,8 @@ class Exception extends \Exception
public const RESPONSE_MISSING_NECESSARY_PARAMS = 9305;
public const RESPONSE_BUSINESS_CODE_WRONG = 9306;
/*
* 关于配置.
*/

View File

@ -6,14 +6,19 @@ namespace Yansongda\Pay\Plugin\Alipay\V2;
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 */
@ -26,9 +31,16 @@ class ResponsePlugin implements PluginInterface
$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
)));
}

View File

@ -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;
@ -82,4 +84,27 @@ class ResponsePluginTest extends TestCase
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; });
}
}