Passed
Push — master ( 047831...1469ea )
by mahdi
03:01
created

Sadad::getPurchaseUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 14
rs 9.9666
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Sadad;
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
15
class Sadad extends Driver
16
{
17
    /**
18
     * Sadad 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
     * Sadad 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
     * Purchase Invoice.
54
     *
55
     * @return string
56
     *
57
     * @throws PurchaseFailedException
58
     * @throws \GuzzleHttp\Exception\GuzzleException
59
     */
60
    public function purchase()
61
    {
62
        $terminalId = $this->settings->terminalId;
63
        $orderId = crc32($this->invoice->getUuid());
64
        $amount = $this->invoice->getAmount() * 10; // convert to rial
65
        $key = $this->settings->key;
66
67
        $signData = $this->encrypt_pkcs7("$terminalId;$orderId;$amount", $key);
68
69
        $data = array(
70
            'MerchantId' => $this->settings->merchantId,
71
            'ReturnUrl' => $this->settings->callbackUrl,
72
            'PaymentIdentity' => $this->settings->PaymentIdentity,
73
            'LocalDateTime' => date("m/d/Y g:i:s a"),
74
            'SignData' => $signData,
75
            'TerminalId' => $terminalId,
76
            'Amount' => $amount,
77
            'OrderId' => $orderId,
78
        );
79
80
        $response = $this
81
            ->client
82
            ->request(
83
                'POST',
84
                $this->getPaymentUrl(),
85
                [
86
                    "json" => $data,
87
                    "headers" => [
88
                        'Content-Type' => 'application/json',
89
                        'User-Agent' => '',
90
                    ],
91
                    "http_errors" => false,
92
                ]
93
            );
94
95
        $body = @json_decode($response->getBody()->getContents());
96
97
        if (empty($body)) {
98
            throw new PurchaseFailedException('دسترسی به صفحه مورد نظر امکان پذیر نمی باشد.');
99
        } elseif ($body->ResCode != 0) {
100
            throw new PurchaseFailedException($body->Description);
101
        }
102
103
        $this->invoice->transactionId($body->Token);
104
105
        // return the transaction's id
106
        return $this->invoice->getTransactionId();
107
    }
108
109
    /**
110
     * Pay the Invoice
111
     *
112
     * @return RedirectionForm
113
     */
114
    public function pay() : RedirectionForm
115
    {
116
        $token = $this->invoice->getTransactionId();
117
        $payUrl = $this->getPurchaseUrl();
118
119
        return $this->redirectWithForm($payUrl, ['Token' => $token], 'GET');
120
    }
121
122
    /**
123
     * Verify payment
124
     *
125
     * @return ReceiptInterface
126
     *
127
     * @throws InvalidPaymentException
128
     * @throws \GuzzleHttp\Exception\GuzzleException
129
     */
130
    public function verify() : ReceiptInterface
131
    {
132
        $key = $this->settings->key;
133
        $token = $this->invoice->getTransactionId() ?? Request::input('token');
134
        $resCode = Request::input('ResCode');
135
        $message = 'تراکنش نا موفق بود در صورت کسر مبلغ از حساب شما حداکثر پس از 72 ساعت مبلغ به حسابتان برمیگردد.';
136
137
        if ($resCode != 0) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $resCode of type mixed|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
138
            throw new InvalidPaymentException($message);
139
        }
140
141
        $data = array(
142
            'Token' => $token,
143
            'SignData' => $this->encrypt_pkcs7($token, $key)
144
        );
145
146
        $response = $this
147
            ->client
148
            ->request(
149
                'POST',
150
                $this->settings->apiVerificationUrl,
151
                [
152
                    "json" => $data,
153
                    "headers" => [
154
                        'Content-Type' => 'application/json',
155
                        'User-Agent' => '',
156
                    ],
157
                    "http_errors" => false,
158
                ]
159
            );
160
161
        $body = json_decode($response->getBody()->getContents());
162
163
        if ($body->ResCode != 0) {
164
            throw new InvalidPaymentException($message);
165
        }
166
167
        /**
168
         * شماره سفارش : $orderId = Request::input('OrderId')
169
         * شماره پیگیری : $body->SystemTraceNo
170
         * شماره مرجع : $body->RetrievalRefNo
171
         */
172
173
        $receipt = $this->createReceipt($body->SystemTraceNo);
174
        $receipt->detail([
175
            'orderId' => $body->OrderId,
176
            'traceNo' => $body->SystemTraceNo,
177
            'referenceNo' => $body->RetrivalRefNo,
178
            'description' => $body->Description,
179
        ]);
180
181
        return $receipt;
182
    }
183
184
    /**
185
     * Generate the payment's receipt
186
     *
187
     * @param $referenceId
188
     *
189
     * @return Receipt
190
     */
191
    protected function createReceipt($referenceId)
192
    {
193
        $receipt = new Receipt('sadad', $referenceId);
194
195
        return $receipt;
196
    }
197
198
    /**
199
     * Create sign data(Tripledes(ECB,PKCS7))
200
     *
201
     * @param $str
202
     * @param $key
203
     *
204
     * @return string
205
     */
206
    protected function encrypt_pkcs7($str, $key)
207
    {
208
        $key = base64_decode($key);
209
        $ciphertext = OpenSSL_encrypt($str, "DES-EDE3", $key, OPENSSL_RAW_DATA);
210
211
        return base64_encode($ciphertext);
212
    }
213
    
214
    /**
215
     * Retrieve payment mode.
216
     *
217
     * @return string
218
     */
219
    protected function getMode() : string
220
    {
221
        return strtolower($this->settings->mode);
222
    }
223
224
225
    /**
226
     * Retrieve purchase url
227
     *
228
     * @return string
229
     */
230
    protected function getPurchaseUrl() : string
231
    {
232
        $mode = $this->getMode();
233
234
        switch ($mode) {
235
            case 'paymentbyidentity':
236
                $url = $this->settings->apiPurchaseUrl;
237
                break;
238
            default: // default: normal
239
                $url = $this->settings->apiPurchaseUrl;
240
                break;
241
        }
242
243
        return $url;
244
    }
245
246
    /**
247
     * Retrieve Payment url
248
     *
249
     * @return string
250
     */
251
    protected function getPaymentUrl() : string
252
    {
253
        $mode = $this->getMode();
254
255
        switch ($mode) {
256
            case 'paymentbyidentity':
257
                $url = $this->settings->apiPaymentByIdentityUrl;
258
                break;
259
            default: // default: normal
260
                $url = $this->settings->apiPaymentUrl;
261
                break;
262
        }
263
264
        return $url;
265
    }
266
}
267