Skip to content

Commit

Permalink
Add irandargah driver (#265)
Browse files Browse the repository at this point in the history
  • Loading branch information
sadegh19b authored Sep 2, 2024
1 parent 65457ac commit 6731a2b
Show file tree
Hide file tree
Showing 3 changed files with 288 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ For **Laravel** integration you can use [shetabit/payment](https://github.com/sh
- [fanavacard](https://www.fanava.com/) :heavy_check_mark:
- [gooyapay](https://gooyapay.ir/) :heavy_check_mark:
- [idpay](https://idpay.ir/) :heavy_check_mark:
- [irandargah](https://irandargah.com/) :heavy_check_mark:
- [irankish](http://irankish.com/) :heavy_check_mark:
- [jibit](https://jibit.ir/) :heavy_check_mark:
- [local](#local-driver) :heavy_check_mark:
Expand Down
17 changes: 17 additions & 0 deletions config/payment.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,22 @@
'sandbox' => false, // set it to true for test environments
'currency' => 'R', //Can be R, T (Rial, Toman)
],
'irandargah' => [
/* Normal api */
'apiPurchaseUrl' => 'https://dargaah.com/payment',
'apiPaymentUrl' => 'https://dargaah.com/ird/startpay/',
'apiVerificationUrl' => 'https://dargaah.com/verification',

/* Sandbox api */
'sandboxApiPurchaseUrl' => ' https://dargaah.com/sandbox/payment',
'sandboxApiPaymentUrl' => 'https://dargaah.com/sandbox/ird/startpay/',
'sandboxApiVerificationUrl' => 'https://dargaah.com/sandbox/verification',

'sandbox' => false, // Set it to true for test environments
'merchantId' => '', // Set `TEST` for test environments (sandbox)
'callbackUrl' => '',
'currency' => 'R', //Can be R, T (Rial, Toman)
],
'irankish' => [
'apiPurchaseUrl' => 'https://ikc.shaparak.ir/api/v3/tokenization/make',
'apiPaymentUrl' => 'https://ikc.shaparak.ir/iuiv3/IPG/Index/',
Expand Down Expand Up @@ -491,6 +507,7 @@
'digipay' => \Shetabit\Multipay\Drivers\Digipay\Digipay::class,
'etebarino' => \Shetabit\Multipay\Drivers\Etebarino\Etebarino::class,
'idpay' => \Shetabit\Multipay\Drivers\Idpay\Idpay::class,
'irandargah' => \Shetabit\Multipay\Drivers\IranDargah\IranDargah::class,
'irankish' => \Shetabit\Multipay\Drivers\Irankish\Irankish::class,
'jibit' => \Shetabit\Multipay\Drivers\Jibit\Jibit::class,
'nextpay' => \Shetabit\Multipay\Drivers\Nextpay\Nextpay::class,
Expand Down
270 changes: 270 additions & 0 deletions src/Drivers/IranDargah/IranDargah.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
<?php

namespace Shetabit\Multipay\Drivers\IranDargah;

use GuzzleHttp\Client;
use Shetabit\Multipay\Abstracts\Driver;
use Shetabit\Multipay\Contracts\ReceiptInterface;
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
use Shetabit\Multipay\Invoice;
use Shetabit\Multipay\Receipt;
use Shetabit\Multipay\RedirectionForm;
use Shetabit\Multipay\Request;

class IranDargah extends Driver
{
/**
* HTTP Client.
*
* @var object
*/
protected $client;

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

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

/**
* IranDargah 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();
}

/**
* Retrieve data from details using its name.
*
* @return string
*/
private function extractDetails($name)
{
return empty($this->invoice->getDetails()[$name]) ? null : $this->invoice->getDetails()[$name];
}

/**
* Purchase Invoice.
*
* @return string
*
* @throws PurchaseFailedException
*/
public function purchase()
{
$data = [
'merchantID' => $this->settings->merchantId,
'amount' => $this->getInvoiceAmount(),
'callbackURL' => $this->settings->callbackUrl,
'orderId' => $this->invoice->getUuid(),
'cardNumber' => $this->extractDetails('cardNumber'),
'mobile' => $this->extractDetails('mobile'),
'description' => $this->extractDetails('description'),
];

$response = $this->client->request(
'POST',
$this->getPurchaseUrl(),
[
'form_params' => $data,
'http_errors' => false,
]
);

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

if ($body['status'] != 200) {
throw new PurchaseFailedException($this->translateStatus($body['status']), $body['status']);
}

$this->invoice->transactionId($body['authority']);

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

/**
* Pay the Invoice
*
* @return RedirectionForm
*/
public function pay(): RedirectionForm
{
$payUrl = $this->getPaymentUrl() . $this->invoice->getTransactionId();

return $this->redirectWithForm($payUrl, [], 'GET');
}

/**
* Verify payment
*
* @return ReceiptInterface
*
* @throws InvalidPaymentException
*/
public function verify(): ReceiptInterface
{
$paymentCode = Request::input('code');

if ($paymentCode != 100) {
throw new InvalidPaymentException($this->translateStatus($paymentCode), $paymentCode);
}

$data = [
'merchantID' => $this->settings->merchantId,
'authority' => $this->invoice->getTransactionId() ?? Request::input('authority'),
'amount' => $this->getInvoiceAmount(),
'orderId' => Request::input('orderId'),
];

$response = $this->client->request(
'POST',
$this->getVerificationUrl(),
[
'json' => $data,
"headers" => [
'Content-Type' => 'application/json',
],
"http_errors" => false,
]
);

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

if ($body['status'] != 100) {
throw new InvalidPaymentException($this->translateStatus($body['status']), $body['status']);
}

$refId = $body['refId'];
$receipt = $this->createReceipt($refId);

$receipt->detail([
'message' => $body['message'],
'status' => $body['status'],
'refId' => $refId,
'orderId' => $body['orderId'],
'cardNumber' => $body['cardNumber'],
]);

return $receipt;
}

/**
* Generate the payment's receipt
*
* @param $referenceId
*
* @return Receipt
*/
public function createReceipt($referenceId)
{
return new Receipt('irandargah', $referenceId);
}

/**
* Retrieve invoice amount
*
* @return int|float
*/
protected function getInvoiceAmount()
{
return $this->invoice->getAmount() * (strtolower($this->settings->currency) === 't' ? 10 : 1); // convert to rial
}

/**
* Retrieve purchase url
*
* @return string
*/
protected function getPurchaseUrl(): string
{
return $this->isSandboxMode()
? $this->settings->sandboxApiPurchaseUrl
: $this->settings->apiPurchaseUrl;
}

/**
* Retrieve Payment url
*
* @return string
*/
protected function getPaymentUrl(): string
{
return $this->isSandboxMode()
? $this->settings->sandboxApiPaymentUrl
: $this->settings->apiPaymentUrl;
}

/**
* Retrieve verification url
*
* @return string
*/
protected function getVerificationUrl(): string
{
return $this->isSandboxMode()
? $this->settings->sandboxApiVerificationUrl
: $this->settings->apiVerificationUrl;
}

/**
* Retrieve payment in sandbox mode?
*
* @return bool
*/
protected function isSandboxMode() : bool
{
return $this->settings->sandbox;
}

/**
* Convert status to a readable message.
*
* @param $status
*
* @return mixed|string
*/
private function translateStatus($status)
{
$translations = [
'100' => 'تراکنش با موفقیت انجام ‌شده‌ است',
'101' => 'تراکنش قبلا وریفای شده است',
'200' => 'اتصال به درگاه بانک با موفقیت انجام ‌شده است',
'201' => 'در حال پرداخت در درگاه بانک',
'403' => 'کد مرچنت صحیح نمی‌باشد',
'404' => 'تراکنش یافت نشد',
'-1' => 'کاربر از انجام تراکنش منصرف‌ شده است',
'-2' => 'اطلاعات ارسالی صحیح نمی‌باشد',
'-10' => 'مبلغ تراکنش کمتر از ۱۰،۰۰۰ ریال است',
'-11' => 'مبلغ تراکنش با مبلغ پرداخت، یکسان نیست. مبلغ برگشت خورد',
'-12' => 'شماره کارتی که با آن، تراکنش انجام ‌شده است با شماره کارت ارسالی، مغایرت دارد. مبلغ برگشت خورد',
'-13' => 'تراکنش تکراری است',
'-20' => 'شناسه تراکنش یافت‌ نشد',
'-21' => 'مدت زمان مجاز، جهت ارسال به بانک گذشته‌است',
'-22' => 'تراکنش برای بانک ارسال شده است',
'-23' => 'خطا در اتصال به درگاه بانک',
'-30' => 'اشکالی در فرایند پرداخت ایجاد ‌شده است. مبلغ برگشت خورد',
'-31' => 'خطای ناشناخته',
];

$unknownError = 'خطای ناشناخته رخ داده است. در صورت کسر مبلغ از حساب حداکثر پس از 72 ساعت به حسابتان برمیگردد';

return array_key_exists($status, $translations) ? $translations[$status] : $unknownError;
}
}

0 comments on commit 6731a2b

Please sign in to comment.