Passed
Pull Request — master (#228)
by
unknown
02:48
created

Digipay::getPaymentUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
4
namespace Shetabit\Multipay\Drivers\Digipay;
5
6
use GuzzleHttp\Client;
7
use GuzzleHttp\Exception\GuzzleException;
8
use GuzzleHttp\RequestOptions;
9
use Shetabit\Multipay\Abstracts\Driver;
10
use Shetabit\Multipay\Contracts\ReceiptInterface;
11
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
12
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
13
use Shetabit\Multipay\Invoice;
14
use Shetabit\Multipay\Receipt;
15
use Shetabit\Multipay\RedirectionForm;
16
use Shetabit\Multipay\Request;
17
18
class Digipay extends Driver
19
{
20
    /**
21
     * Digipay Client.
22
     *
23
     * @var Client
24
     */
25
    protected $client;
26
27
    /**
28
     * Invoice
29
     *
30
     * @var Invoice
31
     */
32
    protected $invoice;
33
34
    /**
35
     * Driver settings
36
     *
37
     * @var object
38
     */
39
    protected $settings;
40
    /**
41
     * Digipay Oauth Token
42
     *
43
     * @var string
44
     */
45
    protected $oauthToken;
46
47
    /**
48
     * Digipay payment url
49
     *
50
     * @var string
51
     */
52
    protected $paymentUrl;
53
54
    /**
55
     * Digipay constructor.
56
     * Construct the class with the relevant settings.
57
     *
58
     * @param Invoice $invoice
59
     * @param $settings
60
     */
61
    public function __construct(Invoice $invoice, $settings)
62
    {
63
        $this->invoice($invoice);
64
        $this->settings= (object) $settings;
65
        $this->client = new Client();
66
        $this->oauthToken = $this->oauth();
67
    }
68
69
    /**
70
     * @throws PurchaseFailedException
71
     */
72
    public function purchase(): string
73
    {
74
        $phone = $this->invoice->getDetail('phone')
75
            ?? $this->invoice->getDetail('cellphone')
76
            ?? $this->invoice->getDetail('mobile');
77
78
        /**
79
         * @see https://docs.mydigipay.com/upg.html#_request_fields_2
80
         */
81
        $data = [
82
            'amount'      => $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1),
83
            'cellNumber'  => $phone,
84
            'providerId'  => $this->invoice->getUuid(),
85
            'callbackUrl' => $this->settings->callbackUrl,
86
        ];
87
88
        if (!is_null($basketDetailsDto = $this->invoice->getDetail('basketDetailsDto'))) {
89
            $data['basketDetailsDto'] = $basketDetailsDto;
90
        }
91
92
        if (!is_null($preferredGateway = $this->invoice->getDetail('preferredGateway'))) {
93
            $data['preferredGateway'] = $preferredGateway;
94
        }
95
96
        if (!is_null($splitDetailsList = $this->invoice->getDetail('splitDetailsList'))) {
97
            $data['splitDetailsList'] = $splitDetailsList;
98
        }
99
100
        /**
101
         * @see https://docs.mydigipay.com/upg.html#_query_parameters_2
102
         */
103
        $digipayType = $this->invoice->getDetail('digipayType') ?? 11;
104
105
        $response = $this
106
            ->client
107
            ->request(
108
                'POST',
109
                $this->settings->apiPurchaseUrl,
110
                [
111
                    RequestOptions::BODY  => json_encode($data),
112
                    RequestOptions::QUERY  => ['type' => $digipayType],
113
                    RequestOptions::HEADERS   => [
114
                        'Agent' => $this->invoice->getDetail('agent') ?? 'WEB',
115
                        'Content-Type'  => 'application/json',
116
                        'Authorization' => 'Bearer ' . $this->oauthToken,
117
                        'Digipay-Version' => '2022-02-02',
118
                    ],
119
                    RequestOptions::HTTP_ERRORS => false,
120
                ]
121
            );
122
123
        if ($response->getStatusCode() != 200) {
124
            // error has happened
125
            $message = $body['result']['message'] ?? 'خطا در هنگام درخواست برای پرداخت رخ داده است.';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $body seems to never exist and therefore isset should always be false.
Loading history...
126
            throw new PurchaseFailedException($message);
127
        }
128
129
        $body = json_decode($response->getBody()->getContents(), true);
130
        $this->invoice->transactionId($body['ticket']);
131
        $this->setPaymentUrl($body['redirectUrl']);
132
133
        // return the transaction's id
134
        return $this->invoice->getTransactionId();
135
    }
136
137
    public function pay(): RedirectionForm
138
    {
139
        return $this->redirectWithForm($this->getPaymentUrl(), [], 'GET');
140
    }
141
142
    /**
143
     * @throws InvalidPaymentException
144
     */
145
    public function verify(): ReceiptInterface
146
    {
147
        /**
148
         * @see https://docs.mydigipay.com/upg.html#ticket_type
149
         */
150
        $digipayTicketType = Request::input('type');
151
        $tracingId = Request::input('trackingCode');
152
153
        $response = $this->client->request(
154
            'POST',
155
            $this->settings->apiVerificationUrl . $tracingId,
156
            [
157
                RequestOptions::QUERY      => ['type' => $digipayTicketType],
158
                RequestOptions::HEADERS    => [
159
                    "Accept"        => "application/json",
160
                    "Authorization" => "Bearer " . $this->oauthToken,
161
                ],
162
                RequestOptions::HTTP_ERRORS => false,
163
            ]
164
        );
165
166
        if ($response->getStatusCode() != 200) {
167
            $message = 'تراکنش تایید نشد';
168
169
            throw new InvalidPaymentException($message, (int) $response->getStatusCode());
170
        }
171
172
        $body = json_decode($response->getBody()->getContents(), true);
173
174
        return (new Receipt('digipay', $body["trackingCode"]))->detail($body);
175
    }
176
177
    /**
178
     * @throws PurchaseFailedException
179
     */
180
    protected function oauth()
181
    {
182
        $response = $this
183
            ->client
184
            ->request(
185
                'POST',
186
                $this->settings->apiOauthUrl,
187
                [
188
                    RequestOptions::HEADERS   => [
189
                        'Authorization' => 'Basic ' . base64_encode("{$this->settings->client_id}:{$this->settings->client_secret}"),
190
                    ],
191
                    RequestOptions::MULTIPART   => [
192
                        [
193
                            "name"     => "username",
194
                            "contents" => $this->settings->username,
195
                        ],
196
                        [
197
                            "name"     => "password",
198
                            "contents" => $this->settings->password,
199
                        ],
200
                        [
201
                            "name"     => "grant_type",
202
                            "contents" => 'password',
203
                        ],
204
                    ],
205
                    RequestOptions::HTTP_ERRORS => false,
206
                ]
207
            );
208
209
        if ($response->getStatusCode() != 200) {
210
            if ($response->getStatusCode() == 401) {
211
                throw new PurchaseFailedException("خطا نام کاربری یا رمز عبور شما اشتباه می باشد.");
212
            } else {
213
                throw new PurchaseFailedException("خطا در هنگام احراز هویت.");
214
            }
215
        }
216
217
        $body = json_decode($response->getBody()->getContents(), true);
218
219
        $this->oauthToken = $body['access_token'];
220
        return $body['access_token'];
221
    }
222
223
    /**
224
     * @return string
225
     */
226
    public function getPaymentUrl(): string
227
    {
228
        return $this->paymentUrl;
229
    }
230
231
    /**
232
     * @param string $paymentUrl
233
     */
234
    public function setPaymentUrl(string $paymentUrl): void
235
    {
236
        $this->paymentUrl = $paymentUrl;
237
    }
238
}
239