HEX
Server: LiteSpeed
System: Linux sv4.hami.host 5.14.0-611.54.3.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 7 16:31:24 EDT 2026 x86_64
User: armgroup (1008)
PHP: 8.2.32
Disabled: show_source, system, shell_exec, passthru, exec, popen, proc_open, mail, socket_create, socket_create_listen, socket_create_pair, link, dl, openlog, syslog, stream_socket_server, curl_multi_init
Upload Files
File: //home/armgroup/libs/vendor/shetabit/multipay/src/Drivers/Pasargad/Pasargad.php
<?php

namespace Shetabit\Multipay\Drivers\Pasargad;

use GuzzleHttp\Client;
use Shetabit\Multipay\Invoice;
use Shetabit\Multipay\Receipt;
use Shetabit\Multipay\Abstracts\Driver;
use Shetabit\Multipay\Contracts\ReceiptInterface;
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
use Shetabit\Multipay\Drivers\Pasargad\Utils\RSAProcessor;
use Shetabit\Multipay\RedirectionForm;
use Shetabit\Multipay\Request;
use DateTimeZone;
use DateTime;

class Pasargad extends Driver
{
    /**
     * Guzzle client
     *
     * @var object
     */
    protected $client;

    /**
     * Invoice
     *
     * @var Invoice
     */
    protected $invoice;

    /**
     * Driver settings
     *
     * @var object
     */
    protected $settings;

    /**
     * Prepared invoice's data
     *
     * @var array
     */
    protected $preparedData = array();

    /**
     * Pasargad(PEP) constructor.
     * Construct the class with the relevant settings.
     *
     * @param Invoice $invoice
     * @param $settings
     */
    public function __construct(Invoice $invoice, $settings)
    {
        $this->invoice($invoice);
        $this->settings = (object) $settings;
        $this->client = new Client();
    }

    /**
     * Purchase Invoice.
     *
     * @return string
     */
    public function purchase()
    {
        $invoiceData = $this->getPreparedInvoiceData();

        $this->invoice->transactionId($invoiceData['InvoiceNumber']);

        // return the transaction's id
        return $this->invoice->getTransactionId();
    }

    /**
     * Pay the Invoice
     *
     * @return RedirectionForm
     */
    public function pay() : RedirectionForm
    {
        $paymentUrl = $this->settings->apiPaymentUrl;
        $getTokenUrl = $this->settings->apiGetToken;
        $tokenData = $this->request($getTokenUrl, $this->getPreparedInvoiceData());

        // redirect using HTML form
        return $this->redirectWithForm($paymentUrl, $tokenData, 'POST');
    }

    /**
     * Verify payment
     *
     * @return ReceiptInterface
     *
     * @throws InvalidPaymentException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function verify() : ReceiptInterface
    {
        $invoiceDetails = $this->request(
            $this->settings->apiCheckTransactionUrl,
            [
                'TransactionReferenceID' => Request::input('tref')
            ]
        );
        $amount = $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1); // convert to rial
        if ($amount != $invoiceDetails['Amount']) {
            throw new InvalidPaymentException('Invalid amount');
        }
        $iranTime = new DateTime('now', new DateTimeZone('Asia/Tehran'));
        $fields = [
            'MerchantCode' => $invoiceDetails['MerchantCode'],
            'TerminalCode' => $invoiceDetails['TerminalCode'],
            'InvoiceNumber' => $invoiceDetails['InvoiceNumber'],
            'InvoiceDate' => $invoiceDetails['InvoiceDate'],
            'Amount' => $invoiceDetails['Amount'],
            'Timestamp' => $iranTime->format("Y/m/d H:i:s"),
        ];

        $verifyResult = $this->request($this->settings->apiVerificationUrl, $fields);

        return $this->createReceipt($verifyResult, $invoiceDetails);
    }

    /**
     * Generate the payment's receipt
     *
     * @param $referenceId
     *
     * @return Receipt
     */
    protected function createReceipt($verifyResult, $invoiceDetails)
    {
        $referenceId = $invoiceDetails['TransactionReferenceID'];
        $traceNumber = $invoiceDetails['TraceNumber'];
        $referenceNumber = $invoiceDetails['ReferenceNumber'];

        $reciept = new Receipt('Pasargad', $referenceId);

        $reciept->detail('TraceNumber', $traceNumber);
        $reciept->detail('ReferenceNumber', $referenceNumber);
        $reciept->detail('MaskedCardNumber', $verifyResult['MaskedCardNumber']);
        $reciept->detail('ShaparakRefNumber', $verifyResult['ShaparakRefNumber']);

        return $reciept;
    }

    /**
     * A default message for exceptions
     *
     * @return string
     */
    protected function getDefaultExceptionMessage()
    {
        return 'مشکلی در دریافت اطلاعات از بانک به وجود آمده است';
    }

    /**
     * Sign given data.
     *
     * @param string $data
     *
     * @return string
     */
    public function sign($data)
    {
        $certificate = $this->settings->certificate;
        $certificateType = $this->settings->certificateType;

        $processor = new RSAProcessor($certificate, $certificateType);

        return $processor->sign($data);
    }

    /**
     * Retrieve prepared invoice's data
     *
     * @return array
     */
    protected function getPreparedInvoiceData()
    {
        if (empty($this->preparedData)) {
            $this->preparedData = $this->prepareInvoiceData();
        }

        return $this->preparedData;
    }

    /**
     * Prepare invoice data
     *
     * @return array
     */
    protected function prepareInvoiceData(): array
    {
        $action = 1003; // 1003 : for buy request (bank standard)
        $merchantCode = $this->settings->merchantId;
        $terminalCode = $this->settings->terminalCode;
        $amount = $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1); // convert to rial
        $redirectAddress = $this->settings->callbackUrl;
        $invoiceNumber = crc32($this->invoice->getUuid()) . rand(0, time());

        $iranTime = new DateTime('now', new DateTimeZone('Asia/Tehran'));
        $timeStamp = $iranTime->format("Y/m/d H:i:s");
        $invoiceDate = $iranTime->format("Y/m/d H:i:s");

        if (!empty($this->invoice->getDetails()['date'])) {
            $invoiceDate = $this->invoice->getDetails()['date'];
        }

        return [
            'InvoiceNumber' => $invoiceNumber,
            'InvoiceDate' => $invoiceDate,
            'Amount' => $amount,
            'TerminalCode' => $terminalCode,
            'MerchantCode' => $merchantCode,
            'RedirectAddress' => $redirectAddress,
            'Timestamp' => $timeStamp,
            'Action' => $action,
        ];
    }

    /**
     * Prepare signature based on Pasargad document
     *
     * @param string $data
     * @return string
     */
    public function prepareSignature(string $data): string
    {
        return base64_encode($this->sign(sha1($data, true)));
    }

    /**
     * Make request to pasargad's Api
     *
     * @param string $url
     * @param array $body
     * @param string $method
     * @return array
     */
    protected function request(string $url, array $body, $method = 'POST'): array
    {
        $body = json_encode($body);
        $sign = $this->prepareSignature($body);

        $response = $this->client->request(
            'POST',
            $url,
            [
                'body' => $body,
                'headers' => [
                    'content-type' => 'application/json',
                    'Sign' => $sign
                ],
                "http_errors" => false,
            ]
        );

        $result = json_decode($response->getBody(), true);

        if ($result['IsSuccess'] === false) {
            throw new InvalidPaymentException($result['Message']);
        }

        return $result;
    }
}