Completed
Push — master ( 27ec34...22ee16 )
by PROSPER
10s
created

Paystack::getAuthorizationResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Laravel Paystack package.
5
 *
6
 * (c) Prosper Otemuyiwa <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Unicodeveloper\Paystack;
13
14
use GuzzleHttp\Client;
15
use Illuminate\Support\Facades\Config;
16
use Unicodeveloper\Paystack\Exceptions\IsNullException;
17
use Unicodeveloper\Paystack\Exceptions\PaymentVerificationFailedException;
18
19
class Paystack
20
{
21
    /**
22
     * Transaction Verification Successful
23
     */
24
    const VS = 'Verification successful';
25
26
    /**
27
     *  Invalid Transaction reference
28
     */
29
    const ITF = "Invalid transaction reference";
30
31
    /**
32
     * Issue Secret Key from your Paystack Dashboard
33
     * @var string
34
     */
35
    protected $secretKey;
36
37
    /**
38
     * Instance of Client
39
     * @var Client
40
     */
41
    protected $client;
42
43
    /**
44
     *  Response from requests made to Paystack
45
     * @var mixed
46
     */
47
    protected $response;
48
49
    /**
50
     * Paystack API base Url
51
     * @var string
52
     */
53
    protected $baseUrl;
54
55
    /**
56
     * Authorization Url - Paystack payment page
57
     * @var string
58
     */
59
    protected $authorizationUrl;
60
61
    public function __construct()
62
    {
63
        $this->setKey();
64
        $this->setBaseUrl();
65
        $this->setRequestOptions();
66
    }
67
68
    /**
69
     * Get Base Url from Paystack config file
70
     */
71
    public function setBaseUrl()
72
    {
73
        $this->baseUrl = Config::get('paystack.paymentUrl');
74
    }
75
76
    /**
77
     * Get secret key from Paystack config file
78
     */
79
    public function setKey()
80
    {
81
        $this->secretKey = Config::get('paystack.secretKey');
82
    }
83
84
    /**
85
     * Set options for making the Client request
86
     */
87
    private function setRequestOptions()
88
    {
89
        $authBearer = 'Bearer '. $this->secretKey;
90
91
        $this->client = new Client(
92
            [
93
                'base_uri' => $this->baseUrl,
94
                'headers' => [
95
                    'Authorization' => $authBearer,
96
                    'Content-Type'  => 'application/json',
97
                    'Accept'        => 'application/json'
98
                ]
99
            ]
100
        );
101
    }
102
103
    /**
104
     * Initiate a payment request to Paystack
105
     * Included the option to pass the payload to this method for situations 
106
     * when the payload is built on the fly (not passed to the controller from a view)
107
     * @return Paystack
108
     */
109
    public function makePaymentRequest( $data = null)
110
    {
111
        if ( $data == null ) {
112
            $data = [
113
                "amount" => intval(request()->amount),
114
                "reference" => request()->reference,
115
                "email" => request()->email,
116
                "plan" => request()->plan,
117
                "first_name" => request()->first_name,
118
                "last_name" => request()->last_name,
119
                "callback_url" => request()->callback_url,
120
                /*
121
                * to allow use of metadata on Paystack dashboard and a means to return additional data back to redirect url
122
                * form need an input field: <input type="hidden" name="metadata" value="{{ json_encode($array) }}" >
123
                *array must be set up as: $array = [ 'custom_fields' => [
124
                *                                                            ['display_name' => "Cart Id", "variable_name" => "cart_id", "value" => "2"],
125
                *                                                            ['display_name' => "Sex", "variable_name" => "sex", "value" => "female"],
126
                *                                                            .
127
                *                                                            .
128
                *                                                            .
129
                *                                                        ]
130
                *                                        
131
                *                                  ]
132
                */
133
                'metadata' => request()->metadata
134
            ];
135
136
            // Remove the fields which were not sent (value would be null)
137
            array_filter($data);
138
        }
139
140
        $this->setHttpResponse('/transaction/initialize', 'POST', $data);
141
142
        return $this;
143
    }
144
145
146
    /**
147
     * @param string $relativeUrl
148
     * @param string $method
149
     * @param array $body
150
     * @return Paystack
151
     * @throws IsNullException
152
     */
153
    private function setHttpResponse($relativeUrl, $method, $body = [])
154
    {
155
        if (is_null($method)) {
156
            throw new IsNullException("Empty method not allowed");
157
        }
158
159
        $this->response = $this->client->{strtolower($method)}(
160
            $this->baseUrl . $relativeUrl,
161
            ["body" => json_encode($body)]
162
        );
163
164
        return $this;
165
    }
166
167
    /**
168
     * Get the authorization url from the callback response
169
     * @return Paystack
170
     */
171
    public function getAuthorizationUrl()
172
    {
173
        $this->makePaymentRequest();
174
175
        $this->url = $this->getResponse()['data']['authorization_url'];
0 ignored issues
show
Bug introduced by
The property url does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
176
177
        return $this;
178
    }
179
    
180
     /**
181
     * Get the authorization callback response
182
     * In situations where Laravel serves as an backend for a detached UI, the api cannot redirect 
183
     * and might need to take different actions based on the success or not of the transaction
184
     * @return array
185
     */
186
    public function getAuthorizationResponse($data)
187
    {
188
        $this->makePaymentRequest($data);
189
190
        $this->url = $this->getResponse()['data']['authorization_url'];
191
192
        return $this->getResponse();
193
    }
194
195
    /**
196
     * Hit Paystack Gateway to Verify that the transaction is valid
197
     */
198
    private function verifyTransactionAtGateway()
199
    {
200
        $transactionRef = request()->query('trxref');
201
202
        $relativeUrl = "/transaction/verify/{$transactionRef}";
203
204
        $this->response = $this->client->get($this->baseUrl . $relativeUrl, []);
205
    }
206
207
    /**
208
     * True or false condition whether the transaction is verified
209
     * @return boolean
210
     */
211
    public function isTransactionVerificationValid()
212
    {
213
        $this->verifyTransactionAtGateway();
214
215
        $result = $this->getResponse()['message'];
216
217
        switch ($result) {
218
            case self::VS:
219
                $validate = true;
220
                break;
221
            case self::ITF:
222
                $validate = false;
223
                break;
224
            default:
225
                $validate = false;
226
                break;
227
        }
228
229
        return $validate;
230
    }
231
232
    /**
233
     * Get Payment details if the transaction was verified successfully
234
     * @return json
235
     * @throws PaymentVerificationFailedException
236
     */
237
    public function getPaymentData()
238
    {
239
        if ($this->isTransactionVerificationValid()) {
240
            return $this->getResponse();
241
        } else {
242
            throw new PaymentVerificationFailedException("Invalid Transaction Reference");
243
        }
244
    }
245
246
    /**
247
     * Fluent method to redirect to Paystack Payment Page
248
     */
249
    public function redirectNow()
250
    {
251
        return redirect($this->url);
252
    }
253
254
    /**
255
     * Get Access code from transaction callback respose
256
     * @return string
257
     */
258
    public function getAccessCode()
259
    {
260
        return $this->getResponse()['data']['access_code'];
261
    }
262
263
    /**
264
     * Generate a Unique Transaction Reference
265
     * @return string
266
     */
267
    public function genTranxRef()
268
    {
269
        return TransRef::getHashedToken();
270
    }
271
272
    /**
273
     * Get all the customers that have made transactions on your platform
274
     * @return array
275
     */
276
    public function getAllCustomers()
277
    {
278
        $this->setRequestOptions();
279
280
        return $this->setHttpResponse("/customer", 'GET', [])->getData();
281
    }
282
283
    /**
284
     * Get all the plans that you have on Paystack
285
     * @return array
286
     */
287
    public function getAllPlans()
288
    {
289
        $this->setRequestOptions();
290
291
        return $this->setHttpResponse("/plan", 'GET', [])->getData();
292
    }
293
294
    /**
295
     * Get all the transactions that have happened overtime
296
     * @return array
297
     */
298
    public function getAllTransactions()
299
    {
300
        $this->setRequestOptions();
301
302
        return $this->setHttpResponse("/transaction", 'GET', [])->getData();
303
    }
304
305
    /**
306
     * Get the whole response from a get operation
307
     * @return array
308
     */
309
    private function getResponse()
310
    {
311
        return json_decode($this->response->getBody(), true);
312
    }
313
314
    /**
315
     * Get the data response from a get operation
316
     * @return array
317
     */
318
    private function getData()
319
    {
320
        return $this->getResponse()['data'];
321
    }
322
323
    /**
324
     * Create a plan
325
     */
326 View Code Duplication
    public function createPlan()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
327
    {
328
        $data = [
329
            "name" => request()->name,
330
            "description" => request()->desc,
331
            "amount" => intval(request()->amount),
332
            "interval" => request()->interval,
333
            "send_invoices" => request()->send_invoices,
334
            "send_sms" => request()->send_sms,
335
            "currency" => request()->currency,
336
        ];
337
338
        $this->setRequestOptions();
339
340
        $this->setHttpResponse("/plan", 'POST', $data);
341
    }
342
343
    /**
344
     * Fetch any plan based on its plan id or code
345
     * @param $plan_code
346
     * @return array
347
     */
348
    public function fetchPlan($plan_code)
349
    {
350
        $this->setRequestOptions();
351
        return $this->setHttpResponse('/plan/' . $plan_code, 'GET', [])->getResponse();
352
    }
353
354
    /**
355
     * Update any plan's details based on its id or code
356
     * @param $plan_code
357
     * @return array
358
     */
359 View Code Duplication
    public function updatePlan($plan_code)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
360
    {
361
        $data = [
362
            "name" => request()->name,
363
            "description" => request()->desc,
364
            "amount" => intval(request()->amount),
365
            "interval" => request()->interval,
366
            "send_invoices" => request()->send_invoices,
367
            "send_sms" => request()->send_sms,
368
            "currency" => request()->currency,
369
        ];
370
371
        $this->setRequestOptions();
372
        return $this->setHttpResponse('/plan/' . $plan_code, 'PUT', $data)->getResponse();
373
    }
374
375
    /**
376
     * Create a customer
377
     */
378 View Code Duplication
    public function createCustomer()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
379
    {
380
        $data = [
381
            "email" => request()->email,
382
            "first_name" => request()->fname,
383
            "last_name" => request()->lname,
384
            "phone" => request()->phone,
385
            "metadata" => request()->additional_info /* key => value pairs array */
386
387
        ];
388
389
        $this->setRequestOptions();
390
        return $this->setHttpResponse('/customer', 'POST', $data)->getResponse();
391
    }
392
393
    /**
394
     * Fetch a customer based on id or code
395
     * @param $customer_id
396
     * @return array
397
     */
398
    public function fetchCustomer($customer_id)
399
    {
400
        $this->setRequestOptions();
401
        return $this->setHttpResponse('/customer/'. $customer_id, 'GET', [])->getResponse();
402
    }
403
404
    /**
405
     * Update a customer's details based on their id or code
406
     * @param $customer_id
407
     * @return array
408
     */
409 View Code Duplication
    public function updateCustomer($customer_id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
410
    {
411
        $data = [
412
            "email" => request()->email,
413
            "first_name" => request()->fname,
414
            "last_name" => request()->lname,
415
            "phone" => request()->phone,
416
            "metadata" => request()->additional_info /* key => value pairs array */
417
418
        ];
419
420
        $this->setRequestOptions();
421
        return $this->setHttpResponse('/customer/'. $customer_id, 'PUT', $data)->getResponse();
422
    }
423
424
    /**
425
     * Export transactions in .CSV
426
     * @return array
427
     */
428
    public function exportTransactions()
429
    {
430
        $data = [
431
            "from" => request()->from,
432
            "to" => request()->to,
433
            'settled' => request()->settled
434
        ];
435
436
        $this->setRequestOptions();
437
        return $this->setHttpResponse('/transaction/export', 'GET', $data)->getResponse();
438
    }
439
440
    /**
441
     * Create a subscription to a plan from a customer.
442
     */
443 View Code Duplication
    public function createSubscription()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
444
    {
445
        $data = [
446
            "customer" => request()->customer, //Customer email or code
447
            "plan" => request()->plan,
448
            "authorization" => request()->authorization_code
449
        ];
450
451
        $this->setRequestOptions();
452
        $this->setHttpResponse('/subscription', 'POST', $data);
453
    }
454
455
    /**
456
     * Get all the subscriptions made on Paystack.
457
     *
458
     * @return array
459
     */
460
    public function getAllSubscriptions()
461
    {
462
        $this->setRequestOptions();
463
464
        return $this->setHttpResponse("/subscription", 'GET', [])->getData();
465
    }
466
467
    /**
468
     * Get customer subscriptions
469
     *
470
     * @param integer $customer_id
471
     * @return array
472
     */
473
    public function getCustomerSubscriptions($customer_id)
474
    {
475
        $this->setRequestOptions();
476
477
        return $this->setHttpResponse('/subscription?customer=' . $customer_id, 'GET', [])->getData();
478
    }
479
480
    /**
481
     * Get plan subscriptions
482
     *
483
     * @param  integer $plan_id
484
     * @return array
485
     */
486
    public function getPlanSubscriptions($plan_id)
487
    {
488
        $this->setRequestOptions();
489
490
        return $this->setHttpResponse('/subscription?plan=' . $plan_id, 'GET', [])->getData();
491
    }
492
493
    /**
494
     * Enable a subscription using the subscription code and token
495
     * @return array
496
     */
497 View Code Duplication
    public function enableSubscription()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
498
    {
499
        $data = [
500
            "code" => request()->code,
501
            "token" => request()->token,
502
        ];
503
504
        $this->setRequestOptions();
505
        return $this->setHttpResponse('/subscription/enable', 'POST', $data)->getResponse();
506
    }
507
508
    /**
509
     * Disable a subscription using the subscription code and token
510
     * @return array
511
     */
512 View Code Duplication
    public function disableSubscription()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
513
    {
514
        $data = [
515
            "code" => request()->code,
516
            "token" => request()->token,
517
        ];
518
519
        $this->setRequestOptions();
520
        return $this->setHttpResponse('/subscription/disable', 'POST', $data)->getResponse();
521
    }
522
523
    /**
524
     * Fetch details about a certain subscription
525
     * @param mixed $subscription_id
526
     * @return array
527
     */
528
    public function fetchSubscription($subscription_id)
529
    {
530
        $this->setRequestOptions();
531
        return $this->setHttpResponse('/subscription/'.$subscription_id, 'GET', [])->getResponse();
532
    }
533
534
    /**
535
     * Create pages you can share with users using the returned slug
536
     */
537 View Code Duplication
    public function createPage()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
538
    {
539
        $data = [
540
            "name" => request()->name,
541
            "description" => request()->description,
542
            "amount" => request()->amount
543
        ];
544
545
        $this->setRequestOptions();
546
        $this->setHttpResponse('/page', 'POST', $data);
547
    }
548
549
    /**
550
     * Fetches all the pages the merchant has
551
     * @return array
552
     */
553
    public function getAllPages()
554
    {
555
        $this->setRequestOptions();
556
        return $this->setHttpResponse('/page', 'GET', [])->getResponse();
557
    }
558
559
    /**
560
     * Fetch details about a certain page using its id or slug
561
     * @param mixed $page_id
562
     * @return array
563
     */
564
    public function fetchPage($page_id)
565
    {
566
        $this->setRequestOptions();
567
        return $this->setHttpResponse('/page/'.$page_id, 'GET', [])->getResponse();
568
    }
569
570
    /**
571
     * Update the details about a particular page
572
     * @param $page_id
573
     * @return array
574
     */
575 View Code Duplication
    public function updatePage($page_id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
576
    {
577
        $data = [
578
            "name" => request()->name,
579
            "description" => request()->description,
580
            "amount" => request()->amount
581
        ];
582
583
        $this->setRequestOptions();
584
        return $this->setHttpResponse('/page/'.$page_id, 'PUT', $data)->getResponse();
585
    }
586
}
587