Payfa   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 148
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 48
c 1
b 0
f 0
dl 0
loc 148
rs 10
wmc 12

7 Methods

Rating   Name   Duplication   Size   Complexity  
A extractDetails() 0 3 2
A pay() 0 5 1
A createReceipt() 0 3 1
A __construct() 0 5 1
A verify() 0 23 2
A purchase() 0 36 3
A notVerified() 0 6 2
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Payfa;
4
5
use GuzzleHttp\Client;
6
use Shetabit\Multipay\Abstracts\Driver;
7
use Shetabit\Multipay\Contracts\ReceiptInterface;
8
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
9
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
10
use Shetabit\Multipay\Invoice;
11
use Shetabit\Multipay\Receipt;
12
use Shetabit\Multipay\RedirectionForm;
13
use Shetabit\Multipay\Request;
14
15
class Payfa extends Driver
16
{
17
    /**
18
     * Payfa 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
     * Payfa 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); // Set the invoice.
48
        $this->settings = (object)$settings; // Set settings.
49
        $this->client = new Client();
50
    }
51
52
    /**
53
     * Retrieve data from details using its name.
54
     *
55
     * @return string
56
     */
57
    private function extractDetails($name)
58
    {
59
        return empty($this->invoice->getDetails()[$name]) ? null : $this->invoice->getDetails()[$name];
60
    }
61
62
    public function purchase()
63
    {
64
        $mobile = $this->extractDetails('mobile');
65
        $cardNumber = $this->extractDetails('cardNumber');
66
67
        $data = array(
68
            'amount' => $this->invoice->getAmount() * ($this->settings->currency == 'T' ? 10 : 1), // convert to rial
69
            'callbackUrl' => $this->settings->callbackUrl,
70
            'mobileNumber' => $mobile,
71
            'invoiceId' => $this->invoice->getUuid(),
72
            'cardNumber' => $cardNumber
73
        );
74
75
        $response = $this->client->request(
76
            'POST',
77
            $this->settings->apiPurchaseUrl,
78
            [
79
                "json" => $data,
80
                "http_errors" => false,
81
                "headers" => [
82
                    "X-API-Key" => $this->settings->apiKey,
83
                    'Content-Type' => 'application/json',
84
                ]
85
            ]
86
        );
87
        $body = json_decode($response->getBody()->getContents(), true);
88
89
90
        if ($response->getStatusCode() != 200) {
91
            throw new PurchaseFailedException($body["title"]);
92
        }
93
94
        $this->invoice->transactionId($body['paymentId']);
95
96
        // return the transaction's id
97
        return $this->invoice->getTransactionId();
98
    }
99
100
    /**
101
     * Pay the Invoice
102
     *
103
     * @return RedirectionForm
104
     */
105
    public function pay(): RedirectionForm
106
    {
107
        $payUrl = $this->settings->apiPaymentUrl . $this->invoice->getTransactionId();
108
109
        return $this->redirectWithForm($payUrl, [], 'GET');
110
    }
111
112
113
    /**
114
     * Verify payment
115
     *
116
     * @return ReceiptInterface
117
     *
118
     * @throws InvalidPaymentException
119
     * @throws \GuzzleHttp\Exception\GuzzleException
120
     */
121
    public function verify(): ReceiptInterface
122
    {
123
        $paymentId = $this->invoice->getTransactionId() ?? Request::input('paymentId');
124
125
126
        $response = $this->client->request(
127
            'POST',
128
            $this->settings->apiVerificationUrl . $paymentId,
129
            [
130
                "http_errors" => false,
131
                "headers" => [
132
                    "X-API-Key" => $this->settings->apiKey,
133
                    'Content-Type' => 'application/json',
134
                ]
135
            ]
136
        );
137
        $body = json_decode($response->getBody()->getContents(), true);
138
139
        if ($response->getStatusCode() != 200) {
140
            $this->notVerified($body["message"], $response->getStatusCode());
141
        }
142
143
        return $this->createReceipt($body['transactionId']);
144
    }
145
146
    protected function createReceipt($referenceId)
147
    {
148
        return new Receipt('payfa', $referenceId);
149
    }
150
151
    /**
152
     * Trigger an exception
153
     *
154
     * @param $message
155
     * @throws InvalidPaymentException
156
     */
157
    private function notVerified($message, $status)
158
    {
159
        if (empty($message)) {
160
            throw new InvalidPaymentException('خطای ناشناخته ای رخ داده است.', (int)$status);
161
        } else {
162
            throw new InvalidPaymentException($message, (int)$status);
163
        }
164
    }
165
}
166