Passed
Push — master ( 8fb633...075a6a )
by mahdi
06:46
created

Normal::purchase()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 52
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 7
eloc 29
c 1
b 0
f 1
nc 16
nop 0
dl 0
loc 52
rs 8.5226

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Zarinpal\Strategies;
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 Normal extends Driver
16
{
17
    /**
18
     * HTTP 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
     * Zarinpal 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);
48
        $this->settings = (object) $settings;
49
        $this->client = new Client();
50
    }
51
52
    /**
53
     * Purchase Invoice.
54
     *
55
     * @return string
56
     *
57
     * @throws PurchaseFailedException
58
     * @throws \SoapFault
59
     */
60
    public function purchase()
61
    {
62
        if (!empty($this->invoice->getDetails()['description'])) {
63
            $description = $this->invoice->getDetails()['description'];
64
        } else {
65
            $description = $this->settings->description;
66
        }
67
68
        if (!empty($this->invoice->getDetails()['mobile'])) {
69
            $mobile = $this->invoice->getDetails()['mobile'];
70
        }
71
72
        if (!empty($this->invoice->getDetails()['email'])) {
73
            $email = $this->invoice->getDetails()['email'];
74
        }
75
76
        $metadata = ['email' => $email, $mobile => $mobile];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $email does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $mobile does not seem to be defined for all execution paths leading up to this point.
Loading history...
77
78
        $data = [
79
            "merchant_id" => $this->settings->merchantId,
80
            "amount" => $this->invoice->getAmount(),
81
            "callback_url" => $this->settings->callbackUrl,
82
            "description" => $description,
83
            "metadata" => array_merge($this->invoice->getDetails() ?? [], $metadata),
84
        ];
85
86
87
        $response = $this
88
            ->client
89
            ->request(
90
                'POST',
91
                $this->settings->apiPurchaseUrl,
92
                [
93
                    "json" => $data,
94
                    "headers" => [
95
                        'Content-Type' => 'application/json',
96
                    ],
97
                    "http_errors" => false,
98
                ]
99
            );
100
101
        $result = json_decode($response->getBody()->getContents(), true);
102
103
        // some error has happened        
104
        if (! empty($result['errors']) || empty($result['data']) || $result['data']['code'] != 100) {            
105
            throw new PurchaseFailedException($result['errors']['message'], $result['errors']['code']);
106
        }
107
108
        $this->invoice->transactionId($result['data']["authority"]);
109
110
        // return the transaction's id
111
        return $this->invoice->getTransactionId();
112
    }
113
114
    /**
115
     * Pay the Invoice
116
     *
117
     * @return RedirectionForm
118
     */
119
    public function pay() : RedirectionForm
120
    {
121
        $transactionId = $this->invoice->getTransactionId();
122
        $paymentUrl = $this->getPaymentUrl();
123
124
        $payUrl = $paymentUrl.$transactionId;
125
126
        return $this->redirectWithForm($payUrl, [], 'GET');
127
    }
128
129
    /**
130
     * Verify payment
131
     *
132
     * @return ReceiptInterface
133
     *
134
     * @throws InvalidPaymentException
135
     */
136
    public function verify() : ReceiptInterface
137
    {
138
        $authority = $this->invoice->getTransactionId() ?? Request::input('Authority');
139
140
        $data = [
141
            "merchant_id" => $this->settings->merchantId,
142
            "authority" => $authority,
143
            "amount" => $this->invoice->getAmount(),
144
        ];
145
146
        $response = $this->client->request(
147
            'POST',
148
            $this->getVerificationUrl(),
149
            [
150
                'json' => $data,
151
                "headers" => [
152
                    'Content-Type' => 'application/json',
153
                ],
154
                "http_errors" => false,
155
            ]
156
        );
157
158
        $result = json_decode($response->getBody()->getContents(), true);
159
160
        if (empty($result['data']) || ! isset($result['data']['ref_id']) || $result['data']['code'] != 100) {
161
            $message = $result['errors']['message'];
162
            $code = $result['errors']['code'];
163
164
            throw new InvalidPaymentException($message, $code);
165
        }
166
167
        return $this->createReceipt($result['data']['ref_id']);
168
    }
169
170
    /**
171
     * Generate the payment's receipt
172
     *
173
     * @param $referenceId
174
     *
175
     * @return Receipt
176
     */
177
    public function createReceipt($referenceId)
178
    {
179
        return new Receipt('zarinpal', $referenceId);
180
    }
181
182
    /**
183
     * Retrieve purchase url
184
     *
185
     * @return string
186
     */
187
    protected function getPurchaseUrl() : string
188
    {
189
        return $this->settings->apiPurchaseUrl;
190
    }
191
192
    /**
193
     * Retrieve Payment url
194
     *
195
     * @return string
196
     */
197
    protected function getPaymentUrl() : string
198
    {
199
        return $this->settings->apiPaymentUrl;
200
    }
201
202
    /**
203
     * Retrieve verification url
204
     *
205
     * @return string
206
     */
207
    protected function getVerificationUrl() : string
208
    {
209
        return $this->settings->apiVerificationUrl;
210
    }
211
}
212