Pna   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 62
c 1
b 0
f 0
dl 0
loc 137
rs 10
wmc 14

4 Methods

Rating   Name   Duplication   Size   Complexity  
B purchase() 0 39 7
A __construct() 0 5 1
A pay() 0 8 1
A verify() 0 32 5
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Pna;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Exception\GuzzleException;
7
use Shetabit\Multipay\Abstracts\Driver;
8
use Shetabit\Multipay\Contracts\ReceiptInterface;
9
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
10
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
11
use Shetabit\Multipay\Invoice;
12
use Shetabit\Multipay\Receipt;
13
use Shetabit\Multipay\RedirectionForm;
14
use Shetabit\Multipay\Request;
15
16
class Pna extends Driver
17
{
18
    /**
19
     * Pna Client.
20
     *
21
     * @var object
22
     */
23
    protected $client;
24
25
    /**
26
     * Invoice
27
     *
28
     * @var Invoice
29
     */
30
    protected $invoice;
31
32
    /**
33
     * Driver settings
34
     *
35
     * @var object
36
     */
37
    protected $settings;
38
39
    /**
40
     * payment token
41
     *
42
     * @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...
43
     */
44
    protected $token;
45
46
    public function __construct(Invoice $invoice, $settings)
47
    {
48
        $this->invoice($invoice);
49
        $this->settings = (object)$settings;
50
        $this->client = new Client();
51
    }
52
53
    /**
54
     *
55
     * @return string
56
     *
57
     * @throws PurchaseFailedException
58
     * @throws GuzzleException
59
     */
60
    public function purchase()
61
    {
62
        $amount = $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1); // convert to rial
63
        if (!empty($this->invoice->getDetails()['description'])) {
64
            $description = $this->invoice->getDetails()['description'];
65
        } else {
66
            $description = $this->settings->description;
67
        }
68
        $data = [
69
            "CorporationPin" => $this->settings->CorporationPin,
70
            "Amount" => $amount,
71
            "OrderId" => intval(1, time()) . crc32($this->invoice->getUuid()),
72
            "CallBackUrl" => $this->settings->callbackUrl,
73
            "AdditionalData" => $description,
74
        ];
75
        if (!empty($this->invoice->getDetails()['mobile'])) {
76
            $data['Originator'] = $this->invoice->getDetails()['mobile'];
77
        }
78
        $response = $this->client->request(
79
            'POST',
80
            $this->settings->apiNormalSale,
81
            [
82
                'json' => $data,
83
                'headers' => [
84
                    'Content-Type' => 'application/json',
85
                ],
86
                'http_errors' => false,
87
            ]
88
        );
89
        $result = json_decode($response->getBody()->getContents(), true);
90
        if (isset($result['errors'])) {
91
            throw new PurchaseFailedException($result['title'] ?? 'اطلاعات وارد شده اشتباه می باشد.', $result['status'] ?? 400);
92
        }
93
        if (!isset($result['status']) || (string)$result['status'] !== '0') {
94
            throw new PurchaseFailedException($result['message'] ?? "خطای ناشناخته رخ داده است. در صورت کسر مبلغ از حساب حداکثر پس از 72 ساعت به حسابتان برمیگردد", $result['status'] ?? 400);
95
        }
96
        $this->invoice->transactionId($result['token']);
97
98
        return $this->invoice->getTransactionId();
99
    }
100
101
    /**
102
     * Pay the Invoice
103
     *
104
     * @return RedirectionForm
105
     */
106
    public function pay(): RedirectionForm
107
    {
108
        $transactionId = $this->invoice->getTransactionId();
109
        $paymentUrl = $this->settings->apiPaymentUrl;
110
111
        $payUrl = $paymentUrl . $transactionId;
112
113
        return $this->redirectWithForm($payUrl, [], 'GET');
114
    }
115
116
    /**
117
     * Verify payment
118
     *
119
     * @throws InvalidPaymentException|GuzzleException
120
     */
121
    public function verify(): ReceiptInterface
122
    {
123
        $transactionId = $this->invoice->getTransactionId() ?? Request::input('Token') ?? Request::input('token');
124
        $data = [
125
            "CorporationPin" => $this->settings->CorporationPin,
126
            "Token" => $transactionId
127
        ];
128
        $response = $this->client->request(
129
            'POST',
130
            $this->settings->apiConfirmationUrl,
131
            [
132
                'json' => $data,
133
                "headers" => [
134
                    'Content-Type' => 'application/json',
135
                ],
136
                'http_errors' => false,
137
            ]
138
        );
139
        $result = json_decode($response->getBody()->getContents(), true);
140
        if (!isset($result['status'])
141
            || ((string)$result['status'] !== '0'
142
                && (string)$result['status'] !== '2')
143
            || (string)$result['rrn'] === '0') {
144
            throw new InvalidPaymentException("خطای ناشناخته رخ داده است. در صورت کسر مبلغ از حساب حداکثر پس از 72 ساعت به حسابتان برمیگردد", $result['status'] ?? 400);
145
        }
146
        $refId = $result['rrn'];
147
        $receipt = new Receipt('pna', $refId);
148
        $receipt->detail([
149
            'cardNumberMasked' => $result['cardNumberMasked'],
150
            'token' => $result['token'],
151
        ]);
152
        return $receipt;
153
    }
154
}
155