merchantId = config('ifnex.zarinpal.merchant_id', 'fake-merchant-id-for-testing'); $isProduction = config('ifnex.zarinpal.sandbox', true); // URLs برای محیط تست و واقعی $this->baseUrl = $isProduction ? 'https://sandbox.zarinpal.com/pg/v4' : 'https://api.zarinpal.com/pg/v4'; $this->callbackUrl = config('ifnex.zarinpal.callback_url', url('/api/v1/payment/callback')); } /** * ایجاد درخواست پرداخت (Payment Request) */ public function requestPayment( float $amount, string $description, ?string $mobile = null, ?string $email = null ): array { $amountToman = (int) round($amount / 10); // ریال به تومان $response = Http::timeout(30)->post("{$this->baseUrl}/PaymentRequest.json", [ 'merchant_id' => $this->merchantId, 'amount' => $amountToman, 'currency' => 'IRR', 'description' => $description, 'callback_url' => $this->callbackUrl, 'metadata' => [ 'mobile' => $mobile, 'email' => $email, ], ]); $result = $response->json(); Log::info('Zarinpal Payment Request', [ 'amount' => $amountToman, 'response' => $result, ]); if ($result['data']['code'] !== 100) { throw new \Exception('خطا در ارتباط با زرین‌پال: ' . ($result['errors']['message'] ?? 'نامشخص')); } $authority = $result['data']['authority']; $paymentUrl = $this->getPaymentUrl($authority); return [ 'authority' => $authority, 'payment_url' => $paymentUrl, 'amount' => $amount, 'amount_toman' => $amountToman, ]; } /** * بررسی صحت پرداخت (Verification) */ public function verifyPayment(string $authority, float $expectedAmount): array { $amountToman = (int) round($expectedAmount / 10); $response = Http::timeout(30)->post("{$this->baseUrl}/PaymentVerification.json", [ 'merchant_id' => $this->merchantId, 'authority' => $authority, 'amount' => $amountToman, ]); $result = $response->json(); Log::info('Zarinpal Payment Verification', [ 'authority' => $authority, 'response' => $result, ]); if ($result['data']['code'] === 100) { return [ 'success' => true, 'ref_id' => $result['data']['ref_id'], 'card_hash' => $result['data']['card_hash'] ?? null, 'card_pan' => $result['data']['card_pan'] ?? null, ]; } elseif ($result['data']['code'] === 101) { // قبلاً verify شده return [ 'success' => true, 'ref_id' => $result['data']['ref_id'] ?? null, 'already_verified' => true, ]; } return [ 'success' => false, 'error_code' => $result['data']['code'] ?? null, 'error_message' => $result['errors']['message'] ?? 'نامشخص', ]; } /** * ساخت لینک پرداخت */ private function getPaymentUrl(string $authority): string { $isProduction = config('ifnex.zarinpal.sandbox', true); $gatewayUrl = $isProduction ? 'https://sandbox.zarinpal.com/pg/StartPay/' : 'https://www.zarinpal.com/pg/StartPay/'; return $gatewayUrl . $authority; } }