1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
/* |
6
|
|
|
* This file is part of the Laravel Paystack package. |
7
|
|
|
* |
8
|
|
|
* (c) Prosper Otemuyiwa <[email protected]> |
9
|
|
|
* |
10
|
|
|
* For the full copyright and license information, please view the LICENSE |
11
|
|
|
* file that was distributed with this source code. |
12
|
|
|
*/ |
13
|
|
|
|
14
|
|
|
namespace Unicodeveloper\Paystack; |
15
|
|
|
|
16
|
|
|
use Unicodeveloper\Paystack\Exceptions\PaymentVerificationFailedException; |
17
|
|
|
|
18
|
|
|
class Paystack |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* Transaction Verification Successful |
22
|
|
|
*/ |
23
|
|
|
const VERIFICATION_SUCCESSFUL = 'Verification successful'; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Invalid Transaction reference |
27
|
|
|
*/ |
28
|
|
|
const INVALID_TRANSACTION_REFERENCE = "Invalid transaction reference"; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Response from requests made to Paystack |
32
|
|
|
* @var array |
33
|
|
|
*/ |
34
|
|
|
protected $response; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Authorization Url - Paystack payment page |
38
|
|
|
* @var string |
39
|
|
|
*/ |
40
|
|
|
protected $authorizationUrl; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var \Xeviant\Paystack\Client |
44
|
|
|
*/ |
45
|
|
|
private $paystack; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Authorization URL |
49
|
|
|
* |
50
|
|
|
* @var string |
51
|
|
|
*/ |
52
|
|
|
private $url; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Paystack constructor. |
56
|
|
|
*/ |
57
|
|
|
public function __construct() |
58
|
|
|
{ |
59
|
|
|
$this->paystack = app()->make('paystack.connection'); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Initiate a payment request to Paystack |
65
|
|
|
* Included the option to pass the payload to this method for situations |
66
|
|
|
* when the payload is built on the fly (not passed to the controller from a view) |
67
|
|
|
* @param null $data |
68
|
|
|
* @return Paystack |
69
|
|
|
*/ |
70
|
|
|
public function makePaymentRequest($data = null) |
71
|
|
|
{ |
72
|
|
|
if ( $data == null ) { |
73
|
|
|
$data = [ |
74
|
|
|
"amount" => intval(request()->amount), |
75
|
|
|
"reference" => request()->reference, |
76
|
|
|
"email" => request()->email, |
77
|
|
|
"plan" => request()->plan, |
78
|
|
|
"first_name" => request()->first_name, |
79
|
|
|
"last_name" => request()->last_name, |
80
|
|
|
"callback_url" => request()->callback_url, |
81
|
|
|
/* |
82
|
|
|
* to allow use of metadata on Paystack dashboard and a means to return additional data back to redirect url |
83
|
|
|
* form need an input field: <input type="hidden" name="metadata" value="{{ json_encode($array) }}" > |
84
|
|
|
*array must be set up as: $array = [ 'custom_fields' => [ |
85
|
|
|
* ['display_name' => "Cart Id", "variable_name" => "cart_id", "value" => "2"], |
86
|
|
|
* ['display_name' => "Sex", "variable_name" => "sex", "value" => "female"], |
87
|
|
|
* . |
88
|
|
|
* . |
89
|
|
|
* . |
90
|
|
|
* ] |
91
|
|
|
* |
92
|
|
|
* ] |
93
|
|
|
*/ |
94
|
|
|
'metadata' => request()->metadata |
95
|
|
|
]; |
96
|
|
|
|
97
|
|
|
// Remove the fields which were not sent (value would be null) |
98
|
|
|
array_filter($data); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
$this->response = $this->paystack->transactions()->initialize($data); |
102
|
|
|
|
103
|
|
|
return $this; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Get the authorization url from the callback response |
108
|
|
|
* @return Paystack |
109
|
|
|
*/ |
110
|
|
|
public function getAuthorizationUrl() |
111
|
|
|
{ |
112
|
|
|
$this->makePaymentRequest(); |
113
|
|
|
|
114
|
|
|
$this->url = $this->getResponse()['data']['authorization_url']; |
115
|
|
|
|
116
|
|
|
return $this; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Get the authorization callback response |
121
|
|
|
* In situations where Laravel serves as an backend for a detached UI, the api cannot redirect |
122
|
|
|
* and might need to take different actions based on the success or not of the transaction |
123
|
|
|
* @param $data |
124
|
|
|
* @return array |
125
|
|
|
*/ |
126
|
|
|
public function getAuthorizationResponse($data) |
127
|
|
|
{ |
128
|
|
|
$this->makePaymentRequest($data); |
129
|
|
|
|
130
|
|
|
$this->url = $this->getResponse()['data']['authorization_url']; |
131
|
|
|
|
132
|
|
|
return $this->getResponse(); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Hit Paystack Gateway to Verify that the transaction is valid |
137
|
|
|
*/ |
138
|
|
|
private function verifyTransactionAtGateway() |
139
|
|
|
{ |
140
|
|
|
$transactionRef = request()->query('trxref'); |
141
|
|
|
|
142
|
|
|
$this->response = $this->paystack->transactions()->verify($transactionRef); |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* True or false condition whether the transaction is verified |
147
|
|
|
* @return boolean |
148
|
|
|
*/ |
149
|
|
|
public function isTransactionVerificationValid() |
150
|
|
|
{ |
151
|
|
|
$this->verifyTransactionAtGateway(); |
152
|
|
|
|
153
|
|
|
$result = $this->getResponse()['message']; |
154
|
|
|
|
155
|
|
|
switch ($result) { |
156
|
|
|
case self::VERIFICATION_SUCCESSFUL: |
157
|
|
|
$validate = true; |
158
|
|
|
break; |
159
|
|
|
case self::INVALID_TRANSACTION_REFERENCE: |
160
|
|
|
$validate = false; |
161
|
|
|
break; |
162
|
|
|
default: |
163
|
|
|
$validate = false; |
164
|
|
|
break; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
return $validate; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Get Payment details if the transaction was verified successfully |
172
|
|
|
* @return array |
173
|
|
|
* @throws PaymentVerificationFailedException |
174
|
|
|
*/ |
175
|
|
|
public function getPaymentData() |
176
|
|
|
{ |
177
|
|
|
if ($this->isTransactionVerificationValid()) { |
178
|
|
|
return $this->getResponse(); |
179
|
|
|
} else { |
180
|
|
|
throw new PaymentVerificationFailedException("Invalid Transaction Reference"); |
181
|
|
|
} |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* Fluent method to redirect to Paystack Payment Page |
186
|
|
|
*/ |
187
|
|
|
public function redirectNow() |
188
|
|
|
{ |
189
|
|
|
return redirect($this->url); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Get Access code from transaction callback response |
194
|
|
|
* @return string |
195
|
|
|
*/ |
196
|
|
|
public function getAccessCode() |
197
|
|
|
{ |
198
|
|
|
return $this->getResponse()['data']['access_code']; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* Generate a Unique Transaction Reference |
203
|
|
|
* @return string |
204
|
|
|
*/ |
205
|
|
|
public function genTranxRef() |
206
|
|
|
{ |
207
|
|
|
return TransRef::getHashedToken(); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Get all the customers that have made transactions on your platform |
212
|
|
|
* @return array |
213
|
|
|
*/ |
214
|
|
|
public function getAllCustomers() |
215
|
|
|
{ |
216
|
|
|
return $this->paystack->cutsomers()->list(); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Get all the plans that you have on Paystack |
221
|
|
|
* @return array |
222
|
|
|
*/ |
223
|
|
|
public function getAllPlans() |
224
|
|
|
{ |
225
|
|
|
return $this->paystack->plans()->list(); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
/** |
229
|
|
|
* Get all the transactions that have happened overtime |
230
|
|
|
* @return array |
231
|
|
|
*/ |
232
|
|
|
public function getAllTransactions() |
233
|
|
|
{ |
234
|
|
|
return $this->paystack->transactions()->list(); |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
/** |
238
|
|
|
* Get the whole response from a get operation |
239
|
|
|
* @return array |
240
|
|
|
*/ |
241
|
|
|
private function getResponse() |
242
|
|
|
{ |
243
|
|
|
return $this->response; |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
/** |
247
|
|
|
* Create a plan |
248
|
|
|
*/ |
249
|
|
View Code Duplication |
public function createPlan() |
|
|
|
|
250
|
|
|
{ |
251
|
|
|
$data = [ |
252
|
|
|
"name" => request()->name, |
253
|
|
|
"description" => request()->desc, |
254
|
|
|
"amount" => intval(request()->amount), |
255
|
|
|
"interval" => request()->interval, |
256
|
|
|
"send_invoices" => request()->send_invoices, |
257
|
|
|
"send_sms" => request()->send_sms, |
258
|
|
|
"currency" => request()->currency, |
259
|
|
|
]; |
260
|
|
|
|
261
|
|
|
return $this->paystack->plans()->create($data); |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* Fetch any plan based on its plan id or code |
266
|
|
|
* @param $planCode |
267
|
|
|
* @return array |
268
|
|
|
*/ |
269
|
|
|
public function fetchPlan($planCode) |
270
|
|
|
{ |
271
|
|
|
return $this->paystack->plans()->fetch($planCode); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* Update any plan's details based on its id or code |
276
|
|
|
* @param $planCode |
277
|
|
|
* @return array |
278
|
|
|
*/ |
279
|
|
View Code Duplication |
public function updatePlan($planCode) |
|
|
|
|
280
|
|
|
{ |
281
|
|
|
$data = [ |
282
|
|
|
"name" => request()->name, |
283
|
|
|
"description" => request()->desc, |
284
|
|
|
"amount" => intval(request()->amount), |
285
|
|
|
"interval" => request()->interval, |
286
|
|
|
"send_invoices" => request()->send_invoices, |
287
|
|
|
"send_sms" => request()->send_sms, |
288
|
|
|
"currency" => request()->currency, |
289
|
|
|
]; |
290
|
|
|
|
291
|
|
|
return $this->paystack->plans()->update($planCode, $data); |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
/** |
295
|
|
|
* Create a customer |
296
|
|
|
*/ |
297
|
|
View Code Duplication |
public function createCustomer() |
|
|
|
|
298
|
|
|
{ |
299
|
|
|
$data = [ |
300
|
|
|
"email" => request()->email, |
301
|
|
|
"first_name" => request()->fname, |
302
|
|
|
"last_name" => request()->lname, |
303
|
|
|
"phone" => request()->phone, |
304
|
|
|
"metadata" => request()->additional_info /* key => value pairs array */ |
305
|
|
|
|
306
|
|
|
]; |
307
|
|
|
|
308
|
|
|
return $this->paystack->customers()->create($data); |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
/** |
312
|
|
|
* Fetch a customer based on id or code |
313
|
|
|
* @param $customerId |
314
|
|
|
* @return array |
315
|
|
|
*/ |
316
|
|
|
public function fetchCustomer($customerId) |
317
|
|
|
{ |
318
|
|
|
return $this->paystack->customers()->fetch($customerId); |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
/** |
322
|
|
|
* Update a customer's details based on their id or code |
323
|
|
|
* @param $customerId |
324
|
|
|
* @return array |
325
|
|
|
*/ |
326
|
|
View Code Duplication |
public function updateCustomer($customerId) |
|
|
|
|
327
|
|
|
{ |
328
|
|
|
$data = [ |
329
|
|
|
"email" => request()->email, |
330
|
|
|
"first_name" => request()->fname, |
331
|
|
|
"last_name" => request()->lname, |
332
|
|
|
"phone" => request()->phone, |
333
|
|
|
"metadata" => request()->additional_info /* key => value pairs array */ |
334
|
|
|
|
335
|
|
|
]; |
336
|
|
|
|
337
|
|
|
return $this->paystack->customers()->update($customerId, $data); |
338
|
|
|
} |
339
|
|
|
|
340
|
|
|
/** |
341
|
|
|
* Export transactions in .CSV |
342
|
|
|
* @return array |
343
|
|
|
*/ |
344
|
|
|
public function exportTransactions() |
345
|
|
|
{ |
346
|
|
|
$data = [ |
347
|
|
|
"from" => request()->from, |
348
|
|
|
"to" => request()->to, |
349
|
|
|
'settled' => request()->settled |
350
|
|
|
]; |
351
|
|
|
|
352
|
|
|
return $this->paystack->transactions()->export($data); |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* Create a subscription to a plan from a customer. |
357
|
|
|
*/ |
358
|
|
|
public function createSubscription() |
359
|
|
|
{ |
360
|
|
|
$data = [ |
361
|
|
|
"customer" => request()->customer, //Customer email or code |
362
|
|
|
"plan" => request()->plan, |
363
|
|
|
"authorization" => request()->authorization_code |
364
|
|
|
]; |
365
|
|
|
|
366
|
|
|
return $this->paystack->subscriptions()->create($data); |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* Get all the subscriptions made on Paystack. |
371
|
|
|
* |
372
|
|
|
* @return array |
373
|
|
|
*/ |
374
|
|
|
public function getAllSubscriptions() |
375
|
|
|
{ |
376
|
|
|
return $this->paystack->subscriptions()->list(); |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
/** |
380
|
|
|
* Get customer subscriptions |
381
|
|
|
* |
382
|
|
|
* @param integer $customerId |
383
|
|
|
* @return array |
384
|
|
|
*/ |
385
|
|
|
public function getCustomerSubscriptions($customerId) |
386
|
|
|
{ |
387
|
|
|
return $this->paystack->subscriptions()->list(['customer' => $customerId]); |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
/** |
391
|
|
|
* Get plan subscriptions |
392
|
|
|
* |
393
|
|
|
* @param integer $planId |
394
|
|
|
* @return array |
395
|
|
|
*/ |
396
|
|
|
public function getPlanSubscriptions($planId) |
397
|
|
|
{ |
398
|
|
|
return $this->paystack->subscriptions()->list(['plan' => $planId]); |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
/** |
402
|
|
|
* Enable a subscription using the subscription code and token |
403
|
|
|
* @return array |
404
|
|
|
*/ |
405
|
|
|
public function enableSubscription() |
406
|
|
|
{ |
407
|
|
|
$data = [ |
408
|
|
|
"code" => request()->code, |
409
|
|
|
"token" => request()->token, |
410
|
|
|
]; |
411
|
|
|
|
412
|
|
|
return $this->paystack->subscrptions()->enable($data); |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
/** |
416
|
|
|
* Disable a subscription using the subscription code and token |
417
|
|
|
* @return array |
418
|
|
|
*/ |
419
|
|
|
public function disableSubscription() |
420
|
|
|
{ |
421
|
|
|
$data = [ |
422
|
|
|
"code" => request()->code, |
423
|
|
|
"token" => request()->token, |
424
|
|
|
]; |
425
|
|
|
|
426
|
|
|
return $this->paystack->subscriptions()->disabled($data); |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
/** |
430
|
|
|
* Fetch details about a certain subscription |
431
|
|
|
* @param mixed $subscriptionId |
432
|
|
|
* @return array |
433
|
|
|
*/ |
434
|
|
|
public function fetchSubscription($subscriptionId) |
435
|
|
|
{ |
436
|
|
|
return $this->paystack->subscriptions()->fetch($subscriptionId); |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* Create pages you can share with users using the returned slug |
441
|
|
|
*/ |
442
|
|
View Code Duplication |
public function createPage() |
|
|
|
|
443
|
|
|
{ |
444
|
|
|
$data = [ |
445
|
|
|
"name" => request()->name, |
446
|
|
|
"description" => request()->description, |
447
|
|
|
"amount" => request()->amount |
448
|
|
|
]; |
449
|
|
|
|
450
|
|
|
return $this->paystack->pages()->create($data); |
451
|
|
|
} |
452
|
|
|
|
453
|
|
|
/** |
454
|
|
|
* Fetches all the pages the merchant has |
455
|
|
|
* @return array |
456
|
|
|
*/ |
457
|
|
|
public function getAllPages() |
458
|
|
|
{ |
459
|
|
|
return $this->paystack->pages()->list(); |
460
|
|
|
} |
461
|
|
|
|
462
|
|
|
/** |
463
|
|
|
* Fetch details about a certain page using its id or slug |
464
|
|
|
* @param mixed $pageId |
465
|
|
|
* @return array |
466
|
|
|
*/ |
467
|
|
|
public function fetchPage($pageId) |
468
|
|
|
{ |
469
|
|
|
return $this->paystack->pages()->fetch($pageId); |
470
|
|
|
} |
471
|
|
|
|
472
|
|
|
/** |
473
|
|
|
* Update the details about a particular page |
474
|
|
|
* @param $pageId |
475
|
|
|
* @return array |
476
|
|
|
*/ |
477
|
|
View Code Duplication |
public function updatePage($pageId) |
|
|
|
|
478
|
|
|
{ |
479
|
|
|
$data = [ |
480
|
|
|
"name" => request()->name, |
481
|
|
|
"description" => request()->description, |
482
|
|
|
"amount" => request()->amount |
483
|
|
|
]; |
484
|
|
|
|
485
|
|
|
return $this->paystack->pages()->update($pageId, $data); |
486
|
|
|
} |
487
|
|
|
|
488
|
|
|
/** |
489
|
|
|
* Creates a subaccount to be used for split payments . Required params are business_name , settlement_bank , account_number , percentage_charge |
490
|
|
|
* |
491
|
|
|
* @return array |
492
|
|
|
*/ |
493
|
|
|
|
494
|
|
View Code Duplication |
public function createSubAccount() |
|
|
|
|
495
|
|
|
{ |
496
|
|
|
$data = [ |
497
|
|
|
"business_name" => request()->business_name, |
498
|
|
|
"settlement_bank" => request()->settlement_bank, |
499
|
|
|
"account_number" => request()->account_number, |
500
|
|
|
"percentage_charge" => request()->percentage_charge, |
501
|
|
|
"primary_contact_email" => request()->primary_contact_email, |
502
|
|
|
"primary_contact_name" => request()->primary_contact_name, |
503
|
|
|
"primary_contact_phone" => request()->primary_contact_phone, |
504
|
|
|
"metadata" => request()->metadata, |
505
|
|
|
'settlement_schedule' => request()->settlement_schedule |
506
|
|
|
]; |
507
|
|
|
|
508
|
|
|
return $this->paystack->subAccount()->create($data); |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
/** |
512
|
|
|
* Fetches details of a subaccount |
513
|
|
|
* @param subaccount code |
514
|
|
|
* @return array |
515
|
|
|
*/ |
516
|
|
|
public function fetchSubAccount($subAccountCode) |
517
|
|
|
{ |
518
|
|
|
return $this->paystack->subAccount()->fetch($subAccountCode); |
519
|
|
|
} |
520
|
|
|
|
521
|
|
|
/** |
522
|
|
|
* Lists all the subaccounts associated with the account |
523
|
|
|
* @param $perPage - Specifies how many records to retrieve per page , $page - SPecifies exactly what page to retrieve |
524
|
|
|
* @param $page |
525
|
|
|
* @return array |
526
|
|
|
*/ |
527
|
|
|
public function listSubAccounts($perPage = null, $page = null) |
528
|
|
|
{ |
529
|
|
|
return $this->paystack->subAccount()->list(['perPage' => $perPage, 'page' => $page]); |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
|
533
|
|
|
/** |
534
|
|
|
* Updates a sub-account to be used for split payments . Required params are business_name , settlement_bank , account_number , percentage_charge |
535
|
|
|
* @param sub-account code |
536
|
|
|
* @return array |
537
|
|
|
*/ |
538
|
|
|
|
539
|
|
View Code Duplication |
public function updateSubAccount($subAccountCode) |
|
|
|
|
540
|
|
|
{ |
541
|
|
|
$data = [ |
542
|
|
|
"business_name" => request()->business_name, |
543
|
|
|
"settlement_bank" => request()->settlement_bank, |
544
|
|
|
"account_number" => request()->account_number, |
545
|
|
|
"percentage_charge" => request()->percentage_charge, |
546
|
|
|
"description" => request()->description, |
547
|
|
|
"primary_contact_email" => request()->primary_contact_email, |
548
|
|
|
"primary_contact_name" => request()->primary_contact_name, |
549
|
|
|
"primary_contact_phone" => request()->primary_contact_phone, |
550
|
|
|
"metadata" => request()->metadata, |
551
|
|
|
'settlement_schedule' => request()->settlement_schedule |
552
|
|
|
]; |
553
|
|
|
|
554
|
|
|
return $this->paystack->subAccount()->update($subAccountCode, $data); |
555
|
|
|
} |
556
|
|
|
} |
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.