fix(security): verify gateway-confirmed amount in payment callback (C1)

The callback marked an order success on any verify-ok result without comparing
the gateway-settled amount to the amount charged. SEP returns AffectiveAmount;
an underpayment or a replayed RefNum from a cheaper order would confirm the
expensive order. Now reject (status=failed, no activation) when the gateway
reports an amount that mismatches the stored amount_rials. Gateways that don't
report a settled amount (Mellat binds it server-side) skip the check.

MockGateway now echoes mock_amount so the guard is exercisable in tests.
Regression: tests/Payment/PaymentCallbackAmountTest (underpayment rejected,
matching amount succeeds).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
hamed
2026-06-28 18:49:33 +03:30
co-authored by Claude Opus 4.8
parent 8e5cd51873
commit ae06498a96
5 changed files with 97 additions and 6 deletions
+6 -1
View File
@@ -26,6 +26,11 @@ class MockGateway implements PaymentGatewayInterface
}
$refId = $callbackData['RefId'] ?? $callbackData['order_id'] ?? 'MOCK-REF';
return new PaymentVerifyResult(true, referenceId: $refId);
// Simulate a gateway that reports the settled amount (like SEP's
// AffectiveAmount) so the controller's amount-mismatch guard is exercisable.
$amount = (int) ($callbackData['mock_amount'] ?? 0);
return new PaymentVerifyResult(true, referenceId: $refId, amountRials: $amount);
}
}