Passed
Pull Request — master (#95)
by
unknown
03:32
created

Walleta::createReceipt()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 2
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 5
rs 10
1
<?php
2
3
namespace Shetabit\Multipay\Drivers\Walleta;
4
5
use GuzzleHttp\Client;
6
use Shetabit\Multipay\Abstracts\Driver;
7
use Shetabit\Multipay\Exceptions\PurchaseFailedException;
8
use Shetabit\Multipay\Contracts\ReceiptInterface;
9
use Shetabit\Multipay\Invoice;
10
use Shetabit\Multipay\Receipt;
11
use Shetabit\Multipay\RedirectionForm;
12
13
class Walleta extends Driver
14
{
15
    /**
16
     * Invoice
17
     *
18
     * @var Invoice
19
     */
20
    protected $invoice;
21
22
    /**
23
     * Response
24
     *
25
     * @var object
26
     */
27
    protected $response;
28
29
    /**
30
     * Driver settings
31
     *
32
     * @var object
33
     */
34
    protected $settings;
35
36
    /**
37
     * Walleta constructor.
38
     * Construct the class with the relevant settings.
39
     *
40
     * @param Invoice $invoice
41
     * @param $settings
42
     */
43
    public function __construct(Invoice $invoice, $settings)
44
    {
45
        $this->invoice($invoice);
46
        $this->settings = (object)$settings;
47
    }
48
49
    /**
50
     * Purchase Invoice.09214125578
51
     *
52
     * @return string
53
     *
54
     * @throws PurchaseFailedException
55
     */
56
    public function purchase()
57
    {
58
59
        $result = $this->token();
60
61
        if (!isset($result['status_code']) or $result['status_code'] != 200) {
62
            $this->purchaseFailed($result['content']['type']);
63
        }
64
65
        $this->invoice->transactionId($result['content']['token']);
66
67
        // return the transaction's id
68
        return $this->invoice->getTransactionId();
69
    }
70
71
    /**
72
     * Pay the Invoice
73
     *
74
     * @return RedirectionForm
75
     */
76
    public function pay(): RedirectionForm
77
    {
78
        return $this->redirectWithForm($this->settings->apiPaymentUrl . $this->invoice->getTransactionId(), [], 'GET');
79
    }
80
81
    /**
82
     * Verify payment
83
     *
84
     * @return mixed|Receipt
85
     *
86
     * @throws PurchaseFailedException
87
     */
88
    public function verify(): ReceiptInterface
89
    {
90
        $result = $this->verifyTransaction();
91
92
        if (!isset($result['status_code']) or $result['status_code'] != 200) {
93
            $this->purchaseFailed($result['status_code']['type']);
94
        }
95
96
        $receipt = $this->createReceipt($this->invoice->getUuid());
97
98
        return $receipt;
99
    }
100
101
    /**
102
     * send request to Walleta
103
     *
104
     * @param $method
105
     * @param $url
106
     * @param array $data
107
     * @return array
108
     */
109
    protected function callApi($method, $url, $data = []): array
110
    {
111
        $client = new Client();
112
113
        $response = $client->request($method, $url, [
114
            "json" => $data,
115
            "headers" => [
116
                'Content-Type' => 'application/json',
117
            ],
118
            "http_errors" => false,
119
        ]);
120
121
        return [
122
            'status_code' => $response->getStatusCode(),
123
            'content' => json_decode($response->getBody()->getContents(), true)
124
        ];
125
    }
126
127
    /**
128
     * Generate the payment's receipt
129
     *
130
     * @param $referenceId
131
     *
132
     * @return Receipt
133
     */
134
    protected function createReceipt($referenceId): Receipt
135
    {
136
        $receipt = new Receipt('walleta', $referenceId);
137
138
        return $receipt;
139
    }
140
141
    /**
142
     * call create token request
143
     *
144
     * @return array
145
     */
146
    public function token(): array
147
    {
148
        return $this->callApi('POST', $this->settings->apiPurchaseUrl, [
149
            'merchant_code' => $this->settings->merchantId,
150
            'invoice_reference' => $this->invoice->getUuid(),
151
            'invoice_date' => date('Y-m-d H:i:s'),
152
            'invoice_amount' => $this->invoice->getAmount(),
153
            'payer_first_name' => $this->invoice->getDetails()['first_name'],
154
            'payer_last_name' => $this->invoice->getDetails()['last_name'],
155
            'payer_national_code' => $this->invoice->getDetails()['national_code'],
156
            'payer_mobile' => $this->invoice->getDetails()['mobile'],
157
            'callback_url' => $this->settings->callbackUrl,
158
            'items' => $this->getItems(),
159
        ]);
160
    }
161
162
    /**
163
     * call verift transaction request
164
     *
165
     * @return array
166
     */
167
    public function verifyTransaction(): array
168
    {
169
        return $this->callApi('POST', $this->settings->apiVerificationUrl, [
170
            'merchant_code' => $this->settings->merchantId,
171
            'token' => $this->invoice->getTransactionId(),
172
            'invoice_reference' => $this->invoice->getUuid(),
173
            'invoice_amount' => $this->invoice->getAmount(),
174
        ]);
175
    }
176
177
    /**
178
     * get Items for
179
     *
180
     *
181
     */
182
    private function getItems()
183
    {
184
        /**
185
         * example data
186
         *
187
         *   $items = [
188
         *       [
189
         *           "reference" => "string",
190
         *           "name" => "string",
191
         *           "quantity" => 0,
192
         *           "unit_price" => 0,
193
         *           "unit_discount" => 0,
194
         *           "unit_tax_amount" => 0,
195
         *           "total_amount" => 0
196
         *       ]
197
         *   ];
198
         */
199
        return $this->invoice->getDetails()['items'];
200
    }
201
202
203
    /**
204
     * Trigger an exception
205
     *
206
     * @param $status
207
     *
208
     * @throws PurchaseFailedException
209
     */
210
    protected function purchaseFailed($status)
211
    {
212
        $translations = [
213
            "server_error" => "یک خطای داخلی رخ داده است.",
214
            "ip_address_error" => "آدرس IP پذیرنده صحیح نیست.",
215
            "validation_error" => "اطلاعات ارسال شده صحیح نیست.",
216
            "merchant_error" => "کد پذیرنده معتبر نیست.",
217
            "payment_token_error" => "شناسه پرداخت معتبر نیست.",
218
            "invoice_amount_error" => "مبلغ تراکنش با مبلغ پرداخت شده مطابقت ندارد.",
219
        ];
220
221
        if (array_key_exists($status, $translations)) {
222
            throw new PurchaseFailedException($translations[$status]);
223
        } else {
224
            throw new PurchaseFailedException('خطای ناشناخته ای رخ داده است.');
225
        }
226
    }
227
}
228