Passed
Push — master ( 437f23...0ad4c0 )
by mahdi
03:18
created

Payping::purchase()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 41
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 26
dl 0
loc 41
rs 9.504
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
namespace Shetabit\Payment\Drivers\Payping;
4
5
use GuzzleHttp\Client;
6
use Shetabit\Payment\Abstracts\Driver;
7
use Shetabit\Payment\Exceptions\{InvalidPaymentException, PurchaseFailedException};
8
use Shetabit\Payment\{Contracts\ReceiptInterface, Invoice, Receipt};
9
10
class Payping extends Driver
11
{
12
    /**
13
     * Payping Client.
14
     *
15
     * @var object
16
     */
17
    protected $client;
18
19
    /**
20
     * Invoice
21
     *
22
     * @var Invoice
23
     */
24
    protected $invoice;
25
26
    /**
27
     * Driver settings
28
     *
29
     * @var object
30
     */
31
    protected $settings;
32
33
    /**
34
     * Payping constructor.
35
     * Construct the class with the relevant settings.
36
     *
37
     * @param Invoice $invoice
38
     * @param $settings
39
     */
40
    public function __construct(Invoice $invoice, $settings)
41
    {
42
        $this->invoice($invoice);
43
        $this->settings = (object) $settings;
44
        $this->client = new Client();
45
    }
46
47
    /**
48
     * Retrieve data from details using its name.
49
     *
50
     * @return string
51
     */
52
    private function extractDetails($name)
53
    {
54
        return empty($this->invoice->getDetails()[$name]) ? null : $this->invoice->getDetails()[$name];
55
    }
56
57
    /**
58
     * Purchase Invoice.
59
     *
60
     * @return string
61
     *
62
     * @throws PurchaseFailedException
63
     * @throws \GuzzleHttp\Exception\GuzzleException
64
     */
65
    public function purchase()
66
    {
67
        $name = $this->extractDetails('name');
68
        $mobile = $this->extractDetails('mobile');
69
        $email = $this->extractDetails('email');
70
        $description = $this->extractDetails('description');
71
72
        $data = array(
73
            "payerName" => $name,
74
            "amount" => $this->invoice->getAmount(),
75
            "payerIdentity" => $mobile ?? $email,
76
            "returnUrl" => $this->settings->callbackUrl,
77
            "description" => $description,
78
            "clientRefId" => $this->invoice->getUuid(),
79
        );
80
81
        $response = $this
82
            ->client
83
            ->request(
84
                'POST',
85
                $this->settings->apiPurchaseUrl,
86
                [
87
                    "json" => $data,
88
                    "headers" => [
89
                        "Accept" => "application/json",
90
                        "Authorization" => "bearer ".$this->settings->merchantId,
91
                    ],
92
                    "http_errors" => false,
93
                ]
94
            );
95
        $body = json_decode($response->getBody()->getContents(), true);
96
97
        if (!empty($body['Error'])) {
98
            // some error has happened
99
            throw new PurchaseFailedException($body['Error']);
100
        }
101
102
        $this->invoice->transactionId($body['code']);
103
104
        // return the transaction's id
105
        return $this->invoice->getTransactionId();
106
    }
107
108
    /**
109
     * Pay the Invoice
110
     *
111
     * @return \Illuminate\Http\RedirectResponse|mixed
112
     */
113
    public function pay()
114
    {
115
        $payUrl = $this->settings->apiPaymentUrl.$this->invoice->getTransactionId();
116
117
        // redirect using laravel logic
118
        return redirect()->to($payUrl);
119
    }
120
121
    /**
122
     * Verify payment
123
     *
124
     * @return ReceiptInterface
125
     *
126
     * @throws InvalidPaymentException
127
     * @throws \GuzzleHttp\Exception\GuzzleException
128
     */
129
    public function verify() : ReceiptInterface
130
    {
131
        $data = [
132
            'amount' => $this->invoice->getAmount(),
133
            'refId'  => request()->input('refid'),
134
        ];
135
136
        $response = $this->client->request(
137
            'POST',
138
            $this->settings->apiVerificationUrl,
139
            [
140
                'json' => $data,
141
                "headers" => [
142
                    "Accept" => "application/json",
143
                    "Authorization" => "bearer ".$this->settings->merchantId,
144
                ],
145
                "http_errors" => false,
146
            ]
147
        );
148
149
        $responseBody = mb_strtolower($response->getBody()->getContents());
150
151
        $body = json_decode($responseBody, true);
152
153
        if (empty($body['amount']) || empty($body['refid']) || !empty($body['error'])) {
154
            $this->notVerified($body);
155
        }
156
157
        return $this->createReceipt($body['refid']);
158
    }
159
160
    /**
161
     * Generate the payment's receipt
162
     *
163
     * @param $referenceId
164
     *
165
     * @return Receipt
166
     */
167
    public function createReceipt($referenceId)
168
    {
169
        $receipt = new Receipt('payping', $referenceId);
170
171
        return $receipt;
172
    }
173
174
    /**
175
     * Trigger an exception
176
     *
177
     * @param $status
178
     * @throws InvalidPaymentException
179
     */
180
    private function notVerified($status)
181
    {
182
        $message = $status['amount'] ?? $status['refid'] ?? $status['error'];
183
184
        throw new InvalidPaymentException($message);
185
    }
186
}
187