Completed
Push — master ( 4b40fd...e9df56 )
by PROSPER
9s
created

Paystack::createSubscription()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 10
Ratio 100 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 10
loc 10
rs 9.4285
cc 1
eloc 7
nc 1
nop 0
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
17
class Paystack {
18
19
    /**
20
     * Transaction Verification Successful
21
     */
22
    const VS = 'Verification successful';
23
24
    /**
25
     *  Invalid Transaction reference
26
     */
27
    const ITF = "Invalid transaction reference";
28
29
    /**
30
     * Issue Secret Key from your Paystack Dashboard
31
     * @var mixed
32
     */
33
    protected $secretKey;
34
35
    /**
36
     * Instance of Client
37
     * @var object
38
     */
39
    protected $client;
40
41
    /**
42
     *  Response from requests made to Paystack
43
     * @var mixed
44
     */
45
    protected $response;
46
47
    /**
48
     * Paystack API base Url
49
     * @var string
50
     */
51
    protected $baseUrl;
52
53
    /**
54
     * Authorization Url - Paystack payment page
55
     * @var string
56
     */
57
    protected $authorizationUrl;
58
59
    public function __construct()
60
    {
61
        $this->setKey();
62
        $this->setBaseUrl();
63
        $this->setRequestOptions();
64
    }
65
66
    /**
67
     * Get Base Url from Paystack config file
68
     */
69
    public function setBaseUrl()
70
    {
71
        $this->baseUrl = Config::get('paystack.paymentUrl');
72
    }
73
74
    /**
75
     * Get secret key from Paystack config file
76
     * @return  void
77
     */
78
    public function setKey()
79
    {
80
        $this->secretKey = Config::get('paystack.secretKey');
81
    }
82
83
    /**
84
     * Set options for making the Client request
85
     * @return  void
86
     */
87
    private function setRequestOptions()
88
    {
89
        $authBearer = 'Bearer '. $this->secretKey;
90
91
        $this->client = new Client(['base_uri' => $this->baseUrl,
92
            'headers' => [
93
                'Authorization' => $authBearer,
94
                'Content-Type'  => 'application/json',
95
                'Accept'        => 'application/json'
96
        ]]);
97
    }
98
99
    /**
100
     * Initiate a payment request to Paystack
101
     */
102
    public function makePaymentRequest()
103
    {
104
        $data = [
105
            "amount" => intval(request()->amount),
106
            "reference" => request()->reference,
107
            "email" => request()->email
108
        ];
109
110
        $this->setHttpResponse('/transaction/initialize', 'POST', $data);
111
112
        return $this;
113
    }
114
115
116
    private function setHttpResponse($relativeUrl, $method, $body = [])
117
    {
118
        if(is_null($method)){
119
            throw new IsNullException("Empty method not allowed");
120
        }
121
122
        $this->response = $this->client->{strtolower($method)}($this->baseUrl . $relativeUrl, ["body" => json_encode($body)]);
123
        return $this;
124
    }
125
126
    /**
127
     * Get the authorization url from the callback response
128
     */
129
    public function getAuthorizationUrl()
130
    {
131
        $this->makePaymentRequest();
132
133
        $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...
134
135
        return $this;
136
    }
137
138
    /**
139
     * Hit Paystack Gateway to Verify that the transaction is valid
140
     * @return void
141
     */
142
    private function verifyTransactionAtGateway()
143
    {
144
        $transactionRef = request()->query('trxref');
145
146
        $relativeUrl = "/transaction/verify/{$transactionRef}";
147
148
        $this->response = $this->client->get($this->baseUrl . $relativeUrl, []);
149
    }
150
151
    /**
152
     * True or false condition whether the transaction is verified
153
     * @return boolean
154
     */
155
    public function isTransactionVerificationValid()
156
    {
157
        $this->verifyTransactionAtGateway();
158
159
        $result = $this->getResponse()['message'];
160
161
        switch ($result)
162
        {
163
            case self::VS:
164
                $validate = true;
165
                break;
166
            case self:ITF:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
167
                $validate = false;
168
                break;
169
            default:
170
                $validate = false;
171
                break;
172
        }
173
174
        return $validate;
175
    }
176
177
    /**
178
     * Get Payment details if the transaction was verified successfully
179
     * @return json
180
     * @throws PaymentVerificationFailedException
181
     */
182
    public function getPaymentData()
183
    {
184
        if ($this->isTransactionVerificationValid()) {
185
            return $this->getResponse();
186
        } else {
187
            throw new PaymentVerificationFailedException("Invalid Transaction Reference");
188
        }
189
    }
190
191
    /**
192
     * Fluent method to redirect to Paystack Payment Page
193
     */
194
    public function redirectNow()
195
    {
196
        return redirect($this->url);
197
    }
198
199
    /**
200
     * Get Access code from transaction callback respose
201
     * @return string
202
     */
203
    public function getAccessCode()
204
    {
205
        return $this->getResponse()['data']['access_code'];
206
    }
207
208
    /**
209
     * Generate a Unique Transaction Reference
210
     * @return string
211
     */
212
    public function genTranxRef()
213
    {
214
        return TransRef::getHashedToken();
215
    }
216
217
    /**
218
     * Get all the customers that have made transactions on your platform
219
     * @return array
220
     */
221
    public function getAllCustomers()
222
    {
223
        $this->setRequestOptions();
224
225
        return $this->setHttpResponse("/customer", 'GET', [])->getData();
226
    }
227
228
    /**
229
     * Get all the plans that you have on Paystack
230
     * @return array
231
     */
232
    public function getAllPlans()
233
    {
234
        $this->setRequestOptions();
235
236
        return $this->setHttpResponse("/plan", 'GET', [])->getData();
237
    }
238
239
    /**
240
     * Get all the transactions that have happened overtime
241
     * @return array
242
     */
243
    public function getAllTransactions()
244
    {
245
        $this->setRequestOptions();
246
247
        return $this->setHttpResponse("/transaction", 'GET', [])->getData();
248
    }
249
250
    /**
251
     * Get the whole response from a get operation
252
     * @return array
253
     */
254
    private function getResponse()
255
    {
256
        return json_decode($this->response->getBody(), true);
257
    }
258
259
    /**
260
     * Get the data response from a get operation
261
     * @return array
262
     */
263
    private function getData()
264
    {
265
        return $this->getResponse()['data'];
266
    }
267
268
    /**
269
     * Create a plan
270
     */
271 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...
272
273
        $data = [
274
            "name" => request()->name,
275
            "description" => request()->desc,
276
            "amount" => intval(request()->amount),
277
            "interval" => request()->interval,
278
            "send_invoices" => request()->send_invoices,
279
            "send_sms" => request()->send_sms,
280
            "currency" => request()->currency,
281
        ];
282
283
        $this->setRequestOptions();
284
285
        $this->setHttpResponse("/plan", 'POST', $data);
286
287
    }
288
289
    /**
290
     * Fetch any plan based on its plan id or code
291
     * @param $plan_code
292
     * @return array
293
     */
294
    public function fetchPlan($plan_code){
295
        $this->setRequestOptions();
296
        return $this->setHttpResponse('/plan/' . $plan_code, 'GET', [])->getResponse();
297
    }
298
299
    /**
300
     * Update any plan's details based on its id or code
301
     * @param $plan_code
302
     * @return array
303
     */
304 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...
305
        $data = [
306
            "name" => request()->name,
307
            "description" => request()->desc,
308
            "amount" => intval(request()->amount),
309
            "interval" => request()->interval,
310
            "send_invoices" => request()->send_invoices,
311
            "send_sms" => request()->send_sms,
312
            "currency" => request()->currency,
313
        ];
314
315
        $this->setRequestOptions();
316
        return $this->setHttpResponse('/plan/' . $plan_code, 'PUT', $data)->getResponse();
317
    }
318
319
    /**
320
     * Create a customer
321
     * @return array
322
     */
323 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...
324
        $data = [
325
            "email" => request()->email,
326
            "first_name" => request()->fname,
327
            "last_name" => request()->lname,
328
            "phone" => request()->phone,
329
            "metadata" => request()->additional_info /* key => value pairs array */
330
331
        ];
332
333
        $this->setRequestOptions();
334
        $this->setHttpResponse('/customer', 'POST', $data);
335
    }
336
337
    /**
338
     * Fetch a customer based on id or code
339
     * @param $customer_id
340
     * @return array
341
     */
342
    public function fetchCustomer($customer_id)
343
    {
344
        $this->setRequestOptions();
345
        return $this->setHttpResponse('/customer/'. $customer_id, 'GET', [])->getResponse();
346
    }
347
348
    /**
349
     * Update a customer's details based on their id or code
350
     * @param $customer_id
351
     * @return array
352
     */
353 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...
354
        $data = [
355
            "email" => request()->email,
356
            "first_name" => request()->fname,
357
            "last_name" => request()->lname,
358
            "phone" => request()->phone,
359
            "metadata" => request()->additional_info /* key => value pairs array */
360
361
        ];
362
363
        $this->setRequestOptions();
364
        return $this->setHttpResponse('/customer/'. $customer_id, 'PUT', $data)->getResponse();
365
    }
366
367
    /**
368
     * Export tranactions in .CSV
369
     * @return array
370
     */
371
    public function exportTransactions(){
372
        $data = [
373
            "from" => request()->from,
374
            "to" => request()->to,
375
            'settled' => request()->settled
376
        ];
377
378
        $this->setRequestOptions();
379
        return $this->setHttpResponse('/transaction/export', 'GET', $data)->getResponse();
380
    }
381
382
    /**
383
     * Create a subscription to a plan from a customer.
384
     * @return array
385
     */
386 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...
387
        $data = [
388
            "customer" => request()->customer, //Customer email or code
389
            "plan" => request()->plan,
390
            "authorization" => request()->authorization_code
391
        ];
392
393
        $this->setRequestOptions();
394
        $this->setHttpResponse('/subscription', 'POST', $data);
395
    }
396
397
    /**
398
     * Enable a subscription using the subscription code and token
399
     * @return array
400
     */
401 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...
402
        $data = [
403
            "code" => request()->code,
404
            "token" => request()->token,
405
        ];
406
407
        $this->setRequestOptions();
408
        return $this->setHttpResponse('/subscription/enable', 'POST', $data)->getResponse();
409
    }
410
411
    /**
412
     * Disable a subscription using the subscription code and token
413
     * @return array
414
     */
415 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...
416
        $data = [
417
            "code" => request()->code,
418
            "token" => request()->token,
419
        ];
420
421
        $this->setRequestOptions();
422
        return $this->setHttpResponse('/subscription/disable', 'POST', $data)->getResponse();
423
    }
424
425
    /**
426
     * Fetch details about a certain subscription
427
     * @param $subscription_id
428
     * @return array
429
     */
430
    public function fetchSubscription($subscription_id)
431
    {
432
        $this->setRequestOptions();
433
        return $this->setHttpResponse('/subscription/'.$subscription_id, 'GET', [])->getResponse();
434
    }
435
436
    /**
437
     * Create pages you can share with users using the returned slug
438
     * @return array
439
     */
440 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...
441
        $data = [
442
            "name" => request()->name,
443
            "description" => request()->description,
444
            "amount" => request()->amount
445
        ];
446
447
        $this->setRequestOptions();
448
        $this->setHttpResponse('/page', 'POST', $data);
449
    }
450
451
    /**
452
     * Fetches all the pages the merchant has
453
     * @return array
454
     */
455
    public function getAllPages()
456
    {
457
        $this->setRequestOptions();
458
        return $this->setHttpResponse('/page', 'GET', [])->getResponse();
459
    }
460
461
    /**
462
     * Fetch details about a certain page using its id or slug
463
     * @param $page_id
464
     * @return array
465
     */
466
    public function fetchPage($page_id)
467
    {
468
        $this->setRequestOptions();
469
        return $this->setHttpResponse('/page/'.$page_id, 'GET', [])->getResponse();
470
    }
471
472
    /**
473
     * Update the details about a particular page
474
     * @param $page_id
475
     * @return array
476
     */
477 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...
478
        $data = [
479
            "name" => request()->name,
480
            "description" => request()->description,
481
            "amount" => request()->amount
482
        ];
483
484
        $this->setRequestOptions();
485
        return $this->setHttpResponse('/page/'.$page_id, 'PUT', $data)->getResponse();
486
    }
487
488
}
489
490
491
492