Shepa   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 226
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 72
c 1
b 0
f 0
dl 0
loc 226
rs 10
wmc 23

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getInvoiceAmount() 0 3 2
A getPurchaseUrl() 0 5 2
A extractDetails() 0 3 2
A purchase() 0 35 4
A getVerificationUrl() 0 5 2
A createReceipt() 0 3 1
A getPaymentUrl() 0 5 2
A pay() 0 5 1
A isSandboxMode() 0 3 1
A verify() 0 48 5
A __construct() 0 5 1
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Shepa;
4
5
use GuzzleHttp\Client;
6
use Shetabit\Multipay\Abstracts\Driver;
7
use Shetabit\Multipay\Contracts\ReceiptInterface;
8
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
9
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
10
use Shetabit\Multipay\Invoice;
11
use Shetabit\Multipay\Receipt;
12
use Shetabit\Multipay\RedirectionForm;
13
use Shetabit\Multipay\Request;
14
15
class Shepa extends Driver
16
{
17
    /**
18
     * HTTP Client.
19
     *
20
     * @var object
21
     */
22
    protected $client;
23
24
    /**
25
     * Invoice
26
     *
27
     * @var Invoice
28
     */
29
    protected $invoice;
30
31
    /**
32
     * Driver settings
33
     *
34
     * @var object
35
     */
36
    protected $settings;
37
38
    /**
39
     * Shepa constructor.
40
     * Construct the class with the relevant settings.
41
     *
42
     * @param Invoice $invoice
43
     * @param $settings
44
     */
45
    public function __construct(Invoice $invoice, $settings)
46
    {
47
        $this->invoice($invoice);
48
        $this->settings = (object) $settings;
49
        $this->client = new Client();
50
    }
51
52
    /**
53
     * Retrieve data from details using its name.
54
     *
55
     * @return string
56
     */
57
    private function extractDetails($name)
58
    {
59
        return empty($this->invoice->getDetails()[$name]) ? null : $this->invoice->getDetails()[$name];
60
    }
61
62
    /**
63
     * Purchase Invoice.
64
     *
65
     * @return string
66
     *
67
     * @throws PurchaseFailedException
68
     */
69
    public function purchase()
70
    {
71
        $data = [
72
            'api' => $this->settings->merchantId,
73
            'amount' => $this->getInvoiceAmount(),
74
            'callback' => $this->settings->callbackUrl,
75
            'mobile' => $this->extractDetails('mobile'),
76
            'email' => $this->extractDetails('email'),
77
            'cardnumber' => $this->extractDetails('cardnumber'),
78
            'description' => $this->extractDetails('description'),
79
        ];
80
81
        $response = $this->client->request(
82
            'POST',
83
            $this->getPurchaseUrl(),
84
            [
85
                'form_params' => $data,
86
                'http_errors' => false,
87
            ]
88
        );
89
90
        $body = json_decode($response->getBody()->getContents(), true);
91
92
        if (!empty($body['error']) || !empty($body['errors'])) {
93
            $errors = !empty($body['error'])
94
                ? $body['error']
95
                : $body['errors'];
96
97
            throw new PurchaseFailedException(implode(', ', $errors));
98
        }
99
100
        $this->invoice->transactionId($body['result']['token']);
101
102
        // return the transaction's id
103
        return $this->invoice->getTransactionId();
104
    }
105
106
    /**
107
     * Pay the Invoice
108
     *
109
     * @return RedirectionForm
110
     */
111
    public function pay(): RedirectionForm
112
    {
113
        $payUrl = $this->getPaymentUrl() . $this->invoice->getTransactionId();
114
115
        return $this->redirectWithForm($payUrl, [], 'GET');
116
    }
117
118
    /**
119
     * Verify payment
120
     *
121
     * @return ReceiptInterface
122
     *
123
     * @throws InvalidPaymentException
124
     */
125
    public function verify(): ReceiptInterface
126
    {
127
        $paymentStatus = Request::input('status');
128
129
        if ($paymentStatus !== 'success') {
130
            throw new InvalidPaymentException('تراکنش از سوی کاربر لغو شد.');
131
        }
132
133
        $data = [
134
            'api' => $this->settings->merchantId,
135
            'token' => $this->invoice->getTransactionId() ?? Request::input('token'),
136
            'amount' => $this->getInvoiceAmount()
137
        ];
138
139
        $response = $this->client->request(
140
            'POST',
141
            $this->getVerificationUrl(),
142
            [
143
                'json' => $data,
144
                "headers" => [
145
                    'Content-Type' => 'application/json',
146
                ],
147
                "http_errors" => false,
148
            ]
149
        );
150
151
        $body = json_decode($response->getBody()->getContents(), true);
152
153
        if (!empty($body['error']) || !empty($body['errors'])) {
154
            $errors = !empty($body['error'])
155
                ? $body['error']
156
                : $body['errors'];
157
158
            throw new InvalidPaymentException(implode(', ', $errors));
159
        }
160
161
        $refId = $body['result']['refid'];
162
        $receipt =  $this->createReceipt($refId);
163
164
        $receipt->detail([
165
            'refid' => $refId,
166
            'transaction_id' => $body['result']['transaction_id'],
167
            'amount' => $body['result']['amount'],
168
            'card_pan' => $body['result']['card_pan'],
169
            'date' => $body['result']['date'],
170
        ]);
171
172
        return $receipt;
173
    }
174
175
    /**
176
     * Generate the payment's receipt
177
     *
178
     * @param $referenceId
179
     *
180
     * @return Receipt
181
     */
182
    public function createReceipt($referenceId)
183
    {
184
        return new Receipt('shepa', $referenceId);
185
    }
186
187
    /**
188
     * Retrieve invoice amount
189
     *
190
     * @return int|float
191
     */
192
    protected function getInvoiceAmount()
193
    {
194
        return $this->invoice->getAmount() * (strtolower($this->settings->currency) === 't' ? 10 : 1); // convert to rial
195
    }
196
197
    /**
198
     * Retrieve purchase url
199
     *
200
     * @return string
201
     */
202
    protected function getPurchaseUrl(): string
203
    {
204
        return $this->isSandboxMode()
205
            ? $this->settings->sandboxApiPurchaseUrl
206
            : $this->settings->apiPurchaseUrl;
207
    }
208
209
    /**
210
     * Retrieve Payment url
211
     *
212
     * @return string
213
     */
214
    protected function getPaymentUrl(): string
215
    {
216
        return $this->isSandboxMode()
217
            ? $this->settings->sandboxApiPaymentUrl
218
            : $this->settings->apiPaymentUrl;
219
    }
220
221
    /**
222
     * Retrieve verification url
223
     *
224
     * @return string
225
     */
226
    protected function getVerificationUrl(): string
227
    {
228
        return $this->isSandboxMode()
229
            ? $this->settings->sandboxApiVerificationUrl
230
            : $this->settings->apiVerificationUrl;
231
    }
232
233
    /**
234
     * Retrieve payment in sandbox mode?
235
     *
236
     * @return bool
237
     */
238
    protected function isSandboxMode() : bool
239
    {
240
        return $this->settings->sandbox;
241
    }
242
}
243