Fix 401 error on sign request on verify
This commit is contained in:
@@ -105,15 +105,33 @@ class WalletPaymentController extends Controller
|
|||||||
throw new UnprocessableEntityHttpException('پرداخت آنلاین فعال نیست');
|
throw new UnprocessableEntityHttpException('پرداخت آنلاین فعال نیست');
|
||||||
}
|
}
|
||||||
|
|
||||||
$payload = array_filter([
|
$payload = [];
|
||||||
'status' => $request->input('status'),
|
foreach ([
|
||||||
'reference_id' => $request->input('reference_id'),
|
'status',
|
||||||
'session_id' => $request->input('session_id'),
|
'reference_id',
|
||||||
'amount' => $request->input('amount'),
|
'session_id',
|
||||||
'track_number' => $request->input('track_number'),
|
'amount',
|
||||||
'timestamp' => $request->input('timestamp'),
|
'track_number',
|
||||||
'signature' => $request->input('signature'),
|
'timestamp',
|
||||||
], static fn ($v) => $v !== null && $v !== '');
|
'signature',
|
||||||
|
] as $key) {
|
||||||
|
if (!$request->has($key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$value = $request->input($key);
|
||||||
|
if ($value === null || is_array($value)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// track_number خالی هم ممکن است در امضا باشد
|
||||||
|
$payload[$key] = (string) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($payload['signature'] ?? '') === '' || ($payload['reference_id'] ?? '') === '') {
|
||||||
|
return response()->json([
|
||||||
|
'ok' => false,
|
||||||
|
'message' => 'پارامترهای بازگشت ناقص است',
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
|
||||||
$synthetic = Request::create('/', 'GET', $payload);
|
$synthetic = Request::create('/', 'GET', $payload);
|
||||||
$result = $gateway->handleReturn($synthetic);
|
$result = $gateway->handleReturn($synthetic);
|
||||||
|
|||||||
@@ -157,10 +157,16 @@ class MontifyPartnerGateway implements WalletPaymentGatewayInterface
|
|||||||
|
|
||||||
public function handleReturn(Request $request): array
|
public function handleReturn(Request $request): array
|
||||||
{
|
{
|
||||||
$query = $request->query();
|
// query() آبجکت ParameterBag است؛ برای HMAC باید آرایهٔ string باشد
|
||||||
|
$query = $this->normalizeReturnQuery($request->query()->all());
|
||||||
$signer = $this->signer();
|
$signer = $this->signer();
|
||||||
|
|
||||||
if (!$signer->verifyReturnSignature($query)) {
|
if (!$signer->verifyReturnSignature($query)) {
|
||||||
|
\Log::warning('montify.return_invalid_signature', [
|
||||||
|
'keys' => array_keys($query),
|
||||||
|
'reference_id' => $query['reference_id'] ?? null,
|
||||||
|
]);
|
||||||
|
|
||||||
return ['ok' => false, 'withdraw' => null, 'http_status' => 401, 'message' => 'امضای نامعتبر'];
|
return ['ok' => false, 'withdraw' => null, 'http_status' => 401, 'message' => 'امضای نامعتبر'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,6 +206,31 @@ class MontifyPartnerGateway implements WalletPaymentGatewayInterface
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* پارامترهای برگشت Montify باید همگی string باشند (طبق مستند).
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $query
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
private function normalizeReturnQuery(array $query): array
|
||||||
|
{
|
||||||
|
$normalized = [];
|
||||||
|
foreach ($query as $key => $value) {
|
||||||
|
if (!is_string($key) || $key === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (is_array($value)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($value === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$normalized[$key] = (string) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $normalized;
|
||||||
|
}
|
||||||
|
|
||||||
public function handleWebhook(Request $request): array
|
public function handleWebhook(Request $request): array
|
||||||
{
|
{
|
||||||
$body = $request->all();
|
$body = $request->all();
|
||||||
|
|||||||
@@ -49,12 +49,22 @@ class MontifyHmacSigner
|
|||||||
public function verifyReturnSignature(array $query): bool
|
public function verifyReturnSignature(array $query): bool
|
||||||
{
|
{
|
||||||
$signature = (string) ($query['signature'] ?? '');
|
$signature = (string) ($query['signature'] ?? '');
|
||||||
if ($signature === '') {
|
if ($signature === '' || !ctype_xdigit($signature)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($query['signature']);
|
unset($query['signature']);
|
||||||
$expected = hash_hmac('sha256', $this->stableStringify($query), $this->clientSecret);
|
|
||||||
|
// فقط اسکالرها — همه string طبق مستند پارتنر
|
||||||
|
$payload = [];
|
||||||
|
foreach ($query as $key => $value) {
|
||||||
|
if (!is_string($key) || is_array($value) || $value === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$payload[$key] = (string) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$expected = hash_hmac('sha256', $this->stableStringify($payload), $this->clientSecret);
|
||||||
|
|
||||||
return $this->hashEqualsHex($signature, $expected);
|
return $this->hashEqualsHex($signature, $expected);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user