Passed
Push — master ( 437f23...0ad4c0 )
by mahdi
03:18
created

Sadad::verify()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 43
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 22
c 1
b 0
f 0
dl 0
loc 43
rs 9.568
cc 3
nc 3
nop 0
1
<?php
2
3
namespace Shetabit\Payment\Drivers\Sadad;
4
5
use GuzzleHttp\Client;
6
use Shetabit\Payment\Abstracts\Driver;
7
use Shetabit\Payment\Exceptions\{InvalidPaymentException, PurchaseFailedException};
8
use Shetabit\Payment\{Contracts\ReceiptInterface, Invoice, Receipt};
9
10
class Sadad extends Driver
11
{
12
    /**
13
     * Sadad Client.
14
     *
15
     * @var object
16
     */
17
    protected $client;
18
19
    /**
20
     * Invoice
21
     *
22
     * @var Invoice
23
     */
24
    protected $invoice;
25
26
    /**
27
     * Driver settings
28
     *
29
     * @var object
30
     */
31
    protected $settings;
32
33
    /**
34
     * Sadad constructor.
35
     * Construct the class with the relevant settings.
36
     *
37
     * @param Invoice $invoice
38
     * @param $settings
39
     */
40
    public function __construct(Invoice $invoice, $settings)
41
    {
42
        $this->invoice($invoice);
43
        $this->settings = (object)$settings;
44
        $this->client = new Client();
45
    }
46
47
    /**
48
     * Purchase Invoice.
49
     *
50
     * @return string
51
     *
52
     * @throws PurchaseFailedException
53
     * @throws \GuzzleHttp\Exception\GuzzleException
54
     */
55
    public function purchase()
56
    {
57
        $terminalId = $this->settings->terminalId;
58
        $orderId = crc32($this->invoice->getUuid());
59
        $amount = $this->invoice->getAmount() * 10; // convert to rial
60
        $key = $this->settings->key;
61
62
        $signData = $this->encrypt_pkcs7("$terminalId;$orderId;$amount", $key);
63
64
        $data = array(
65
            'MerchantId' => $this->settings->merchantId,
66
            'ReturnUrl' => $this->settings->callbackUrl,
67
            'LocalDateTime' => date("m/d/Y g:i:s a"),
68
            'SignData' => $signData,
69
            'TerminalId' => $terminalId,
70
            'Amount' => $amount,
71
            'OrderId' => $orderId,
72
        );
73
74
        $response = $this
75
            ->client
76
            ->request(
77
                'POST',
78
                $this->settings->apiPurchaseUrl,
79
                [
80
                    "json" => $data,
81
                    "headers" => [
82
                        'Content-Type' => 'application/json',
83
                    ],
84
                    "http_errors" => false,
85
                ]
86
            );
87
88
        $body = json_decode($response->getBody()->getContents(), true);
89
90
        if ($body->ResCode!=0) {
91
            throw new PurchaseFailedException($body->Description);
92
        }
93
94
        $this->invoice->transactionId($body->Token);
95
96
        // return the transaction's id
97
        return $this->invoice->getTransactionId();
98
    }
99
100
    /**
101
     * Pay the Invoice
102
     *
103
     * @return \Illuminate\Http\RedirectResponse|mixed
104
     */
105
    public function pay()
106
    {
107
        $token = $this->invoice->getTransactionId();
108
        $payUrl = $this->settings->apiPaymentUrl.'?Token='.$token;
109
110
        // redirect using laravel logic
111
        return redirect()->to($payUrl);
112
    }
113
114
    /**
115
     * Verify payment
116
     *
117
     * @return ReceiptInterface
118
     *
119
     * @throws InvalidPaymentException
120
     * @throws \GuzzleHttp\Exception\GuzzleException
121
     */
122
    public function verify() : ReceiptInterface
123
    {
124
        $key = $this->settings->key;
125
        $token = $this->invoice->getTransactionId() ?? request()->get('token');
126
        $resCode = request()->get('ResCode');
127
        $message = 'تراکنش نا موفق بود در صورت کسر مبلغ از حساب شما حداکثر پس از 72 ساعت مبلغ به حسابتان برمیگردد.';
128
129
        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...
130
            throw new InvalidPaymentException($message);
131
        }
132
133
        $data = array(
134
            'Token' => $token,
135
            'SignData' => $this->encrypt_pkcs7($token, $key)
136
        );
137
138
        $response = $this
139
            ->client
140
            ->request(
141
                'POST',
142
                $this->settings->apiPurchaseUrl,
143
                [
144
                    "json" => $data,
145
                    "headers" => [
146
                        'Content-Type' => 'application/json',
147
                    ],
148
                    "http_errors" => false,
149
                ]
150
            );
151
152
        $body = json_decode($response->getBody()->getContents(), true);
153
154
        if ($body->ResCode == -1) {
155
            throw new InvalidPaymentException($message);
156
        }
157
158
        /**
159
         * شماره سفارش : $orderId = request()->get('OrderId')
160
         * شماره پیگیری : $body->SystemTraceNo
161
         * شماره مرجع : $body->RetrievalRefNo
162
         */
163
164
        return $this->createReceipt($body->SystemTraceNo);
165
    }
166
167
    /**
168
     * Generate the payment's receipt
169
     *
170
     * @param $referenceId
171
     *
172
     * @return Receipt
173
     */
174
    public function createReceipt($referenceId)
175
    {
176
        $receipt = new Receipt('sadad', $referenceId);
177
178
        return $receipt;
179
    }
180
181
    /**
182
     * Create sign data(Tripledes(ECB,PKCS7))
183
     *
184
     * @param $str
185
     * @param $key
186
     *
187
     * @return string
188
     */
189
    public function encrypt_pkcs7($str, $key)
190
    {
191
        $key = base64_decode($key);
192
        $ciphertext = OpenSSL_encrypt($str,"DES-EDE3", $key, OPENSSL_RAW_DATA);
193
194
        return base64_encode($ciphertext);
195
    }
196
}
197