Paystar::pay()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 8
rs 10
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Paystar;
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 Paystar extends Driver
16
{
17
    /**
18
     * Paystar 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
     * payment token
40
     *
41
     * @var $token
0 ignored issues
show
Documentation Bug introduced by
The doc comment $token at position 0 could not be parsed: Unknown type name '$token' at position 0 in $token.
Loading history...
42
     */
43
    protected $token;
44
45
    /**
46
     * Paystar constructor.
47
     * Construct the class with the relevant settings.
48
     *
49
     * @param Invoice $invoice
50
     * @param $settings
51
     */
52
    public function __construct(Invoice $invoice, $settings)
53
    {
54
        $this->invoice($invoice);
55
        $this->settings = (object) $settings;
56
        $this->client = new Client();
57
    }
58
59
    /**
60
     * Purchase Invoice.
61
     *
62
     * @return string
63
     *
64
     * @throws PurchaseFailedException
65
     * @throws \GuzzleHttp\Exception\GuzzleException
66
     */
67
    public function purchase()
68
    {
69
        $details = $this->invoice->getDetails();
70
        $order_id = $this->invoice->getUuid();
71
        $amount = $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1); // convert to rial
72
        $callback = $this->settings->callbackUrl;
73
74
        $data = [
75
            'amount' => $amount,
76
            'order_id' => $order_id,
77
            'mail' => $details['email'] ?? null,
78
            'phone' => $details['mobile'] ?? $details['phone'] ?? null,
79
            'description' => $details['description'] ?? $this->settings->description,
80
            'callback' => $callback,
81
            'sign' =>
82
                hash_hmac(
83
                    'SHA512',
84
                    $amount . '#' . $order_id . '#' . $callback,
85
                    $this->settings->signKey
86
                ),
87
        ];
88
89
        $response = $this
90
            ->client
91
            ->request(
92
                'POST',
93
                $this->settings->apiPurchaseUrl,
94
                [
95
                    'headers' => [
96
                        'Content-Type' => 'application/json',
97
                        'Accept' => 'application/json',
98
                        'Authorization' => 'Bearer ' . $this->settings->gatewayId,
99
                    ],
100
                    'body' => json_encode($data),
101
                ]
102
            );
103
104
        $body = json_decode($response->getBody()->getContents());
105
106
        if ($body->status !== 1) {
107
            // some error has happened
108
            throw new PurchaseFailedException($this->translateStatus($body->status));
109
        }
110
111
        $this->invoice->transactionId($body->data->ref_num);
112
        $this->token = $body->data->token;
113
114
        // return the transaction's id
115
        return $this->invoice->getTransactionId();
116
    }
117
118
    /**
119
     * Pay the Invoice
120
     *
121
     * @return RedirectionForm
122
     */
123
    public function pay() : RedirectionForm
124
    {
125
        return $this->redirectWithForm(
126
            $this->settings->apiPaymentUrl,
127
            [
128
                'token' => $this->token,
129
            ],
130
            'POST'
131
        );
132
    }
133
134
    /**
135
     * Verify payment
136
     *
137
     * @return mixed|void
138
     *
139
     * @throws InvalidPaymentException
140
     * @throws \GuzzleHttp\Exception\GuzzleException
141
     */
142
    public function verify() : ReceiptInterface
143
    {
144
        $amount = $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1); // convert to rial
145
        $refNum = Request::post('ref_num');
146
        $cardNumber = Request::post('card_number');
147
        $trackingCode = Request::post('tracking_code');
148
149
        if (!$trackingCode) {
150
            throw new InvalidPaymentException($this->translateStatus(-1), -1);
151
        }
152
153
        $data = [
154
            'amount' => $amount,
155
            'ref_num' => $refNum,
156
            'tracking_code' => $trackingCode,
157
            'sign' =>
158
                hash_hmac(
159
                    'SHA512',
160
                    $amount . '#' . $refNum . '#' . $cardNumber . '#' . $trackingCode,
161
                    $this->settings->signKey
162
                ),
163
        ];
164
165
        $response = $this->client->request(
166
            'POST',
167
            $this->settings->apiVerificationUrl,
168
            [
169
                'headers' => [
170
                    'Content-Type' => 'application/json',
171
                    'Accept' => 'application/json',
172
                    'Authorization' => 'Bearer ' . $this->settings->gatewayId,
173
                ],
174
                'body' => json_encode($data),
175
            ]
176
        );
177
178
        $body = json_decode($response->getBody()->getContents());
179
180
        if ($body->status !== 1) {
181
            throw new InvalidPaymentException($this->translateStatus($body->status), (int)$body->status);
182
        }
183
184
        return $this->createReceipt($refNum);
185
    }
186
187
    /**
188
     * Generate the payment's receipt
189
     *
190
     * @param $referenceId
191
     *
192
     * @return Receipt
193
     */
194
    protected function createReceipt($referenceId)
195
    {
196
        $receipt = new Receipt('paystar', $referenceId);
197
198
        return $receipt;
199
    }
200
201
    /**
202
     * Trigger an exception
203
     *
204
     * @param $status
205
     *
206
     * @return mixed|string
207
     */
208
    private function translateStatus($status)
209
    {
210
        $status = (string) $status;
211
212
        $translations = [
213
            '1' => 'موفق',
214
            '-1' => 'درخواست نامعتبر (خطا در پارامترهای ورودی)',
215
            '-2' => 'درگاه فعال نیست',
216
            '-3' => 'توکن تکراری است',
217
            '-4' => 'مبلغ بیشتر از سقف مجاز درگاه است',
218
            '-5' => 'شناسه ref_num معتبر نیست',
219
            '-6' => 'تراکنش قبلا وریفای شده است',
220
            '-7' => 'پارامترهای ارسال شده نامعتبر است',
221
            '-8' => 'تراکنش را نمیتوان وریفای کرد',
222
            '-9' => 'تراکنش وریفای نشد',
223
            '-98' => 'تراکنش ناموفق',
224
            '-99' => 'خطای سامانه'
225
        ];
226
227
        $unknownError = 'خطای ناشناخته رخ داده است.';
228
229
        return array_key_exists($status, $translations) ? $translations[$status] : $unknownError;
230
    }
231
}
232