Fanavacard   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 181
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 69
c 1
b 0
f 1
dl 0
loc 181
rs 10
wmc 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A pay() 0 8 1
A createReceipt() 0 14 1
A getWsContext() 0 3 1
A getToken() 0 27 4
A httpClientInit() 0 7 1
A purchase() 0 7 1
A verify() 0 31 5
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Fanavacard;
4
5
use GuzzleHttp\Client;
6
use Shetabit\Multipay\Abstracts\Driver;
7
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
8
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
9
use Shetabit\Multipay\Contracts\ReceiptInterface;
10
use Shetabit\Multipay\Invoice;
11
use Shetabit\Multipay\Receipt;
12
use Shetabit\Multipay\RedirectionForm;
13
use Shetabit\Multipay\Request;
14
use const CURLOPT_SSL_CIPHER_LIST;
15
16
class Fanavacard extends Driver
17
{
18
    /**
19
     * client
20
     *
21
     * @var Client
22
     */
23
    protected $client;
24
25
    /**
26
     * Invoice
27
     *
28
     * @var Invoice
29
     */
30
    protected $invoice;
31
32
    /**
33
     * Driver settings
34
     *
35
     * @var object
36
     */
37
    protected $settings;
38
39
    /**
40
     * Etebarino constructor.
41
     * Construct the class with the relevant settings.
42
     *
43
     * @param Invoice $invoice
44
     * @param $settings
45
     */
46
    public function __construct(Invoice $invoice, $settings)
47
    {
48
        $this->invoice($invoice);
49
        $this->settings = (object)$settings;
50
        $this->httpClientInit();
51
    }
52
53
    /**
54
     * Purchase Invoice
55
     *
56
     * @return string
57
     *
58
     * @throws PurchaseFailedException
59
     */
60
    public function purchase()
61
    {
62
        $this->invoice->uuid(crc32($this->invoice->getUuid()));
63
        $token  = $this->getToken();
64
        $this->invoice->transactionId($token['Token']);
65
66
        return $this->invoice->getTransactionId();
67
    }
68
69
    /**
70
     * Pay the Invoice
71
     *
72
     * @return RedirectionForm
73
     */
74
    public function pay(): RedirectionForm
75
    {
76
        $url = rtrim($this->settings->baseUri, '/')."/{$this->settings->apiPaymentUrl}";
77
78
        return $this->redirectWithForm($url, [
79
            'token' => $this->invoice->getTransactionId(),
80
            'language' => 'fa'
81
        ], 'POST');
82
    }
83
84
    /**
85
     * Verify payment
86
     *
87
     * @return ReceiptInterface
88
     *
89
     * @throws PurchaseFailedException
90
     * @throws InvalidPaymentException
91
     */
92
    public function verify(): ReceiptInterface
93
    {
94
        $transaction_amount = Request::input('transactionAmount');
95
        $amount = $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1); // convert to rial
96
97
        if ($amount == $transaction_amount) {
98
            $param = ['Token'=>Request::input('token'), 'RefNum'=>Request::input('RefNum')];
99
            $response = $this->client->post($this->settings->apiVerificationUrl, [
100
                'json'=> array_merge(
101
                    ['WSContext'=> $this->getWsContext()],
102
                    $param
103
                )]);
104
105
            $response_data = json_decode($response->getBody()->getContents());
106
            if ($response_data->Result != 'erSucceed') {
107
                throw new InvalidPaymentException($response_data->Result);
108
            } elseif ($amount != $response_data->Amount) {
109
                $this->client->post(
110
                    $this->settings->apiReverseAmountUrl,
111
                    [
112
                        'json'=> [
113
                            'WSContext'=> $this->getWsContext(),
114
                            $param
115
                        ]
116
                    ]
117
                );
118
                throw new InvalidPaymentException('مبلغ تراکنش برگشت داده شد');
119
            }
120
        }
121
122
        return $this->createReceipt(Request::input('ResNum'));
123
    }
124
125
126
    /**
127
     * Generate the payment's receipt
128
     *
129
     * @param $referenceId
130
     *
131
     * @return Receipt
132
     */
133
    protected function createReceipt($referenceId): Receipt
134
    {
135
        $receipt = new Receipt('fanavacard', $referenceId);
136
        $receipt->detail([
137
                             'ResNum'=>Request::input('ResNum'),
138
                             'RefNum'=>Request::input('RefNum'),
139
                             'token'=>Request::input('token'),
140
                             'CustomerRefNum'=>Request::input('CustomerRefNum'),
141
                             'CardMaskPan'=>Request::input('CardMaskPan'),
142
                             'transactionAmount'=>Request::input('transactionAmount'),
143
                             'emailAddress'=>Request::input('emailAddress'),
144
                             'mobileNo'=>Request::input('mobileNo'),
145
                         ]);
146
        return $receipt;
147
    }
148
149
    /**
150
     * call create token request
151
     *
152
     * @return array
153
     * @throws PurchaseFailedException
154
     */
155
    public function getToken(): array
156
    {
157
        $response = $this->client->request('POST', $this->settings->apiPurchaseUrl, [
158
            'json'=>[
159
                'WSContext'=> $this->getWsContext(),
160
                'TransType'=>'EN_GOODS',
161
                'ReserveNum'=>$this->invoice->getDetail('invoice_number') ?? crc32($this->invoice->getUuid()),
162
                'Amount'=> $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1), // convert to rial
163
                'RedirectUrl'=>$this->settings->callbackUrl,
164
            ]]);
165
166
        if ($response->getStatusCode() != 200) {
167
            throw new PurchaseFailedException(
168
                "cant get token |  {$response->getBody()->getContents()}",
169
                $response->getStatusCode()
170
            );
171
        }
172
173
        $response_data = json_decode($response->getBody()->getContents());
174
        if ($response_data->Result != 'erSucceed') {
175
            throw new PurchaseFailedException(
176
                "cant get token |  {$response->getBody()->getContents()}",
177
                $response->getStatusCode()
178
            );
179
        }
180
181
        return (array) $response_data;
182
    }
183
184
    private function httpClientInit(): void
185
    {
186
        $this->client = new Client([
187
                                       'curl'=>[CURLOPT_SSL_CIPHER_LIST=>'DEFAULT@SECLEVEL=1',],
188
                                       'verify' => false,
189
                                       'base_uri' => $this->settings->baseUri,
190
                                       'headers' => ['Content-Type' => 'application/json',],
191
                                   ]);
192
    }
193
194
    private function getWsContext(): array
195
    {
196
        return ['UserId' => $this->settings->username, 'Password' => $this->settings->password];
197
    }
198
}
199