fix(payment): skip Shaparak IP allowlist for browser-redirect gateways (mellat/sep)
Mellat/SEP return the result via a user-browser redirect (POST/GET), so the received IP is the user's, not Shaparak's. The IP allowlist therefore rejected every real callback — including user cancel — with 'forbidden'. Security is provided by the tamper check (RefId/SaleOrderId) and server-side verify. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -285,9 +285,12 @@ class PaymentController extends BaseController
|
||||
public function callback(string $gateway, Request $request): \Symfony\Component\HttpFoundation\Response
|
||||
{
|
||||
$clientIp = $request->getClientIp() ?? '';
|
||||
// در حالت تست یا sandbox ملت، callback از IPی خارج از رنج شاپرک میآید؛ IP-check رد میشود.
|
||||
$bypassIp = $this->gateways->isTestMode()
|
||||
|| ($gateway === 'mellat' && $this->gateways->isMellatSandbox());
|
||||
// درگاههای ملت و سپ نتیجه را با ریدایرکتِ مرورگرِ کاربر (POST/GET) برمیگردانند،
|
||||
// نه server-to-server؛ پس IP دریافتی، IPِ کاربر است و allowlist شاپرک اعمال نمیشود
|
||||
// (در غیر این صورت هر callback واقعی — از جمله «لغو» — رد میشد). امنیت از طریق چک
|
||||
// ضد-دستکاری (RefId/SaleOrderId) و verify سمت بانک در PaymentManager تأمین میشود.
|
||||
$browserRedirectGateways = ['mellat', 'sep'];
|
||||
$bypassIp = $this->gateways->isTestMode() || in_array($gateway, $browserRedirectGateways, true);
|
||||
if (!$bypassIp && !$this->isAllowedCallbackIp($clientIp)) {
|
||||
return $this->renderPaymentResult('forbidden');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user