1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Created By: Henry Ejemuta |
4
|
|
|
* Project: laravel-monnify |
5
|
|
|
* Class Name: Monnify.php |
6
|
|
|
* Date Created: 7/13/20 |
7
|
|
|
* Time Created: 7:55 PM |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
namespace HenryEjemuta\LaravelMonnify; |
11
|
|
|
|
12
|
|
|
use HenryEjemuta\LaravelMonnify\Classes\MonnifyAllowedPaymentSources; |
13
|
|
|
use HenryEjemuta\LaravelMonnify\Classes\MonnifyBankAccount; |
14
|
|
|
use HenryEjemuta\LaravelMonnify\Classes\MonnifyIncomeSplitConfig; |
15
|
|
|
use HenryEjemuta\LaravelMonnify\Classes\MonnifyOnFailureValidate; |
16
|
|
|
use HenryEjemuta\LaravelMonnify\Classes\MonnifyPaymentMethods; |
17
|
|
|
use HenryEjemuta\LaravelMonnify\Classes\MonnifyTransaction; |
18
|
|
|
use HenryEjemuta\LaravelMonnify\Classes\MonnifyTransactionList; |
19
|
|
|
use HenryEjemuta\LaravelMonnify\Exceptions\MonnifyFailedRequestException; |
20
|
|
|
use HenryEjemuta\LaravelMonnify\Exceptions\MonnifyInvalidParameterException; |
21
|
|
|
use Illuminate\Support\Facades\Http; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Class Monnify |
25
|
|
|
* @package HenryEjemuta\LaravelMonnify |
26
|
|
|
* |
27
|
|
|
* This is a Laravel wrapper around the Monnify API hence all failed request will throw MonnifyFailedRequestException with the appropriate message from the Monnify API as well as error code |
28
|
|
|
* |
29
|
|
|
* @link https://docs.teamapt.com/display/MON/Monnify+API+Docs for any error details as well as status code to gracefully handle them within your application |
30
|
|
|
* |
31
|
|
|
*/ |
32
|
|
|
class Monnify |
33
|
|
|
{ |
34
|
|
|
/** |
35
|
|
|
* base url |
36
|
|
|
* |
37
|
|
|
* @var |
38
|
|
|
*/ |
39
|
|
|
private $baseUrl; |
40
|
|
|
private $v1 = "/api/v1/"; |
41
|
|
|
private $v2 = "/api/v2/"; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* the cart session key |
45
|
|
|
* |
46
|
|
|
* @var |
47
|
|
|
*/ |
48
|
|
|
protected $instanceName; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Flexible handle to the Monnify Configuration |
52
|
|
|
* |
53
|
|
|
* @var |
54
|
|
|
*/ |
55
|
|
|
protected $config; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Http Client for remote request handling |
59
|
|
|
* @var Http |
60
|
|
|
*/ |
61
|
|
|
private $httpClient; |
62
|
|
|
|
63
|
|
|
|
64
|
|
|
private $oAuth2Token = ''; |
65
|
|
|
private $oAuth2TokenExpires = ''; |
66
|
|
|
|
67
|
|
|
public function __construct($baseUrl, $instanceName, $config) |
68
|
|
|
{ |
69
|
|
|
$this->baseUrl = $baseUrl; |
70
|
|
|
$this->instanceName = $instanceName; |
71
|
|
|
$this->config = $config; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* get instance name of the cart |
77
|
|
|
* |
78
|
|
|
* @return string |
79
|
|
|
*/ |
80
|
|
|
public function getInstanceName() |
81
|
|
|
{ |
82
|
|
|
return $this->instanceName; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
|
86
|
|
|
private function withBasicAuth() |
87
|
|
|
{ |
88
|
|
|
$this->httpClient = Http::withBasicAuth($this->config['api_key'], $this->config['secret_key'])->asJson(); |
|
|
|
|
89
|
|
|
return $this; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* @return $this |
95
|
|
|
* @throws MonnifyFailedRequestException |
96
|
|
|
*/ |
97
|
|
|
private function getToken() |
98
|
|
|
{ |
99
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}auth/login"; |
100
|
|
|
$this->withBasicAuth(); |
101
|
|
|
$response = $this->httpClient->post($endpoint); |
102
|
|
|
|
103
|
|
|
$responseObject = json_decode($response->body()); |
104
|
|
|
if (!$response->successful()) |
105
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
106
|
|
|
|
107
|
|
|
$this->oAuth2Token = $responseObject->responseBody->accessToken; |
108
|
|
|
$this->oAuth2TokenExpires = ((time() + $responseObject->responseBody->expiresIn) - 60);//Just make sure the token would not expire in 60 secs |
109
|
|
|
|
110
|
|
|
return $this; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
|
114
|
|
|
private function withOAuth2() |
115
|
|
|
{ |
116
|
|
|
if (time() >= $this->oAuth2TokenExpires) { |
117
|
|
|
$this->getToken(); |
118
|
|
|
$this->httpClient = Http::withToken($this->oAuth2Token); |
|
|
|
|
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
return $this; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* This enables you to retrieve all banks supported by Monnify for collections and disbursements. |
127
|
|
|
* @return array |
128
|
|
|
* |
129
|
|
|
* @throws MonnifyFailedRequestException |
130
|
|
|
*/ |
131
|
|
|
public function getBanks() |
132
|
|
|
{ |
133
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}banks"; |
134
|
|
|
|
135
|
|
|
$this->withOAuth2(); |
136
|
|
|
$response = $this->httpClient->get($endpoint); |
137
|
|
|
|
138
|
|
|
$responseObject = json_decode($response->body()); |
139
|
|
|
if (!$response->successful()) |
140
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
141
|
|
|
|
142
|
|
|
return $responseObject->responseBody; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* This API enables you to retrieve all banks with valid USSD short code. This is useful if you'll like to display USSD short codes for your customers to dial. |
148
|
|
|
* For a full list of banks, use @return array |
149
|
|
|
* |
150
|
|
|
* @throws MonnifyFailedRequestException |
151
|
|
|
* |
152
|
|
|
* @see getBanks() |
153
|
|
|
* |
154
|
|
|
*/ |
155
|
|
|
public function getBanksWithUSSDShortCode() |
156
|
|
|
{ |
157
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}sdk/transactions/banks"; |
158
|
|
|
|
159
|
|
|
$this->withOAuth2(); |
160
|
|
|
$response = $this->httpClient->get($endpoint); |
161
|
|
|
|
162
|
|
|
$responseObject = json_decode($response->body()); |
163
|
|
|
if (!$response->successful()) |
164
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
165
|
|
|
|
166
|
|
|
return $responseObject->responseBody; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Creates a sub account for a merchant. Allowing the merchant split transaction settlement between the main account and one or more sub account(s) |
172
|
|
|
* For $bankCode, check returned object from getBanks() or getBanksWithUSSDShortCode() |
173
|
|
|
* @param string $bankCode |
174
|
|
|
* @param string $accountNumber The account number that should be created as a sub account. |
175
|
|
|
* @param string $email The email tied to the sub account. This email will receive settlement reports for settlements into the sub account. |
176
|
|
|
* @param string|null $currencyCode |
177
|
|
|
* @param string|null $splitPercentage |
178
|
|
|
* @return array |
179
|
|
|
* |
180
|
|
|
* @throws MonnifyFailedRequestException |
181
|
|
|
* |
182
|
|
|
* Once the request is sent, a sub account code will be returned. This sub account code is the unique identifier for that sub account and will be used to reference the sub account in split payment requests. |
183
|
|
|
* <strong>Note: </strong> Currency code and Split Percentage will use the configured default in you .env file if not explicitly provided |
184
|
|
|
* Also, if bank account is not found within the provide bank code a MonnifyFailedRequestException will be thrown |
185
|
|
|
* |
186
|
|
|
*/ |
187
|
|
|
public function createSubAccount(string $bankCode, string $accountNumber, string $email, string $currencyCode = null, string $splitPercentage = null) |
188
|
|
|
{ |
189
|
|
|
$currencyCode = $currencyCode ?? $this->config['default_currency_code']; |
190
|
|
|
$splitPercentage = $splitPercentage ?? $this->config['default_split_percentage']; |
191
|
|
|
|
192
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}sub-accounts"; |
193
|
|
|
|
194
|
|
|
$this->withBasicAuth(); |
195
|
|
|
$response = $this->httpClient->post($endpoint, [[ |
196
|
|
|
'currencyCode' => $currencyCode, |
197
|
|
|
'bankCode' => $bankCode, |
198
|
|
|
'accountNumber' => $accountNumber, |
199
|
|
|
'email' => $email, |
200
|
|
|
'defaultSplitPercentage' => $splitPercentage, |
201
|
|
|
],]); |
202
|
|
|
|
203
|
|
|
$responseObject = json_decode($response->body()); |
204
|
|
|
if (!$response->successful()) |
205
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
206
|
|
|
|
207
|
|
|
return $responseObject->responseBody; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* Creates a sub accounts for a merchant. Allowing the merchant split transaction settlement between the main account and one or more sub account(s) |
213
|
|
|
* For $bankCode, check returned object from getBanks() or getBanksWithUSSDShortCode() |
214
|
|
|
* @param array $accounts is an array of arrays, with each individual array containing the following keys 'currencyCode', 'bankCode', 'accountNumber', 'email', and 'defaultSplitPercentage' |
215
|
|
|
* Note that you can always get the set default currency code as well as default split percentage from the monnify config file with config('monnify.default_currency_code') and config('monnify.default_split_percentage') respectively |
216
|
|
|
* @return array |
217
|
|
|
* |
218
|
|
|
* @throws MonnifyFailedRequestException |
219
|
|
|
* |
220
|
|
|
* Once the request is sent, a sub account code will be returned. This sub account code is the unique identifier for that sub account and will be used to reference the sub account in split payment requests. |
221
|
|
|
* <strong>Note: </strong> If any of the provided details bank account is not found within the corresponding provide bank code a MonnifyFailedRequestException will be thrown |
222
|
|
|
* |
223
|
|
|
*/ |
224
|
|
|
public function createSubAccounts(array $accounts) |
225
|
|
|
{ |
226
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}sub-accounts"; |
227
|
|
|
|
228
|
|
|
$this->withBasicAuth(); |
229
|
|
|
$response = $this->httpClient->post($endpoint, $accounts); |
230
|
|
|
|
231
|
|
|
$responseObject = json_decode($response->body()); |
232
|
|
|
if (!$response->successful()) |
233
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
234
|
|
|
|
235
|
|
|
return $responseObject->responseBody; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Returns a list of sub accounts previously created by the merchant. |
241
|
|
|
* @return array |
242
|
|
|
* |
243
|
|
|
* @throws MonnifyFailedRequestException |
244
|
|
|
* |
245
|
|
|
*/ |
246
|
|
|
public function getSubAccounts() |
247
|
|
|
{ |
248
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}sub-accounts"; |
249
|
|
|
|
250
|
|
|
$this->withBasicAuth(); |
251
|
|
|
$response = $this->httpClient->get($endpoint); |
252
|
|
|
|
253
|
|
|
$responseObject = json_decode($response->body()); |
254
|
|
|
if (!$response->successful()) |
255
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
256
|
|
|
|
257
|
|
|
return $responseObject->responseBody; |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Deletes a merchant's sub account. |
263
|
|
|
* @param string $subAccountCode The unique reference for the sub account |
264
|
|
|
* @return array |
265
|
|
|
* |
266
|
|
|
* @throws MonnifyFailedRequestException |
267
|
|
|
*/ |
268
|
|
|
public function deleteSubAccount(string $subAccountCode) |
269
|
|
|
{ |
270
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}sub-accounts/$subAccountCode"; |
271
|
|
|
|
272
|
|
|
$this->withBasicAuth(); |
273
|
|
|
$response = $this->httpClient->delete($endpoint); |
274
|
|
|
|
275
|
|
|
$responseObject = json_decode($response->body()); |
276
|
|
|
if (!$response->successful()) |
277
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
278
|
|
|
|
279
|
|
|
return $responseObject->responseMessage; |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* Updates the information on an existing sub account for a merchant. |
285
|
|
|
* |
286
|
|
|
* @param string $subAccountCode The unique reference for the sub account |
287
|
|
|
* @param string $bankCode |
288
|
|
|
* @param string $accountNumber |
289
|
|
|
* @param string $email The email tied to the sub account. This email will receive settlement reports for settlements into the sub account. |
290
|
|
|
* @param string|null $currencyCode |
291
|
|
|
* @param string|null $splitPercentage |
292
|
|
|
* @return array |
293
|
|
|
* |
294
|
|
|
* @throws MonnifyFailedRequestException |
295
|
|
|
* |
296
|
|
|
*/ |
297
|
|
|
public function updateSubAccount(string $subAccountCode, string $bankCode, string $accountNumber, string $email, string $currencyCode = null, string $splitPercentage = null) |
298
|
|
|
{ |
299
|
|
|
$currencyCode = $currencyCode ?? $this->config['default_currency_code']; |
300
|
|
|
$splitPercentage = $splitPercentage ?? $this->config['default_split_percentage']; |
301
|
|
|
|
302
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}sub-accounts"; |
303
|
|
|
|
304
|
|
|
$this->withBasicAuth(); |
305
|
|
|
$response = $this->httpClient->put($endpoint, [ |
306
|
|
|
'subAccountCode' => $subAccountCode, |
307
|
|
|
'currencyCode' => $currencyCode, |
308
|
|
|
'bankCode' => $bankCode, |
309
|
|
|
'accountNumber' => $accountNumber, |
310
|
|
|
'email' => $email, |
311
|
|
|
'defaultSplitPercentage' => $splitPercentage, |
312
|
|
|
]); |
313
|
|
|
|
314
|
|
|
$responseObject = json_decode($response->body()); |
315
|
|
|
if (!$response->successful()) |
316
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
317
|
|
|
|
318
|
|
|
return $responseObject->responseBody; |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* This returns all transactions done by a merchant. |
324
|
|
|
* |
325
|
|
|
* @param array $queryParams |
326
|
|
|
* @return object |
327
|
|
|
* |
328
|
|
|
* @throws MonnifyFailedRequestException |
329
|
|
|
* |
330
|
|
|
* Kindly check here for query parameters keys |
331
|
|
|
* @link https://docs.teamapt.com/display/MON/Get+All+Transactions |
332
|
|
|
*/ |
333
|
|
|
public function getAllTransactions(array $queryParams) |
334
|
|
|
{ |
335
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}transactions/search?" . http_build_query($queryParams, '', '&'); |
336
|
|
|
|
337
|
|
|
$this->withOAuth2(); |
338
|
|
|
$response = $this->httpClient->get($endpoint); |
339
|
|
|
|
340
|
|
|
$responseObject = json_decode($response->body()); |
341
|
|
|
if (!$response->successful()) |
342
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
343
|
|
|
|
344
|
|
|
return $responseObject->responseBody; |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
|
348
|
|
|
/** |
349
|
|
|
* Once an account number has been reserved for a customer, the customer can make payment by initiating a transfer to that account number at any time. Once the transfer hits the partner bank, we will notify you with the transfer details along with the accountReference you specified when reserving the account. |
350
|
|
|
* |
351
|
|
|
* @param string $accountReference Your unique reference used to identify this reserved account |
352
|
|
|
* @param string $accountName The name you want to be attached to the reserved account. This will be displayed during name enquiry |
353
|
|
|
* @param string $customerEmail Email address of the customer who the account is being reserved for. This is the unique identifier for each customer. |
354
|
|
|
* @param string $customerName Full name of the customer who the account is being reserved for |
355
|
|
|
* @param string|null $customerBvn BVN of the customer the account is being reserved for. Although this field is not mandated, it is advised that it is supplied. Please note that there could be low limits on the reserved account in future, if BVN is not supplied. |
356
|
|
|
* @param string|null $currencyCode |
357
|
|
|
* @param MonnifyIncomeSplitConfig|null $incomeSplitConfig |
358
|
|
|
* @param bool $restrictPaymentSource |
359
|
|
|
* @param MonnifyAllowedPaymentSources $allowedPaymentSources |
360
|
|
|
* @return object |
361
|
|
|
* |
362
|
|
|
* @throws MonnifyInvalidParameterException |
363
|
|
|
* @throws MonnifyFailedRequestException |
364
|
|
|
* @link https://docs.teamapt.com/display/MON/Reserving+An+Account |
365
|
|
|
*/ |
366
|
|
|
public function reserveAccount(string $accountReference, string $accountName, string $customerEmail, string $customerName = null, string $customerBvn = null, string $currencyCode = null, bool $restrictPaymentSource = false, MonnifyAllowedPaymentSources $allowedPaymentSources = null, MonnifyIncomeSplitConfig $incomeSplitConfig = null) |
367
|
|
|
{ |
368
|
|
|
if ($restrictPaymentSource && is_null($allowedPaymentSources)) |
369
|
|
|
throw new MonnifyInvalidParameterException("Allowed Payment Sources can't be null if payment source is restricted"); |
370
|
|
|
|
371
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}bank-transfer/reserved-accounts"; |
372
|
|
|
$requestBody = [ |
373
|
|
|
"accountReference" => $accountReference, |
374
|
|
|
"accountName" => $accountName, |
375
|
|
|
"currencyCode" => $currencyCode ?? $this->config['default_currency_code'], |
376
|
|
|
"contractCode" => $this->config['contract_code'], |
377
|
|
|
"customerEmail" => $customerEmail, |
378
|
|
|
"restrictPaymentSource" => $restrictPaymentSource, |
379
|
|
|
]; |
380
|
|
|
|
381
|
|
|
if ((!is_null($customerName)) && (!empty(trim($customerName)))) |
382
|
|
|
$requestBody['customerName'] = $customerName; |
383
|
|
|
|
384
|
|
|
if ((!is_null($customerBvn)) && (!empty(trim($customerBvn)))) |
385
|
|
|
$requestBody['customerBvn'] = $customerBvn; |
386
|
|
|
|
387
|
|
|
if (!is_null($allowedPaymentSources)) |
388
|
|
|
$requestBody['allowedPaymentSources'] = $allowedPaymentSources->toArray(); |
389
|
|
|
|
390
|
|
|
if (!is_null($incomeSplitConfig)) |
391
|
|
|
$requestBody['incomeSplitConfig'] = $incomeSplitConfig->toArray(); |
392
|
|
|
|
393
|
|
|
$this->withOAuth2(); |
394
|
|
|
$response = $this->httpClient->post($endpoint, $requestBody); |
395
|
|
|
|
396
|
|
|
|
397
|
|
|
$responseObject = json_decode($response->body()); |
398
|
|
|
if (!$response->successful()) |
399
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
400
|
|
|
|
401
|
|
|
return $responseObject->responseBody; |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* If you want to get the details of a reserved account, you can initiate a GET request to the endpoint below and we will return all the details attached to that account Reference. |
407
|
|
|
* |
408
|
|
|
* @param string $accountReference Your unique reference used to identify this reserved account |
409
|
|
|
* @return object |
410
|
|
|
* |
411
|
|
|
* @throws MonnifyFailedRequestException |
412
|
|
|
* @link https://docs.teamapt.com/display/MON/Get+Reserved+Account+Details |
413
|
|
|
*/ |
414
|
|
|
public function getReservedAccountDetails(string $accountReference) |
415
|
|
|
{ |
416
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}bank-transfer/reserved-accounts/$accountReference"; |
417
|
|
|
|
418
|
|
|
$this->withOAuth2(); |
419
|
|
|
$response = $this->httpClient->get($endpoint); |
420
|
|
|
|
421
|
|
|
|
422
|
|
|
$responseObject = json_decode($response->body()); |
423
|
|
|
if (!$response->successful()) |
424
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
425
|
|
|
|
426
|
|
|
return $responseObject->responseBody; |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
|
430
|
|
|
/** |
431
|
|
|
* You can update income splitting config for a reserved account using the endpoint below. |
432
|
|
|
* |
433
|
|
|
* @param string $accountReference Your unique reference used to identify this reserved account |
434
|
|
|
* @param MonnifyIncomeSplitConfig $incomeSplitConfig |
435
|
|
|
* @return object |
436
|
|
|
* |
437
|
|
|
* @throws MonnifyFailedRequestException |
438
|
|
|
* @link https://docs.teamapt.com/display/MON/Updating+Split+Config+for+Reserved+Account |
439
|
|
|
*/ |
440
|
|
|
public function updateReservedAccountSplitConfig(string $accountReference, MonnifyIncomeSplitConfig $incomeSplitConfig) |
441
|
|
|
{ |
442
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}bank-transfer/reserved-accounts/update-income-split-config/$accountReference"; |
443
|
|
|
|
444
|
|
|
$this->withOAuth2(); |
445
|
|
|
$response = $this->httpClient->put($endpoint, $incomeSplitConfig->toArray()); |
446
|
|
|
|
447
|
|
|
|
448
|
|
|
$responseObject = json_decode($response->body()); |
449
|
|
|
if (!$response->successful()) |
450
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
451
|
|
|
|
452
|
|
|
return $responseObject->responseBody; |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
|
456
|
|
|
/** |
457
|
|
|
* You can get a paginated list of transactions processed to a reserved account by making a GET Request to the endpoint below and by specifying the accountReference as a query parameter. You can also specify the page number and size (number of transactions) you want returned per page. |
458
|
|
|
* |
459
|
|
|
* @param string $accountReference Your unique reference used to identify this reserved account |
460
|
|
|
* @param int $page The page of data you want returned by Monnify (Starts from 0) |
461
|
|
|
* @param int $size The number of records you want returned in a page. |
462
|
|
|
* @return object |
463
|
|
|
* |
464
|
|
|
* @throws MonnifyFailedRequestException |
465
|
|
|
* @link https://docs.teamapt.com/display/MON/Getting+all+transactions+on+a+reserved+account |
466
|
|
|
*/ |
467
|
|
|
public function getAllTransactionsForReservedAccount(string $accountReference, int $page = 0, int $size = 10) |
468
|
|
|
{ |
469
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}bank-transfer/reserved-accounts/transactions?accountReference=$accountReference&page=$page&size=$size"; |
470
|
|
|
|
471
|
|
|
$this->withOAuth2(); |
472
|
|
|
$response = $this->httpClient->get($endpoint); |
473
|
|
|
|
474
|
|
|
|
475
|
|
|
$responseObject = json_decode($response->body()); |
476
|
|
|
if (!$response->successful()) |
477
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
478
|
|
|
|
479
|
|
|
return $responseObject->responseBody; |
480
|
|
|
} |
481
|
|
|
|
482
|
|
|
|
483
|
|
|
/** |
484
|
|
|
* You can delete a reserved account by initiating a DELETE request to the endpoint below. We will immediately deallocate the account. |
485
|
|
|
* Please note this action cannot be reversed!! |
486
|
|
|
* |
487
|
|
|
* @param string $accountNumber The virtual account number generated for the accountReference (Reserved account number) |
488
|
|
|
* @return object |
489
|
|
|
* |
490
|
|
|
* @throws MonnifyFailedRequestException |
491
|
|
|
* @link https://docs.teamapt.com/display/MON/Deallocating+a+reserved+account |
492
|
|
|
*/ |
493
|
|
|
public function deallocateReservedAccount(string $accountNumber) |
494
|
|
|
{ |
495
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}bank-transfer/reserved-accounts/$accountNumber"; |
496
|
|
|
|
497
|
|
|
$this->withOAuth2(); |
498
|
|
|
$response = $this->httpClient->delete($endpoint); |
499
|
|
|
|
500
|
|
|
|
501
|
|
|
$responseObject = json_decode($response->body()); |
502
|
|
|
if (!$response->successful()) |
503
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
504
|
|
|
|
505
|
|
|
return $responseObject->responseBody; |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
|
509
|
|
|
/** |
510
|
|
|
* This API enables you restrict accounts that can fund a reserved account. This most used for a wallet system where you want only the owner of a reserved account to fund the reserved account. |
511
|
|
|
* |
512
|
|
|
* You can explicitly specify account numbers, or specify one or more account names. |
513
|
|
|
* |
514
|
|
|
* <strong>How are specified rules applied?</strong> |
515
|
|
|
* If only account numbers are specified, funding of account will be restricted to specified account numbers. |
516
|
|
|
* If only account names are specified, funding of account will be restricted to specified account names. |
517
|
|
|
* If both account numbers and account names are specified, funding will be permitted when either of the two rules match, i.e. source account number matches specified account numbers or source account name matches specified account name. |
518
|
|
|
* Account Name Matching Rule |
519
|
|
|
* |
520
|
|
|
* Matching of source account name is dynamic, such that if CIROMA CHUKWUMA ADEKUNLE is the specified account name, funding of accounts will be permitted from accounts with name that has AT LEAST TWO words from the specified name, and in any order. |
521
|
|
|
* |
522
|
|
|
* @param string $accountReference Your unique reference used to identify this reserved account |
523
|
|
|
* @param MonnifyAllowedPaymentSources $allowedPaymentSources |
524
|
|
|
* @return object |
525
|
|
|
* |
526
|
|
|
* @throws MonnifyFailedRequestException |
527
|
|
|
* @link https://docs.teamapt.com/display/MON/Getting+all+transactions+on+a+reserved+account |
528
|
|
|
*/ |
529
|
|
|
public function sourceAccountRestriction(string $accountReference, MonnifyAllowedPaymentSources $allowedPaymentSources) |
530
|
|
|
{ |
531
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}bank-transfer/reserved-accounts/update-payment-source-filter/$accountReference"; |
532
|
|
|
|
533
|
|
|
$this->withOAuth2(); |
534
|
|
|
$response = $this->httpClient->put($endpoint, [ |
535
|
|
|
"restrictPaymentSource" => true, |
536
|
|
|
"allowedPaymentSources" => $allowedPaymentSources->toArray() |
537
|
|
|
]); |
538
|
|
|
|
539
|
|
|
|
540
|
|
|
$responseObject = json_decode($response->body()); |
541
|
|
|
if (!$response->successful()) |
542
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
543
|
|
|
|
544
|
|
|
return $responseObject->responseBody; |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
|
548
|
|
|
/** |
549
|
|
|
* Allows you initialize a transaction on Monnify and returns a checkout URL which you can load within a browser to display the payment form to your customer. |
550
|
|
|
* |
551
|
|
|
* @param float $amount The amount to be paid by the customer |
552
|
|
|
* @param string $customerName Full name of the customer |
553
|
|
|
* @param string $customerEmail Email address of the customer |
554
|
|
|
* @param string $paymentReference Merchant's Unique reference for the transaction. |
555
|
|
|
* @param string $paymentDescription Description for the transaction. Will be returned as part of the account name on name enquiry for transfer payments. |
556
|
|
|
* @param string $redirectUrl A URL which user will be redirected to, on completion of the payment. |
557
|
|
|
* @param MonnifyPaymentMethods $monnifyPaymentMethods |
558
|
|
|
* @param MonnifyIncomeSplitConfig $incomeSplitConfig |
559
|
|
|
* @param string|null $currencyCode |
560
|
|
|
* @return array |
561
|
|
|
* |
562
|
|
|
* @throws MonnifyFailedRequestException |
563
|
|
|
* @link https://docs.teamapt.com/display/MON/Initialize+Transaction |
564
|
|
|
*/ |
565
|
|
|
public function initializeTransaction(float $amount, string $customerName, string $customerEmail, string $paymentReference, string $paymentDescription, string $redirectUrl, MonnifyPaymentMethods $monnifyPaymentMethods, MonnifyIncomeSplitConfig $incomeSplitConfig = null, string $currencyCode = null) |
566
|
|
|
{ |
567
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}merchant/transactions/init-transaction"; |
568
|
|
|
|
569
|
|
|
$this->withBasicAuth(); |
570
|
|
|
$formData = [ |
571
|
|
|
"amount" => $amount, |
572
|
|
|
"customerName" => trim($customerName), |
573
|
|
|
"customerEmail" => $customerEmail, |
574
|
|
|
"paymentReference" => $paymentReference, |
575
|
|
|
"paymentDescription" => trim($paymentDescription), |
576
|
|
|
"currencyCode" => $currencyCode ?? $this->config['default_currency_code'], |
577
|
|
|
"contractCode" => $this->config['contract_code'], |
578
|
|
|
"redirectUrl" => trim($redirectUrl), |
579
|
|
|
"paymentMethods" => $monnifyPaymentMethods->toArray(), |
580
|
|
|
]; |
581
|
|
|
if ($incomeSplitConfig !== null) |
582
|
|
|
$formData["incomeSplitConfig"] = $incomeSplitConfig->toArray(); |
583
|
|
|
|
584
|
|
|
$response = $this->httpClient->post($endpoint, $formData); |
585
|
|
|
|
586
|
|
|
$responseObject = json_decode($response->body()); |
587
|
|
|
if (!$response->successful()) |
588
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
589
|
|
|
|
590
|
|
|
return $responseObject->responseBody; |
591
|
|
|
} |
592
|
|
|
|
593
|
|
|
|
594
|
|
|
/** |
595
|
|
|
* When Monnify sends transaction notifications, we add a transaction hash for security reasons. We expect you to try to recreate the transaction hash and only honor the notification if it matches. |
596
|
|
|
* |
597
|
|
|
* To calculate the hash value, concatenate the following parameters in the request body and generate a hash using the SHA512 algorithm: |
598
|
|
|
* |
599
|
|
|
* @param string $paymentReference Unique reference generated by the merchant for each transaction. However, will be the same as transactionReference for reserved accounts. |
600
|
|
|
* @param mixed $amountPaid The amount that was paid by the customer |
601
|
|
|
* @param string $paidOn Date and Time when payment happened in the format dd/mm/yyyy hh:mm:ss |
602
|
|
|
* @param string $transactionReference Unique transaction reference generated by Monnify for each transaction |
603
|
|
|
* @return string Hash of successful transaction |
604
|
|
|
* |
605
|
|
|
* @link https://docs.teamapt.com/display/MON/Calculating+the+Transaction+Hash |
606
|
|
|
*/ |
607
|
|
|
public function calculateTransactionHash(string $paymentReference, $amountPaid, string $paidOn, string $transactionReference) |
608
|
|
|
{ |
609
|
|
|
$clientSK = $this->config['secret_key']; |
610
|
|
|
return hash('sha512', "$clientSK|$paymentReference|$amountPaid|$paidOn|$transactionReference"); |
611
|
|
|
} |
612
|
|
|
|
613
|
|
|
public function calculateTransactionHashFix(string $paymentReference, $amountPaid, string $paidOn, string $transactionReference) |
614
|
|
|
{ |
615
|
|
|
$clientSK = $this->config['secret_key']; |
616
|
|
|
return hash('sha512', "$clientSK|$paymentReference|$amountPaid|$paidOn|$transactionReference"); |
617
|
|
|
} |
618
|
|
|
|
619
|
|
|
|
620
|
|
|
/** |
621
|
|
|
* We highly recommend that when you receive a notification from us, even after checking to ensure the hash values match, |
622
|
|
|
* you should initiate a get transaction status request to us with the transactionReference to confirm the actual status of that transaction before updating the records on your database. |
623
|
|
|
* |
624
|
|
|
* @param string $transactions Unique transaction reference generated by Monnify for each transaction |
625
|
|
|
* @return object |
626
|
|
|
* |
627
|
|
|
* @throws MonnifyFailedRequestException |
628
|
|
|
* @link https://docs.teamapt.com/display/MON/Get+Transaction+Status |
629
|
|
|
*/ |
630
|
|
|
public function getTransactionStatus(string $transactions) |
631
|
|
|
{ |
632
|
|
|
$endpoint = "{$this->baseUrl}{$this->v2}transactions/$transactions/"; |
633
|
|
|
|
634
|
|
|
$this->withOAuth2(); |
635
|
|
|
$response = $this->httpClient->get($endpoint); |
636
|
|
|
|
637
|
|
|
$responseObject = json_decode($response->body()); |
638
|
|
|
if (!$response->successful()) |
639
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
640
|
|
|
|
641
|
|
|
return $responseObject->responseBody; |
642
|
|
|
} |
643
|
|
|
|
644
|
|
|
|
645
|
|
|
/** |
646
|
|
|
* Allows you get virtual account details for a transaction using the transactionReference of an initialized transaction. |
647
|
|
|
* This is useful if you want to control the payment interface. |
648
|
|
|
* There are a lot of UX considerations to keep in mind if you choose to do this so we recommend you read this @link https://docs.teamapt.com/display/MON/Optimizing+Your+User+Experience. |
649
|
|
|
* |
650
|
|
|
* @param string $transactionReference |
651
|
|
|
* @param string $bankCode |
652
|
|
|
* @return array |
653
|
|
|
* |
654
|
|
|
* @throws MonnifyFailedRequestException |
655
|
|
|
* @link https://docs.teamapt.com/display/MON/Pay+with+Bank+Transfer |
656
|
|
|
*/ |
657
|
|
|
public function payWithBankTransfer(string $transactionReference, string $bankCode) |
658
|
|
|
{ |
659
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}merchant/bank-transfer/init-payment"; |
660
|
|
|
|
661
|
|
|
$this->withBasicAuth(); |
662
|
|
|
$response = $this->httpClient->post($endpoint, [ |
663
|
|
|
"transactionReference" => $transactionReference, |
664
|
|
|
"bankCode" => trim($bankCode), |
665
|
|
|
]); |
666
|
|
|
|
667
|
|
|
$responseObject = json_decode($response->body()); |
668
|
|
|
if (!$response->successful()) |
669
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
670
|
|
|
|
671
|
|
|
return $responseObject->responseBody; |
672
|
|
|
} |
673
|
|
|
|
674
|
|
|
|
675
|
|
|
/** |
676
|
|
|
* To initiate a single transfer, you will need to send a request to the endpoint below: |
677
|
|
|
* |
678
|
|
|
* If the merchant does not have Two Factor Authentication (2FA) enabled, the transaction will be processed instantly and the response will be as follows: |
679
|
|
|
* |
680
|
|
|
* If the merchant has Two Factor Authentication (2FA) enabled, a One Time Password (OTP) will be sent to the designated email address(es). That OTP will need to be supplied via the VALIDATE OTP REQUEST before the transaction can be approved. If 2FA is enabled, |
681
|
|
|
* |
682
|
|
|
* @param float $amount |
683
|
|
|
* @param string $reference |
684
|
|
|
* @param string $narration |
685
|
|
|
* @param MonnifyBankAccount $bankAccount |
686
|
|
|
* @param string|null $currencyCode |
687
|
|
|
* @return array |
688
|
|
|
* |
689
|
|
|
* @throws MonnifyFailedRequestException |
690
|
|
|
* |
691
|
|
|
* @see https://docs.teamapt.com/display/MON/Initiate+Transfer |
692
|
|
|
*/ |
693
|
|
|
public function initiateTransferSingle(float $amount, string $reference, string $narration, MonnifyBankAccount $bankAccount, string $currencyCode = null) |
694
|
|
|
{ |
695
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}disbursements/single"; |
696
|
|
|
|
697
|
|
|
$this->withBasicAuth(); |
698
|
|
|
$response = $this->httpClient->post($endpoint, [ |
699
|
|
|
"amount" => $amount, |
700
|
|
|
"reference" => trim($reference), |
701
|
|
|
"narration" => trim($narration), |
702
|
|
|
"bankCode" => $bankAccount->getBankCode(), |
703
|
|
|
"accountNumber" => $bankAccount->getAccountNumber(), |
704
|
|
|
"currency" => $currencyCode ?? $this->config['default_currency_code'], |
705
|
|
|
"walletId" => $this->config['wallet_id'] |
706
|
|
|
]); |
707
|
|
|
|
708
|
|
|
$responseObject = json_decode($response->body()); |
709
|
|
|
if (!$response->successful()) |
710
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
711
|
|
|
|
712
|
|
|
return $responseObject->initiateTransferSingle; |
713
|
|
|
} |
714
|
|
|
|
715
|
|
|
|
716
|
|
|
/** |
717
|
|
|
* To initiate a single transfer, you will need to send a request to the endpoint below: |
718
|
|
|
* |
719
|
|
|
* If the merchant does not have Two Factor Authentication (2FA) enabled, the transaction will be processed instantly and the response will be as follows: |
720
|
|
|
* |
721
|
|
|
* If the merchant has Two Factor Authentication (2FA) enabled, a One Time Password (OTP) will be sent to the designated email address(es). That OTP will need to be supplied via the VALIDATE OTP REQUEST before the transaction can be approved. If 2FA is enabled, |
722
|
|
|
* |
723
|
|
|
* |
724
|
|
|
* @param MonnifyTransaction $monnifyTransaction Transaction Object |
725
|
|
|
* @return array |
726
|
|
|
* |
727
|
|
|
* @throws MonnifyFailedRequestException |
728
|
|
|
* @see https://docs.teamapt.com/display/MON/Initiate+Transfer |
729
|
|
|
*/ |
730
|
|
|
public function initiateTransferSingleWithMonnifyTransaction(MonnifyTransaction $monnifyTransaction) |
731
|
|
|
{ |
732
|
|
|
return $this->initiateTransferSingle($monnifyTransaction->getAmount(), $monnifyTransaction->getReference(), $monnifyTransaction->getNarration(), $monnifyTransaction->getBankAccount(), $monnifyTransaction->getCurrencyCode()); |
733
|
|
|
} |
734
|
|
|
|
735
|
|
|
|
736
|
|
|
/** |
737
|
|
|
* To initiate a single transfer, you will need to send a request to the endpoint below: |
738
|
|
|
* Bulk transfers allows you send a single request with a list of disbursements you want to be processed. Below is a sample request for initiating a bulk transfer |
739
|
|
|
* |
740
|
|
|
* If the merchant does not have Two Factor Authentication (2FA) enabled, the transaction will be processed instantly and the response will be as follows: |
741
|
|
|
* |
742
|
|
|
* If the merchant has Two Factor Authentication (2FA) enabled, a One Time Password (OTP) will be sent to the designated email address(es). That OTP will need to be supplied via the VALIDATE OTP REQUEST before the transaction can be approved. If 2FA is enabled, |
743
|
|
|
* |
744
|
|
|
* @param string $title |
745
|
|
|
* @param string $batchReference The unique reference for the entire batch of transactions being sent. |
746
|
|
|
* @param string $narration The Narration for the transactions being processed |
747
|
|
|
* @param MonnifyOnFailureValidate $onFailureValidate Used to determine how Monnify should handle failed transaction validations in a batch. The two options are MonnifyOnFailureValidate::BREAK() & MonnifyOnFailureValidate::CONTINUE(). Use MonnifyOnFailureValidate::BREAK() to tell Monnify to reject the entire batch and use MonnifyOnFailureValidate::CONTINUE() to tell Monnify to process the valid transactions. |
748
|
|
|
* @param int $notificationInterval Used to determine how often Monnify should notify the merchant of progress when processing a batch transfer. The options are 10, 20, 50 and 100 and they represent percentages. i.e. 20 means notify me at intervals of 20% (20%, 40%, 60%, 80% ,100%). |
749
|
|
|
* @param MonnifyTransactionList $transactionList |
750
|
|
|
* @return array |
751
|
|
|
* |
752
|
|
|
* @throws MonnifyFailedRequestException |
753
|
|
|
* @see https://docs.teamapt.com/display/MON/Initiate+Transfer |
754
|
|
|
*/ |
755
|
|
|
public function initiateTransferBulk(string $title, string $batchReference, string $narration, MonnifyOnFailureValidate $onFailureValidate, int $notificationInterval, MonnifyTransactionList $transactionList) |
756
|
|
|
{ |
757
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}disbursements/batch"; |
758
|
|
|
|
759
|
|
|
$this->withBasicAuth(); |
760
|
|
|
$response = $this->httpClient->post($endpoint, [ |
761
|
|
|
"title" => $title, |
762
|
|
|
"batchReference" => trim($batchReference), |
763
|
|
|
"narration" => trim($narration), |
764
|
|
|
"walletId" => $this->config['wallet_id'], |
765
|
|
|
"onValidationFailure" => "$onFailureValidate", |
766
|
|
|
"notificationInterval" => $notificationInterval, |
767
|
|
|
"transactionList" => $transactionList->toArray() |
768
|
|
|
]); |
769
|
|
|
|
770
|
|
|
$responseObject = json_decode($response->body()); |
771
|
|
|
if (!$response->successful()) |
772
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
773
|
|
|
|
774
|
|
|
return $responseObject->responseBody; |
775
|
|
|
} |
776
|
|
|
|
777
|
|
|
/** |
778
|
|
|
* @param string $authorizationCode The One Time Password sent to the specified email to be used to authenticate the transaction |
779
|
|
|
* @param string $reference The unique reference for a transaction. Also to be specified for each transaction in a bulk transaction request. |
780
|
|
|
* @param string $path |
781
|
|
|
* @return object |
782
|
|
|
* |
783
|
|
|
* @throws MonnifyFailedRequestException |
784
|
|
|
* @link https://docs.teamapt.com/pages/viewpage.action?pageId=4587995 |
785
|
|
|
*/ |
786
|
|
|
private function authorizeTransfer2FA(string $authorizationCode, string $reference, string $path) |
787
|
|
|
{ |
788
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}disbursements/$path/validate-otp"; |
789
|
|
|
|
790
|
|
|
$this->withBasicAuth(); |
791
|
|
|
$response = $this->httpClient->post($endpoint, [ |
792
|
|
|
"authorizationCode" => $authorizationCode, |
793
|
|
|
"reference" => trim($reference), |
794
|
|
|
]); |
795
|
|
|
|
796
|
|
|
$responseObject = json_decode($response->body()); |
797
|
|
|
if (!$response->successful()) |
798
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
799
|
|
|
|
800
|
|
|
return $responseObject->responseBody; |
801
|
|
|
} |
802
|
|
|
|
803
|
|
|
/** |
804
|
|
|
* To authorize a single transfer, you will need to send a request to using this |
805
|
|
|
* |
806
|
|
|
* @param string $authorizationCode The One Time Password sent to the specified email to be used to authenticate the transaction |
807
|
|
|
* @param string $reference The unique reference for a transaction. Also to be specified for each transaction in a bulk transaction request. |
808
|
|
|
* @return object |
809
|
|
|
* |
810
|
|
|
* @throws MonnifyFailedRequestException |
811
|
|
|
* @link https://docs.teamapt.com/pages/viewpage.action?pageId=4587995 |
812
|
|
|
*/ |
813
|
|
|
public function authorizeSingleTransfer2FA(string $authorizationCode, string $reference) |
814
|
|
|
{ |
815
|
|
|
return $this->authorizeTransfer2FA($authorizationCode, $reference, 'single'); |
816
|
|
|
} |
817
|
|
|
|
818
|
|
|
/** |
819
|
|
|
* To authorize a bulk transfer, you will need to send a request to using this |
820
|
|
|
* |
821
|
|
|
* @param string $authorizationCode The One Time Password sent to the specified email to be used to authenticate the transaction |
822
|
|
|
* @param string $reference The unique reference for a transaction. Also to be specified for each transaction in a bulk transaction request. |
823
|
|
|
* @return object |
824
|
|
|
* |
825
|
|
|
* @throws MonnifyFailedRequestException |
826
|
|
|
* @link https://docs.teamapt.com/pages/viewpage.action?pageId=4587995 |
827
|
|
|
*/ |
828
|
|
|
public function authorizeBulkTransfer2FA(string $authorizationCode, string $reference) |
829
|
|
|
{ |
830
|
|
|
return $this->authorizeTransfer2FA($authorizationCode, $reference, 'batch'); |
831
|
|
|
} |
832
|
|
|
|
833
|
|
|
|
834
|
|
|
/** |
835
|
|
|
* @param string $reference The unique reference for a transaction. Also to be specified for each transaction in a bulk transaction request. |
836
|
|
|
* @param string $path |
837
|
|
|
* @return object |
838
|
|
|
* |
839
|
|
|
* @throws MonnifyFailedRequestException |
840
|
|
|
* @link https://docs.teamapt.com/display/MON/Get+Transfer+Details |
841
|
|
|
*/ |
842
|
|
|
private function getTransferDetails(string $reference, string $path) |
843
|
|
|
{ |
844
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}disbursements/$path/summary?reference=$reference"; |
845
|
|
|
|
846
|
|
|
$this->withBasicAuth(); |
847
|
|
|
$response = $this->httpClient->get($endpoint); |
848
|
|
|
|
849
|
|
|
$responseObject = json_decode($response->body()); |
850
|
|
|
if (!$response->successful()) |
851
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
852
|
|
|
|
853
|
|
|
return $responseObject->responseBody; |
854
|
|
|
} |
855
|
|
|
|
856
|
|
|
|
857
|
|
|
/** |
858
|
|
|
* Single Transfers |
859
|
|
|
* To get the details of a single transfer |
860
|
|
|
* |
861
|
|
|
* @param string $reference The unique reference for a transaction. Also to be specified for each transaction in a bulk transaction request. |
862
|
|
|
* @return object |
863
|
|
|
* |
864
|
|
|
* @throws MonnifyFailedRequestException |
865
|
|
|
* @link https://docs.teamapt.com/display/MON/Get+Transfer+Details |
866
|
|
|
*/ |
867
|
|
|
public function getSingleTransferDetails(string $reference) |
868
|
|
|
{ |
869
|
|
|
return $this->getTransferDetails($reference, 'single'); |
870
|
|
|
} |
871
|
|
|
|
872
|
|
|
|
873
|
|
|
/** |
874
|
|
|
* Bulk Transfers |
875
|
|
|
* To get the details of a bulk transfer |
876
|
|
|
* |
877
|
|
|
* @param string $batchReference The unique reference for a transaction. Also to be specified for each transaction in a bulk transaction request. |
878
|
|
|
* @return object |
879
|
|
|
* |
880
|
|
|
* @throws MonnifyFailedRequestException |
881
|
|
|
* @link https://docs.teamapt.com/display/MON/Get+Transfer+Details |
882
|
|
|
*/ |
883
|
|
|
public function getBulkTransferDetails(string $batchReference) |
884
|
|
|
{ |
885
|
|
|
return $this->getTransferDetails($batchReference, 'batch'); |
886
|
|
|
} |
887
|
|
|
|
888
|
|
|
|
889
|
|
|
/** |
890
|
|
|
* This allows you get a paginated list of all transactions in a bulk transfer batch and their statuses. |
891
|
|
|
* |
892
|
|
|
* @param string $batchReference The unique reference for the entire batch of transactions being sent. |
893
|
|
|
* @param int $pageNo A number specifying what page of transfers to be retrieved. Minimum value is 0, and defaults to 0 if not specified. |
894
|
|
|
* @param int $pageSize A number specifying size of each transfer page. Minimum value is 1, and defaults to 10 if not specified. |
895
|
|
|
* @return object |
896
|
|
|
* |
897
|
|
|
* @throws MonnifyFailedRequestException |
898
|
|
|
* @link https://docs.teamapt.com/display/MON/Get+Bulk+Transfer+Transactions |
899
|
|
|
*/ |
900
|
|
|
public function getBulkTransferTransactions(string $batchReference, int $pageNo = 0, int $pageSize = 10) |
901
|
|
|
{ |
902
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}disbursements/bulk/$batchReference/transactions?pageNo=$pageNo&pageSize=$pageSize"; |
903
|
|
|
$this->withBasicAuth(); |
904
|
|
|
$response = $this->httpClient->get($endpoint); |
905
|
|
|
|
906
|
|
|
$responseObject = json_decode($response->body()); |
907
|
|
|
if (!$response->successful()) |
908
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
909
|
|
|
|
910
|
|
|
return $responseObject->responseBody; |
911
|
|
|
} |
912
|
|
|
|
913
|
|
|
|
914
|
|
|
/** |
915
|
|
|
* This allows you get a paginated list of all transactions in a bulk transfer batch and their statuses. |
916
|
|
|
* |
917
|
|
|
* @param string $path |
918
|
|
|
* @param int $pageNo A number specifying what page of transfers to be retrieved. Minimum value is 0, and defaults to 0 if not specified. |
919
|
|
|
* @param int $pageSize A number specifying size of each transfer page. Minimum value is 1, and defaults to 10 if not specified. |
920
|
|
|
* @return object |
921
|
|
|
* |
922
|
|
|
* @throws MonnifyFailedRequestException |
923
|
|
|
* @link https://docs.teamapt.com/display/MON/List+All+Transfers |
924
|
|
|
*/ |
925
|
|
|
private function listAllTransfers(string $path, int $pageNo = 0, int $pageSize = 10) |
926
|
|
|
{ |
927
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}disbursements/$path/transactions?pageNo=$pageNo&pageSize=$pageSize"; |
928
|
|
|
|
929
|
|
|
$this->withBasicAuth(); |
930
|
|
|
$response = $this->httpClient->get($endpoint); |
931
|
|
|
|
932
|
|
|
$responseObject = json_decode($response->body()); |
933
|
|
|
if (!$response->successful()) |
934
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
935
|
|
|
|
936
|
|
|
return $responseObject->responseBody; |
937
|
|
|
} |
938
|
|
|
|
939
|
|
|
|
940
|
|
|
/** |
941
|
|
|
* Single Transfers |
942
|
|
|
* To get a list of all single transfers |
943
|
|
|
* |
944
|
|
|
* @param int $pageNo |
945
|
|
|
* @param int $pageSize |
946
|
|
|
* @return object |
947
|
|
|
* |
948
|
|
|
* @throws MonnifyFailedRequestException |
949
|
|
|
* @link https://docs.teamapt.com/display/MON/Get+Transfer+Details |
950
|
|
|
*/ |
951
|
|
|
public function getSingleTransferTransactions(int $pageNo = 0, int $pageSize = 10) |
952
|
|
|
{ |
953
|
|
|
return $this->listAllTransfers('single', $pageNo, $pageSize); |
954
|
|
|
} |
955
|
|
|
|
956
|
|
|
|
957
|
|
|
/** |
958
|
|
|
* Bulk Transfers |
959
|
|
|
* To get a list of all bulk transfers |
960
|
|
|
* |
961
|
|
|
* @param int $pageNo |
962
|
|
|
* @param int $pageSize |
963
|
|
|
* @return object |
964
|
|
|
* |
965
|
|
|
* @throws MonnifyFailedRequestException |
966
|
|
|
* @link https://docs.teamapt.com/display/MON/Get+Transfer+Details |
967
|
|
|
*/ |
968
|
|
|
public function getAllBulkTransferTransactions(int $pageNo = 0, int $pageSize = 10) |
969
|
|
|
{ |
970
|
|
|
return $this->listAllTransfers('bulk', $pageNo, $pageSize); |
971
|
|
|
} |
972
|
|
|
|
973
|
|
|
|
974
|
|
|
/** |
975
|
|
|
* This allows you check if an account number is a valid NUBAN, get the account name if valid. |
976
|
|
|
* |
977
|
|
|
* @param MonnifyBankAccount $bankAccount |
978
|
|
|
* @return mixed |
979
|
|
|
* @throws MonnifyFailedRequestException |
980
|
|
|
* |
981
|
|
|
* @link https://docs.teamapt.com/display/MON/Validate+Bank+Account |
982
|
|
|
*/ |
983
|
|
|
public function validateBankAccount(MonnifyBankAccount $bankAccount) |
984
|
|
|
{ |
985
|
|
|
|
986
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}disbursements/account/validate?accountNumber={$bankAccount->getAccountNumber()}&bankCode={$bankAccount->getBankCode()}"; |
987
|
|
|
$this->withBasicAuth(); |
988
|
|
|
$response = $this->httpClient->get($endpoint); |
989
|
|
|
|
990
|
|
|
$responseObject = json_decode($response->body()); |
991
|
|
|
if (!$response->successful()) |
992
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
993
|
|
|
|
994
|
|
|
return $responseObject->responseBody; |
995
|
|
|
} |
996
|
|
|
|
997
|
|
|
|
998
|
|
|
/** |
999
|
|
|
* This allows you to get the available balance in your monnify wallet. |
1000
|
|
|
* |
1001
|
|
|
* @return mixed |
1002
|
|
|
* @throws MonnifyFailedRequestException |
1003
|
|
|
* |
1004
|
|
|
* @link https://docs.teamapt.com/display/MON/Get+Wallet+Balance |
1005
|
|
|
*/ |
1006
|
|
|
public function getWalletBalance() |
1007
|
|
|
{ |
1008
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}disbursements/wallet-balance?walletId={$this->config['wallet_id']}"; |
1009
|
|
|
$this->withBasicAuth(); |
1010
|
|
|
$response = $this->httpClient->get($endpoint); |
1011
|
|
|
|
1012
|
|
|
$responseObject = json_decode($response->body()); |
1013
|
|
|
if (!$response->successful()) |
1014
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
1015
|
|
|
|
1016
|
|
|
return $responseObject->responseBody; |
1017
|
|
|
} |
1018
|
|
|
|
1019
|
|
|
|
1020
|
|
|
/** |
1021
|
|
|
* This allows you to resend OTP for 2FA |
1022
|
|
|
* |
1023
|
|
|
* @param string $reference |
1024
|
|
|
* @return mixed |
1025
|
|
|
* @throws MonnifyFailedRequestException |
1026
|
|
|
* @link https://docs.teamapt.com/display/MON/Resend+OTP |
1027
|
|
|
*/ |
1028
|
|
|
public function resendOTP(string $reference) |
1029
|
|
|
{ |
1030
|
|
|
$endpoint = "{$this->baseUrl}{$this->v1}disbursements/single/resend-otp"; |
1031
|
|
|
$this->withBasicAuth(); |
1032
|
|
|
$response = $this->httpClient->post($endpoint, [ |
1033
|
|
|
'reference' => $reference |
1034
|
|
|
]); |
1035
|
|
|
|
1036
|
|
|
$responseObject = json_decode($response->body()); |
1037
|
|
|
if (!$response->successful()) |
1038
|
|
|
throw new MonnifyFailedRequestException($responseObject->responseMessage ?? "Path '{$responseObject->path}' {$responseObject->error}", $responseObject->responseCode ?? $responseObject->status); |
1039
|
|
|
|
1040
|
|
|
return $responseObject->responseBody; |
1041
|
|
|
} |
1042
|
|
|
|
1043
|
|
|
|
1044
|
|
|
} |
1045
|
|
|
|
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..