├── .env.example ├── .gitignore ├── .travis.yml ├── LICENSE ├── Tests ├── Abstractions │ └── ModelAbstractionsTest.php ├── BaseTestCase.php ├── Exceptions │ └── ExceptionHandlerTest.php ├── Factories │ └── PaystackHttpClientFactoryTest.php ├── Helpers │ ├── TransactionHelpersTest.php │ └── UtilsTest.php ├── Models │ ├── CustomerTest.php │ ├── OneTimeTransactionTest.php │ ├── PlanTest.php │ ├── ReturningTransactionTest.php │ └── TransactionModelObjectTest.php ├── PaystackLibTest.php └── Repositories │ ├── CustomerResourceTest.php │ ├── PlanResourceTest.php │ └── TransactionResourceTest.php ├── changelog.md ├── composer.json ├── phpunit.xml ├── phpunit_bootstrap.php ├── readme.md └── src ├── Abstractions ├── BaseTransaction.php ├── Model.php └── Resource.php ├── Contracts ├── ModelInterface.php ├── PlansInterface.php ├── ResourceInterface.php └── TransactionContract.php ├── Exceptions ├── BaseException.php ├── ExceptionHandler.php ├── PaystackInternalServerError.php ├── PaystackInvalidTransactionException.php ├── PaystackNotFoundException.php ├── PaystackUnauthorizedException.php ├── PaystackUnsupportedOperationException.php └── PaystackValidationException.php ├── Factories └── PaystackHttpClientFactory.php ├── Helpers ├── Transaction.php └── Utils.php ├── Models ├── Customer.php ├── OneTimeTransaction.php ├── Plan.php ├── ReturningTransaction.php └── Transaction.php ├── Paystack.php └── Repositories ├── CustomerResource.php ├── PlanResource.php └── TransactionResource.php /.env.example: -------------------------------------------------------------------------------- 1 | #PAYSTACK LIB MODE [test | live] 2 | PAYSTACK_MODE=test 3 | #YOUR PAYSTACK KEYS 4 | PAYSTACK_LIVE_PUBLIC_KEY=my_paystack_live_keys 5 | PAYSTACK_LIVE_SECRET_KEY=my_paystack_live_keys 6 | PAYSTACK_TEST_PUBLIC_KEY=my_paystack_test_keys 7 | PAYSTACK_TEST_SECRET_KEY=my_paystack_test_keys 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | build 3 | vendor 4 | composer.lock 5 | .env 6 | testings.php -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.5 4 | - 5.6 5 | - 7.0 6 | 7 | install: 8 | - travis_retry composer install --no-interaction --prefer-source 9 | - travis_retry composer require satooshi/php-coveralls:~0.6@stable 10 | 11 | before_script: 12 | - cp .env.example .env 13 | - mkdir -p build/logs 14 | - mkdir -p build/coverage 15 | 16 | script: 17 | - phpunit --coverage-clover build/logs/clover.xml 18 | 19 | after_success: 20 | - sh -c 'php vendor/bin/coveralls -v' 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Malik M. Abiola 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Tests/Abstractions/ModelAbstractionsTest.php: -------------------------------------------------------------------------------- 1 | _setAttributes($this->planData); 26 | 27 | $this->assertArraySubset($this->planData, $plan->get(['name', 'description', 'amount', 'currency'])); 28 | 29 | return $plan; 30 | } 31 | 32 | /** 33 | * @depends testSetAttributesReturnsAttributes 34 | * 35 | * @param Plan $plan 36 | */ 37 | public function testGetAttributes($plan) 38 | { 39 | $this->assertArraySubset($this->planData, $plan->get('name', 'description', 'amount', 'currency')); 40 | } 41 | 42 | public function testSetAttributesThrowsException() 43 | { 44 | $this->setExpectedException(\InvalidArgumentException::class); 45 | 46 | $plan = new Plan(new PlanResource(PaystackHttpClientFactory::make())); 47 | 48 | $plan->_setAttributes(''); 49 | } 50 | 51 | public function tearDown() 52 | { 53 | parent::tearDown(); // TODO: Change the autogenerated stub 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Tests/BaseTestCase.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'Authorization' => 'Bearer ', 19 | 'Content-Type' => 'application/json', 20 | ], 21 | ]; 22 | 23 | protected $customerResource; 24 | protected $customer; 25 | 26 | protected $planResource; 27 | protected $plan; 28 | 29 | protected $paystackHttpClient; 30 | 31 | protected $transactionResource; 32 | 33 | protected $transactionRequestArray; 34 | 35 | protected $customerCreateResponseData = [ 36 | 'first_name' => 'first_name', 37 | 'last_name' => 'last_name', 38 | 'email' => 'email@email.com', 39 | 'phone' => '2348032145698', 40 | 'integration' => 100082, 41 | 'domain' => 'test', 42 | 'customer_code' => 'CUS_docpswclqcq6oha', 43 | 'id' => 4158, 44 | 'createdAt' => '2016-02-14T10:15:33.481Z', 45 | 'updatedAt' => '2016-02-14T10:15:33.481Z', 46 | ]; 47 | protected $customerRetrievedResponseData = [ 48 | 'transactions' => [], 49 | 'subscriptions' => [], 50 | 'authorizations' => [], 51 | 'first_name' => 'first_name', 52 | 'last_name' => 'last_name', 53 | 'email' => 'email@email.com', 54 | 'phone' => '2348032145698', 55 | 'metadata' => null, 56 | 'domain' => 'test', 57 | 'customer_code' => 'CUS_k324c8osdjcohgt', 58 | 'id' => 4166, 59 | 'integration' => 100082, 60 | 'createdAt' => '2016-02-14T10:56:55.000Z', 61 | 'updatedAt' => '2016-02-14T10:56:55.000Z', 62 | 'total_transactions' => 0, 63 | 'total_transaction_value' => 0, 64 | ]; 65 | protected $customerUpdatedResponseData = [ 66 | 'first_name' => 'first_name', 67 | 'last_name' => 'new_last_name', 68 | 'email' => 'email@email.com', 69 | 'phone' => '2348032145698', 70 | 'metadata' => null, 71 | 'domain' => 'test', 72 | 'customer_code' => 'CUS_k324c8osdjcohgt', 73 | 'id' => 4166, 74 | 'integration' => 100082, 75 | 'createdAt' => '2016-02-14T10:56:55.000Z', 76 | 'updatedAt' => '2016-02-14T19:22:41.000Z', 77 | ]; 78 | protected $customersRetrievedResponseData = [ 79 | [ 80 | 'integration' => 100082, 81 | 'first_name' => null, 82 | 'last_name' => null, 83 | 'email' => 'email@email.com', 84 | 'phone' => null, 85 | 'metadata' => null, 86 | 'domain' => 'test', 87 | 'customer_code' => 'CUS_7hs14ranchjust4', 88 | 'id' => 4578, 89 | 'createdAt' => '2016-02-17T17:44:37.000Z', 90 | 'updatedAt' => '2016-02-17T17:44:37.000Z', 91 | ], 92 | [ 93 | 'integration' => 100082, 94 | 'first_name' => 'first_name', 95 | 'last_name' => 'new_last_name_e', 96 | 'email' => 'email@email.com', 97 | 'phone' => '2348032145698', 98 | 'metadata' => null, 99 | 'domain' => 'test', 100 | 'customer_code' => 'CUS_0zebihimtknqq6g', 101 | 'id' => 4575, 102 | 'createdAt' => '2016-02-17T17:26:16.000Z', 103 | 'updatedAt' => '2016-02-17T17:26:23.000Z', 104 | ], 105 | [ 106 | 'integration' => 100082, 107 | 'first_name' => 'first_name', 108 | 'last_name' => 'new_last_name_e', 109 | 'email' => 'email@email.com', 110 | 'phone' => '2348032145698', 111 | 'metadata' => null, 112 | 'domain' => 'test', 113 | 'customer_code' => 'CUS_7m9lsn3wg1okb66', 114 | 'id' => 4574, 115 | 'createdAt' => '2016-02-17T17:22:32.000Z', 116 | 'updatedAt' => '2016-02-17T17:22:38.000Z', 117 | ], 118 | [ 119 | 'integration' => 100082, 120 | 'first_name' => 'first_name', 121 | 'last_name' => 'new_last_name_e', 122 | 'email' => 'email@email.com', 123 | 'phone' => '2348032145698', 124 | 'metadata' => null, 125 | 'domain' => 'test', 126 | 'customer_code' => 'CUS_2x84ajdrp7e7cto', 127 | 'id' => 4571, 128 | 'createdAt' => '2016-02-17T17:03:27.000Z', 129 | 'updatedAt' => '2016-02-17T17:03:34.000Z', 130 | ], 131 | [ 132 | 'integration' => 100082, 133 | 'first_name' => 'first_name', 134 | 'last_name' => 'new_last_name_e', 135 | 'email' => 'email@email.com', 136 | 'phone' => '2348032145698', 137 | 'metadata' => null, 138 | 'domain' => 'test', 139 | 'customer_code' => 'CUS_1c1zp6vxa8v0aua', 140 | 'id' => 4527, 141 | 'createdAt' => '2016-02-17T14:26:29.000Z', 142 | 'updatedAt' => '2016-02-17T14:26:39.000Z', 143 | ], 144 | [ 145 | 'integration' => 100082, 146 | 'first_name' => 'first_name', 147 | 'last_name' => 'new_last_name_e', 148 | 'email' => 'email@email.com', 149 | 'phone' => '2348032145698', 150 | 'metadata' => null, 151 | 'domain' => 'test', 152 | 'customer_code' => 'CUS_3ohvst0iox1e9f8', 153 | 'id' => 4506, 154 | 'createdAt' => '2016-02-17T13:19:25.000Z', 155 | 'updatedAt' => '2016-02-17T13:19:36.000Z', 156 | ], 157 | [ 158 | 'integration' => 100082, 159 | 'first_name' => 'first_name', 160 | 'last_name' => 'new_last_name', 161 | 'email' => 'email@email.com', 162 | 'phone' => '2348032145698', 163 | 'metadata' => null, 164 | 'domain' => 'test', 165 | 'customer_code' => 'CUS_k324c8osdjcohgt', 166 | 'id' => 4166, 167 | 'createdAt' => '2016-02-14T10:56:55.000Z', 168 | 'updatedAt' => '2016-02-14T19:22:41.000Z', 169 | ], 170 | [ 171 | 'integration' => 100082, 172 | 'first_name' => 'first_name', 173 | 'last_name' => 'last_name', 174 | 'email' => 'email@email.com', 175 | 'phone' => '2348032145698', 176 | 'metadata' => null, 177 | 'domain' => 'test', 178 | 'customer_code' => 'CUS_fkhi6ypqfndzua4', 179 | 'id' => 4165, 180 | 'createdAt' => '2016-02-14T10:55:09.000Z', 181 | 'updatedAt' => '2016-02-14T10:55:09.000Z', 182 | ], 183 | [ 184 | 'integration' => 100082, 185 | 'first_name' => 'first_name', 186 | 'last_name' => 'last_name', 187 | 'email' => 'email@email.com', 188 | 'phone' => '2348032145698', 189 | 'metadata' => null, 190 | 'domain' => 'test', 191 | 'customer_code' => 'CUS_nc97lzm7u6k0uz9', 192 | 'id' => 4164, 193 | 'createdAt' => '2016-02-14T10:46:29.000Z', 194 | 'updatedAt' => '2016-02-14T10:46:29.000Z', 195 | ], 196 | ]; 197 | protected $customerData = [ 198 | 'first_name' => 'first_name', 199 | 'last_name' => 'last_name', 200 | 'email' => 'email@email.com', 201 | 'phone' => '2348032145698', 202 | ]; 203 | 204 | protected $planCreatedResourceResponseData = [ 205 | 'name' => 'new_test_plan', 206 | 'description' => 'New Test Plan', 207 | 'amount' => 10000, 208 | 'currency' => 'NGN', 209 | 'integration' => 100082, 210 | 'domain' => 'test', 211 | 'plan_code' => 'PLN_qxcu4d3ws1its7n', 212 | 'interval' => 'monthly', 213 | 'send_invoices' => true, 214 | 'send_sms' => true, 215 | 'hosted_page' => false, 216 | 'id' => 65, 217 | 'createdAt' => '2016-02-15T13:13:32.055Z', 218 | 'updatedAt' => '2016-02-15T13:13:32.055Z', 219 | ]; 220 | protected $planRetrievedResourceResponseData = [ 221 | 'subscriptions' => [], 222 | 'integration' => 100082, 223 | 'domain' => 'test', 224 | 'name' => 'new_test_plan', 225 | 'plan_code' => 'PLN_qxcu4d3ws1its7n', 226 | 'description' => 'New Test Plan', 227 | 'amount' => 10000, 228 | 'interval' => 'monthly', 229 | 'send_invoices' => true, 230 | 'send_sms' => true, 231 | 'hosted_page' => false, 232 | 'hosted_page_url' => null, 233 | 'hosted_page_summary' => null, 234 | 'currency' => 'NGN', 235 | 'id' => 65, 236 | 'createdAt' => '2016-02-15T13:13:32.000Z', 237 | 'updatedAt' => '2016-02-15T13:13:32.000Z', 238 | ]; 239 | protected $planUpdatedResourceResponseData = [ 240 | 'domain' => 'test', 241 | 'name' => 'new_test_plan', 242 | 'plan_code' => 'PLN_qxcu4d3ws1its7n', 243 | 'description' => 'new plan description', 244 | 'amount' => 10000, 245 | 'interval' => 'monthly', 246 | 'send_invoices' => true, 247 | 'send_sms' => true, 248 | 'hosted_page' => false, 249 | 'hosted_page_url' => null, 250 | 'hosted_page_summary' => null, 251 | 'currency' => 'NGN', 252 | 'id' => 65, 253 | 'integration' => 100082, 254 | 'createdAt' => '2016-02-15T13:13:32.000Z', 255 | 'updatedAt' => '2016-02-15T13:15:30.000Z', 256 | ]; 257 | protected $plansRetrievedResourceResponseData = [ 258 | [ 259 | 'subscriptions' => [], 260 | 'integration' => 100082, 261 | 'domain' => 'test', 262 | 'name' => 'TestPlan', 263 | 'plan_code' => 'PLN_3yjwpipkqymanb5', 264 | 'description' => 'test plan', 265 | 'amount' => 2000, 266 | 'interval' => 'monthly', 267 | 'send_invoices' => true, 268 | 'send_sms' => true, 269 | 'hosted_page' => true, 270 | 'hosted_page_url' => 'WescosaTestPlan', 271 | 'hosted_page_summary' => null, 272 | 'currency' => 'NGN', 273 | 'id' => 50, 274 | 'createdAt' => '2016-02-06T15:51:51.000Z', 275 | 'updatedAt' => '2016-02-06T15:51:51.000Z', 276 | ], 277 | [ 278 | 'subscriptions' => [], 279 | 'integration' => 100082, 280 | 'domain' => 'test', 281 | 'name' => 'new_test_plan', 282 | 'plan_code' => 'PLN_qxcu4d3ws1its7n', 283 | 'description' => 'new plan description', 284 | 'amount' => 10000, 285 | 'interval' => 'monthly', 286 | 'send_invoices' => true, 287 | 'send_sms' => true, 288 | 'hosted_page' => false, 289 | 'hosted_page_url' => null, 290 | 'hosted_page_summary' => null, 291 | 'currency' => 'NGN', 292 | 'id' => 65, 293 | 'createdAt' => '2016-02-15T13:13:32.000Z', 294 | 'updatedAt' => '2016-02-15T13:15:30.000Z', 295 | ], 296 | [ 297 | 'subscriptions' => [], 298 | 'integration' => 100082, 299 | 'domain' => 'test', 300 | 'name' => 'new_test_plan', 301 | 'plan_code' => 'PLN_rklaibixjjywxa2', 302 | 'description' => 'New Test Plan', 303 | 'amount' => 10000, 304 | 'interval' => 'weekly', 305 | 'send_invoices' => true, 306 | 'send_sms' => true, 307 | 'hosted_page' => false, 308 | 'hosted_page_url' => null, 309 | 'hosted_page_summary' => null, 310 | 'currency' => 'NGN', 311 | 'id' => 68, 312 | 'createdAt' => '2016-02-17T14:09:31.000Z', 313 | 'updatedAt' => '2016-02-17T14:09:35.000Z', 314 | ], 315 | [ 316 | 'subscriptions' => [], 317 | 'integration' => 100082, 318 | 'domain' => 'test', 319 | 'name' => 'new_test_plan', 320 | 'plan_code' => 'PLN_2fb699wfezb0gyr', 321 | 'description' => 'New Test Plan', 322 | 'amount' => 10000, 323 | 'interval' => 'weekly', 324 | 'send_invoices' => true, 325 | 'send_sms' => true, 326 | 'hosted_page' => false, 327 | 'hosted_page_url' => null, 328 | 'hosted_page_summary' => null, 329 | 'currency' => 'NGN', 330 | 'id' => 69, 331 | 'createdAt' => '2016-02-17T14:18:47.000Z', 332 | 'updatedAt' => '2016-02-17T14:18:53.000Z', 333 | ], 334 | [ 335 | 'subscriptions' => [], 336 | 'integration' => 100082, 337 | 'domain' => 'test', 338 | 'name' => 'new_test_plan', 339 | 'plan_code' => 'PLN_vaj2ot80m76s4iw', 340 | 'description' => 'New Test Plan', 341 | 'amount' => 10000, 342 | 'interval' => 'weekly', 343 | 'send_invoices' => true, 344 | 'send_sms' => true, 345 | 'hosted_page' => false, 346 | 'hosted_page_url' => null, 347 | 'hosted_page_summary' => null, 348 | 'currency' => 'NGN', 349 | 'id' => 70, 350 | 'createdAt' => '2016-02-17T14:24:12.000Z', 351 | 'updatedAt' => '2016-02-17T14:24:18.000Z', 352 | ], 353 | [ 354 | 'subscriptions' => [], 355 | 'integration' => 100082, 356 | 'domain' => 'test', 357 | 'name' => 'new_test_plan', 358 | 'plan_code' => 'PLN_6voibagfhozg0je', 359 | 'description' => 'New Test Plan', 360 | 'amount' => 10000, 361 | 'interval' => 'weekly', 362 | 'send_invoices' => true, 363 | 'send_sms' => true, 364 | 'hosted_page' => false, 365 | 'hosted_page_url' => null, 366 | 'hosted_page_summary' => null, 367 | 'currency' => 'NGN', 368 | 'id' => 71, 369 | 'createdAt' => '2016-02-17T14:26:48.000Z', 370 | 'updatedAt' => '2016-02-17T14:26:53.000Z', 371 | ], 372 | [ 373 | 'subscriptions' => [], 374 | 'integration' => 100082, 375 | 'domain' => 'test', 376 | 'name' => 'new_test_plan', 377 | 'plan_code' => 'PLN_vmt89e4k3y44bxr', 378 | 'description' => 'New Test Plan', 379 | 'amount' => 10000, 380 | 'interval' => 'weekly', 381 | 'send_invoices' => true, 382 | 'send_sms' => true, 383 | 'hosted_page' => false, 384 | 'hosted_page_url' => null, 385 | 'hosted_page_summary' => null, 386 | 'currency' => 'NGN', 387 | 'id' => 72, 388 | 'createdAt' => '2016-02-17T17:03:41.000Z', 389 | 'updatedAt' => '2016-02-17T17:03:44.000Z', 390 | ], 391 | ]; 392 | protected $planData = [ 393 | 'name' => 'new_test_plan', 394 | 'description' => 'New Test Plan', 395 | 'amount' => 10000, 396 | 'currency' => 'NGN', 397 | ]; 398 | 399 | protected $initOneTimeTransactionResourceResponseData = [ 400 | 'authorization_url' => 'https=>//standard.paystack.co/pay/u0w3i084gp', 401 | 'access_code' => 'u0w3i084gp', 402 | 'reference' => 'radnosm160202014046', 403 | ]; 404 | protected $chargeReturningTransactionResourceResponseData = [ 405 | 'amount' => 10000, 406 | 'transaction_date' => '2016-02-02T02:41:25.000Z', 407 | 'status' => 'success', 408 | 'reference' => 'radnosm160202014046', 409 | 'domain' => 'test', 410 | 'authorization' => [ 411 | 'authorization_code' => 'AUTH_jonwwppn', 412 | 'card_type' => 'visa', 413 | 'last4' => '1381', 414 | 'bank' => null, 415 | ], 416 | 'customer' => [ 417 | 'first_name' => null, 418 | 'last_name' => null, 419 | 'email' => 'testuser@test.com', 420 | ], 421 | 'plan' => 0, 422 | ]; 423 | protected $transactionDetailsResponseData = [ 424 | 'integration' => 100082, 425 | 'customer' => [ 426 | 'first_name' => 'first_name', 427 | 'last_name' => 'last_name', 428 | 'email' => 'email@email.com', 429 | 'phone' => '2348032145698', 430 | 'metadata' => null, 431 | 'domain' => 'test', 432 | 'customer_code' => 'CUS_docpswclqcq6oha', 433 | 'id' => 4158, 434 | 'integration' => 100082, 435 | 'createdAt' => '2016-02-14T10:15:33.000Z', 436 | 'updatedAt' => '2016-02-14T10:15:33.000Z', 437 | ], 438 | 'coupon' => 0, 439 | 'plan' => 0, 440 | 'subscription' => null, 441 | 'invoice' => null, 442 | 'reference' => 'imaginary_reference_key', 443 | 'domain' => 'test', 444 | 'status' => 'pending', 445 | 'message' => null, 446 | 'original_amount' => 10000, 447 | 'amount' => 10000, 448 | 'authorized_amount' => null, 449 | 'captured_amount' => null, 450 | 'quantity' => 1, 451 | 'gateway_response' => null, 452 | 'receipt_number' => null, 453 | 'merchant_transaction_reference' => null, 454 | 'authorization_code' => null, 455 | 'authorization_url' => 'u0w3i084gp', 456 | 'authorization_url_valid' => true, 457 | 'authorization_url_accessed_at' => null, 458 | 'authorization_url_access_count' => null, 459 | 'currency' => 'NGN', 460 | 'logged_for_settlement' => null, 461 | 'settled' => null, 462 | 'metadata' => null, 463 | 'response' => null, 464 | 'transaction_number' => null, 465 | 'payment_page' => null, 466 | 'ip_address' => null, 467 | 'paidAt' => null, 468 | 'id' => 9663, 469 | 'createdAt' => '2016-02-15T17:49:21.000Z', 470 | 'updatedAt' => null, 471 | ]; 472 | protected $allTransactionsResponseData = [ 473 | [ 474 | 'integration' => 100082, 475 | 'customer' => [ 476 | 'first_name' => 'first_name', 477 | 'last_name' => 'last_name', 478 | 'email' => 'email@email.com', 479 | 'phone' => '2348032145698', 480 | 'metadata' => null, 481 | 'domain' => 'test', 482 | 'customer_code' => 'CUS_docpswclqcq6oha', 483 | 'id' => 4158, 484 | 'integration' => 100082, 485 | 'createdAt' => '2016-02-14T10:15:33.000Z', 486 | 'updatedAt' => '2016-02-14T10:15:33.000Z', 487 | ], 488 | 'coupon' => 0, 489 | 'plan' => 0, 490 | 'subscription' => null, 491 | 'invoice' => null, 492 | 'reference' => 'imaginary_reference_key', 493 | 'domain' => 'test', 494 | 'status' => 'pending', 495 | 'message' => null, 496 | 'original_amount' => 10000, 497 | 'amount' => 10000, 498 | 'authorized_amount' => null, 499 | 'captured_amount' => null, 500 | 'quantity' => 1, 501 | 'gateway_response' => null, 502 | 'receipt_number' => null, 503 | 'merchant_transaction_reference' => null, 504 | 'authorization_code' => null, 505 | 'authorization_url' => 'u0w3i084gp', 506 | 'authorization_url_valid' => true, 507 | 'authorization_url_accessed_at' => null, 508 | 'authorization_url_access_count' => null, 509 | 'currency' => 'NGN', 510 | 'logged_for_settlement' => null, 511 | 'settled' => null, 512 | 'metadata' => null, 513 | 'response' => null, 514 | 'transaction_number' => null, 515 | 'payment_page' => null, 516 | 'ip_address' => null, 517 | 'paidAt' => null, 518 | 'id' => 9663, 519 | 'createdAt' => '2016-02-15T17:49:21.000Z', 520 | 'updatedAt' => null, 521 | ], 522 | [ 523 | 'integration' => 100082, 524 | 'customer' => [ 525 | 'first_name' => null, 526 | 'last_name' => null, 527 | 'email' => 'testuser@test.com', 528 | 'phone' => null, 529 | 'metadata' => null, 530 | 'domain' => 'test', 531 | 'customer_code' => 'CUS_ob42yn9tskrdg7x', 532 | 'id' => 2855, 533 | 'integration' => 100082, 534 | 'createdAt' => '2016-02-02T01:36:16.000Z', 535 | 'updatedAt' => '2016-02-02T01:36:16.000Z', 536 | ], 537 | 'coupon' => 0, 538 | 'plan' => 0, 539 | 'subscription' => null, 540 | 'invoice' => null, 541 | 'authorization' => [ 542 | 'domain' => 'test', 543 | 'authorization_code' => 'AUTH_jonwwppn', 544 | 'card_type' => null, 545 | 'last4' => null, 546 | 'bank' => null, 547 | 'description' => 'visa ending with 1381', 548 | 'mobile' => null, 549 | 'id' => 2381, 550 | 'integration' => 100082, 551 | 'customer' => 2855, 552 | 'card' => 5513, 553 | 'createdAt' => '2016-02-07T15:07:21.000Z', 554 | 'updatedAt' => null, 555 | ], 556 | 'reference' => 'radnosm160202014046', 557 | 'domain' => 'test', 558 | 'status' => 'success', 559 | 'message' => null, 560 | 'original_amount' => 5000, 561 | 'amount' => 5000, 562 | 'authorized_amount' => 5000, 563 | 'captured_amount' => 5000, 564 | 'quantity' => 1, 565 | 'gateway_response' => 'Success', 566 | 'receipt_number' => '517301335067', 567 | 'merchant_transaction_reference' => 'PSTKg285q', 568 | 'authorization_code' => 'AUTH_jonwwppn', 569 | 'authorization_url' => '9h4fd7ksim', 570 | 'authorization_url_valid' => false, 571 | 'authorization_url_accessed_at' => null, 572 | 'authorization_url_access_count' => null, 573 | 'currency' => 'NGN', 574 | 'logged_for_settlement' => 'ignored', 575 | 'settled' => null, 576 | 'metadata' => null, 577 | 'response' => 'vpc_AVSResultCode=Unsupported&vpc_AcqAVSRespCode=Unsupported&vpc_AcqCSCRespCode=M&vpc_AcqResponseCode=00&vpc_Amount=5000&vpc_AuthorizeId=testtest&vpc_BatchNo=20150621&vpc_CSCResultCode=M&vpc_Card=MC&vpc_Command=pay&vpc_Currency=NGN&vpc_Locale=en_NG&vpc_MerchTxnRef=PSTKg285q&vpc_Merchant=PWC001&vpc_Message=Approved&vpc_OrderInfo=PSTKz4ogk&vpc_ReceiptNo=517301335067&vpc_SecureHash=234D2610F6A533A0A83F09137DE54FABC1A3C1FD8D7C372A814152AF4B877A06&vpc_SecureHashType=SHA256&vpc_TransactionNo=1100000876&vpc_TxnResponseCode=0&vpc_Version=1', 578 | 'transaction_number' => '1100000876', 579 | 'payment_page' => null, 580 | 'ip_address' => null, 581 | 'paidAt' => '2016-02-07T15:07:21.000Z', 582 | 'id' => 5561, 583 | 'createdAt' => '2016-02-02T02:41:25.000Z', 584 | 'updatedAt' => '2016-02-07T15:07:25.000Z', 585 | ], 586 | [ 587 | 'integration' => 100082, 588 | 'customer' => [ 589 | 'first_name' => null, 590 | 'last_name' => null, 591 | 'email' => 'testuser@test.com', 592 | 'phone' => null, 593 | 'metadata' => null, 594 | 'domain' => 'test', 595 | 'customer_code' => 'CUS_ob42yn9tskrdg7x', 596 | 'id' => 2855, 597 | 'integration' => 100082, 598 | 'createdAt' => '2016-02-02T01:36:16.000Z', 599 | 'updatedAt' => '2016-02-02T01:36:16.000Z', 600 | ], 601 | 'coupon' => 0, 602 | 'plan' => 0, 603 | 'subscription' => null, 604 | 'invoice' => null, 605 | 'reference' => 'radnosm160202013743', 606 | 'domain' => 'test', 607 | 'status' => 'pending', 608 | 'message' => null, 609 | 'original_amount' => 5000, 610 | 'amount' => 5000, 611 | 'authorized_amount' => null, 612 | 'captured_amount' => null, 613 | 'quantity' => 1, 614 | 'gateway_response' => null, 615 | 'receipt_number' => null, 616 | 'merchant_transaction_reference' => null, 617 | 'authorization_code' => null, 618 | 'authorization_url' => 'r3it6og93x', 619 | 'authorization_url_valid' => true, 620 | 'authorization_url_accessed_at' => null, 621 | 'authorization_url_access_count' => null, 622 | 'currency' => 'NGN', 623 | 'logged_for_settlement' => null, 624 | 'settled' => null, 625 | 'metadata' => null, 626 | 'response' => null, 627 | 'transaction_number' => null, 628 | 'payment_page' => null, 629 | 'ip_address' => null, 630 | 'paidAt' => null, 631 | 'id' => 5560, 632 | 'createdAt' => '2016-02-02T02:38:22.000Z', 633 | 'updatedAt' => null, 634 | ], 635 | [ 636 | 'integration' => 100082, 637 | 'customer' => [ 638 | 'first_name' => null, 639 | 'last_name' => null, 640 | 'email' => 'testuser@test.com', 641 | 'phone' => null, 642 | 'metadata' => null, 643 | 'domain' => 'test', 644 | 'customer_code' => 'CUS_ob42yn9tskrdg7x', 645 | 'id' => 2855, 646 | 'integration' => 100082, 647 | 'createdAt' => '2016-02-02T01:36:16.000Z', 648 | 'updatedAt' => '2016-02-02T01:36:16.000Z', 649 | ], 650 | 'coupon' => 0, 651 | 'plan' => 0, 652 | 'subscription' => null, 653 | 'invoice' => null, 654 | 'reference' => 'radnosm160202013616', 655 | 'domain' => 'test', 656 | 'status' => 'pending', 657 | 'message' => null, 658 | 'original_amount' => 5000, 659 | 'amount' => 5000, 660 | 'authorized_amount' => null, 661 | 'captured_amount' => null, 662 | 'quantity' => 1, 663 | 'gateway_response' => null, 664 | 'receipt_number' => null, 665 | 'merchant_transaction_reference' => null, 666 | 'authorization_code' => null, 667 | 'authorization_url' => 'pvowir7xns', 668 | 'authorization_url_valid' => true, 669 | 'authorization_url_accessed_at' => null, 670 | 'authorization_url_access_count' => null, 671 | 'currency' => 'NGN', 672 | 'logged_for_settlement' => null, 673 | 'settled' => null, 674 | 'metadata' => null, 675 | 'response' => null, 676 | 'transaction_number' => null, 677 | 'payment_page' => null, 678 | 'ip_address' => null, 679 | 'paidAt' => null, 680 | 'id' => 5559, 681 | 'createdAt' => '2016-02-02T02:36:55.000Z', 682 | 'updatedAt' => null, 683 | ], 684 | ]; 685 | protected $transactionTotalsResponseData = [ 686 | 'total_volume' => 5000, 687 | 'total_transactions' => 1, 688 | 'pending_transfers' => 5000, 689 | ]; 690 | protected $verifyTransactionResponseData = [ 691 | 'amount' => 5000, 692 | 'transaction_date' => '2016-02-02T02:41:25.000Z', 693 | 'status' => 'success', 694 | 'reference' => 'radnosm160202014046', 695 | 'domain' => 'test', 696 | 'authorization' => [ 697 | 'authorization_code' => 'AUTH_jonwwppn', 698 | 'card_type' => 'visa', 699 | 'last4' => '1381', 700 | 'bank' => null, 701 | ], 702 | 'customer' => [ 703 | 'first_name' => null, 704 | 'last_name' => null, 705 | 'email' => 'testuser@test.com', 706 | ], 707 | 'plan' => 0, 708 | ]; 709 | 710 | public function getFakedCustomerData(array $specifics = []) 711 | { 712 | $faker = Faker::create(); 713 | 714 | return array_merge( 715 | [ 716 | 'first_name' => $faker->firstName, 717 | 'last_name' => $faker->lastName, 718 | 'email' => $faker->email, 719 | 'phone' => $faker->phoneNumber, 720 | ], 721 | $specifics 722 | ); 723 | } 724 | 725 | public function setUp() 726 | { 727 | parent::setUp(); 728 | } 729 | 730 | public function tearDown() 731 | { 732 | parent::tearDown(); 733 | } 734 | } 735 | -------------------------------------------------------------------------------- /Tests/Exceptions/ExceptionHandlerTest.php: -------------------------------------------------------------------------------- 1 | response = new \stdClass(); 23 | } 24 | 25 | public function testExceptionHandlerHandlesUnauthorizedError() 26 | { 27 | $this->response->message = 'Unauthorized'; 28 | $exception = ExceptionHandler::handle( 29 | '', 30 | $this->response, 31 | Response::HTTP_UNAUTHORIZED 32 | ); 33 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $exception); 34 | $this->assertStringStartsWith('Unauthorized', $exception->getErrors()); 35 | } 36 | 37 | public function testExceptionHandlerHandlesNotFoundErrors() 38 | { 39 | $this->response->message = 'Not Found'; 40 | $exception = ExceptionHandler::handle( 41 | '', 42 | $this->response, 43 | Response::HTTP_NOT_FOUND 44 | ); 45 | $this->assertInstanceOf(PaystackNotFoundException::class, $exception); 46 | $this->assertStringStartsWith($this->response->message, $exception->getErrors()); 47 | } 48 | 49 | public function testExceptionHandlerHandlesBadRequestErrors() 50 | { 51 | $this->response->message = 'A validation error has occured'; 52 | 53 | $exception = ExceptionHandler::handle( 54 | '', 55 | $this->response, 56 | Response::HTTP_BAD_REQUEST 57 | ); 58 | $this->assertInstanceOf(PaystackValidationException::class, $exception); 59 | $this->assertStringStartsWith($this->response->message, $exception->getErrors()); 60 | } 61 | 62 | public function testExceptionHandlerHandlesGateWayTimeoutExceptions() 63 | { 64 | $this->response->message = ''; 65 | 66 | $exception = ExceptionHandler::handle( 67 | '', 68 | $this->response, 69 | Response::HTTP_GATEWAY_TIMEOUT 70 | ); 71 | $this->assertInstanceOf(PaystackInternalServerError::class, $exception); 72 | } 73 | 74 | public function testExceptionHandlerHandlesInternalServerErrors() 75 | { 76 | $this->response->message = 'Internal Server Error'; 77 | 78 | $exception = ExceptionHandler::handle( 79 | '', 80 | $this->response, 81 | Response::HTTP_INTERNAL_SERVER_ERROR 82 | ); 83 | $this->assertInstanceOf(PaystackInternalServerError::class, $exception); 84 | } 85 | 86 | public function testExceptionHandlerHandlesUnknownError() 87 | { 88 | $this->response->message = 'Internal Server Error'; 89 | 90 | $exception = ExceptionHandler::handle( 91 | '', 92 | $this->response, 93 | Response::HTTP_SERVICE_UNAVAILABLE 94 | ); 95 | $this->assertInstanceOf(\Exception::class, $exception); 96 | } 97 | 98 | public function tearDown() 99 | { 100 | parent::tearDown(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Tests/Factories/PaystackHttpClientFactoryTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf( 19 | Client::class, 20 | PaystackHttpClientFactory::make() 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Tests/Helpers/TransactionHelpersTest.php: -------------------------------------------------------------------------------- 1 | transactionResource = new TransactionResource(PaystackHttpClientFactory::make()); 22 | } 23 | 24 | public function testRetrieveTransactionDetailsReturnsTransactionDetails() 25 | { 26 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 27 | $mockTransactionResource->shouldReceive('get') 28 | ->once() 29 | ->andReturn($this->transactionDetailsResponseData); 30 | 31 | $transactionHelper = Transaction::make(); 32 | $transactionHelper->setTransactionResource($mockTransactionResource); 33 | 34 | $transaction = $transactionHelper->details('9663'); 35 | 36 | $this->assertInstanceOf(\MAbiola\Paystack\Models\Transaction::class, $transaction); 37 | $this->assertEquals($this->transactionDetailsResponseData['reference'], $transaction->get('reference')); 38 | 39 | $this->assertTrue(is_array($transaction->_toArray())); 40 | } 41 | 42 | public function testRetrieveTransactionDetailsReturnsException() 43 | { 44 | $invalidResponse = new \stdClass(); 45 | $invalidResponse->message = 'Transaction Not Found'; 46 | 47 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 48 | $mockTransactionResource->shouldReceive('get') 49 | ->once() 50 | ->andReturn(new PaystackNotFoundException($invalidResponse, 404)); 51 | 52 | $transactionHelper = Transaction::make(); 53 | $transactionHelper->setTransactionResource($mockTransactionResource); 54 | 55 | $this->setExpectedException(PaystackNotFoundException::class); 56 | $transactionHelper->details('9663'); 57 | } 58 | 59 | public function testGetAllTransactionsReturnsAllTransactions() 60 | { 61 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 62 | $mockTransactionResource->shouldReceive('getAll') 63 | ->withAnyArgs() 64 | ->once() 65 | ->andReturn($this->allTransactionsResponseData); 66 | 67 | $transactionHelper = Transaction::make(); 68 | $transactionHelper->setTransactionResource($mockTransactionResource); 69 | 70 | $allTransactions = $transactionHelper->allTransactions(1); 71 | 72 | $this->assertTrue(is_array($allTransactions)); 73 | $this->assertCount(4, $allTransactions); 74 | $this->assertInstanceOf(\MAbiola\Paystack\Models\Transaction::class, $allTransactions[0]); 75 | $this->assertArrayHasKey('customer', $allTransactions[0]->get(['customer'])); 76 | } 77 | 78 | public function testGetAllTransactionsReturnsException() 79 | { 80 | $invalidResponse = new \stdClass(); 81 | $invalidResponse->message = 'Transaction Not Found'; 82 | 83 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 84 | $mockTransactionResource->shouldReceive('getAll') 85 | ->withAnyArgs() 86 | ->once() 87 | ->andReturn(new PaystackNotFoundException($invalidResponse, 404)); 88 | 89 | $transactionHelper = Transaction::make(); 90 | $transactionHelper->setTransactionResource($mockTransactionResource); 91 | 92 | $this->setExpectedException(PaystackNotFoundException::class); 93 | $transactionHelper->allTransactions(1); 94 | } 95 | 96 | public function testGetTransactionTotalsReturnsTransactionTotals() 97 | { 98 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 99 | $mockTransactionResource->shouldReceive('getTransactionTotals') 100 | ->once() 101 | ->andReturn($this->transactionTotalsResponseData); 102 | 103 | $transactionHelper = Transaction::make(); 104 | $transactionHelper->setTransactionResource($mockTransactionResource); 105 | 106 | $transactionTotals = $transactionHelper->transactionsTotals(); 107 | 108 | $this->assertTrue(is_array($transactionTotals)); 109 | $this->assertArrayHasKey('total_volume', $transactionTotals); 110 | $this->assertArrayHasKey('total_transactions', $transactionTotals); 111 | $this->assertArrayHasKey('pending_transfers', $transactionTotals); 112 | $this->assertEquals($this->transactionTotalsResponseData['total_transactions'], $transactionTotals['total_transactions']); 113 | } 114 | 115 | public function testGetTransactionTotalsReturnsException() 116 | { 117 | $invalidResponse = new \stdClass(); 118 | $invalidResponse->message = 'Authorization Not Found'; 119 | 120 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 121 | $mockTransactionResource->shouldReceive('getTransactionTotals') 122 | ->once() 123 | ->andReturn(new PaystackUnauthorizedException($invalidResponse, 401)); 124 | 125 | $this->setExpectedException(PaystackUnauthorizedException::class); 126 | $transactionHelper = Transaction::make(); 127 | $transactionHelper->setTransactionResource($mockTransactionResource); 128 | 129 | $transactionHelper->transactionsTotals(); 130 | } 131 | 132 | public function testVerifyTransactionReturnsTransaction() 133 | { 134 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 135 | $mockTransactionResource->shouldReceive('verify') 136 | ->once() 137 | ->andReturn($this->verifyTransactionResponseData); 138 | 139 | $transactionHelper = Transaction::make(); 140 | $transactionHelper->setTransactionResource($mockTransactionResource); 141 | 142 | $verify = $transactionHelper->verify($this->initOneTimeTransactionResourceResponseData['reference']); 143 | 144 | $this->assertTrue(is_array($verify)); 145 | $this->assertArrayHasKey('customer', $verify); 146 | $this->assertArrayHasKey('amount', $verify); 147 | $this->assertArrayHasKey('plan', $verify); 148 | } 149 | 150 | public function testVerifyTransactionReturnsFalse() 151 | { 152 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 153 | $mockTransactionResource->shouldReceive('verify') 154 | ->once() 155 | ->andReturn(['status' => 'unsuccessful']); 156 | 157 | $transactionHelper = Transaction::make(); 158 | $transactionHelper->setTransactionResource($mockTransactionResource); 159 | 160 | $verify = $transactionHelper->verify($this->initOneTimeTransactionResourceResponseData['reference']); 161 | 162 | $this->assertFalse($verify); 163 | } 164 | 165 | public function testVerifyTransactionThrowsException() 166 | { 167 | $invalidResponse = new \stdClass(); 168 | $invalidResponse->message = 'Authorization Not Found'; 169 | 170 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 171 | $mockTransactionResource->shouldReceive('verify') 172 | ->once() 173 | ->andReturn(new PaystackUnauthorizedException($invalidResponse, 401)); 174 | 175 | $this->setExpectedException(PaystackUnauthorizedException::class); 176 | $transactionHelper = Transaction::make(); 177 | $transactionHelper->setTransactionResource($mockTransactionResource); 178 | 179 | $transactionHelper->verify($this->initOneTimeTransactionResourceResponseData['reference']); 180 | } 181 | 182 | public function tearDown() 183 | { 184 | parent::tearDown(); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /Tests/Helpers/UtilsTest.php: -------------------------------------------------------------------------------- 1 | assertNotEquals(Utils::generateTransactionRef(), Utils::generateTransactionRef()); 19 | } 20 | 21 | public function testGetEnvReturnsDefaultValueWhenKeyNotFound() 22 | { 23 | $this->assertEquals('key', Utils::env('NOT_FOUND_KEY', 'key')); 24 | } 25 | 26 | public function testTransformUrlReturnsTransformedUrl() 27 | { 28 | $this->assertEquals('/customer/1', Utils::transformUrl(Resource::CUSTOMERS_URL, 1)); 29 | $this->assertEquals( 30 | '/transaction/verify/transaction_reference', 31 | Utils::transformUrl( 32 | Resource::VERIFY_TRANSACTION, 33 | 'transaction_reference', 34 | ':reference' 35 | ) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Tests/Models/CustomerTest.php: -------------------------------------------------------------------------------- 1 | customerResource = new CustomerResource(PaystackHttpClientFactory::make()); 22 | } 23 | 24 | public function testSaveCustomerReturnsCustomer() 25 | { 26 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 27 | $mockCustomerResource->shouldReceive('save') 28 | ->withAnyArgs() 29 | ->once() 30 | ->andReturn($this->customerCreateResponseData); 31 | 32 | $customerModel = new Customer($mockCustomerResource); 33 | $createdCustomer = $customerModel->make( 34 | $this->customerData['first_name'], 35 | $this->customerData['last_name'], 36 | $this->customerData['email'], 37 | $this->customerData['phone'] 38 | )->save(); 39 | 40 | $this->assertInstanceOf(Customer::class, $createdCustomer); 41 | $this->assertEquals($this->customerData['first_name'], $createdCustomer->get('first_name')); 42 | $this->assertEquals($this->customerData['last_name'], $createdCustomer->get('last_name')); 43 | $this->assertEquals($this->customerData['email'], $createdCustomer->get('email')); 44 | $this->assertEquals($this->customerData['phone'], $createdCustomer->get('phone')); 45 | } 46 | 47 | public function testGetCustomerReturnsCustomer() 48 | { 49 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 50 | $mockCustomerResource->shouldReceive('get') 51 | ->withAnyArgs() 52 | ->once() 53 | ->andReturn($this->customerRetrievedResponseData); 54 | 55 | $customerModel = new Customer($mockCustomerResource); 56 | $retrievedCustomer = $customerModel->getCustomer($this->customerCreateResponseData['customer_code']); 57 | 58 | $this->assertInstanceOf(Customer::class, $retrievedCustomer); 59 | $this->assertEquals($this->customerData['first_name'], $retrievedCustomer->get('first_name')); 60 | $this->assertEquals($this->customerData['last_name'], $retrievedCustomer->get('last_name')); 61 | $this->assertEquals($this->customerData['email'], $retrievedCustomer->get('email')); 62 | $this->assertEquals($this->customerData['phone'], $retrievedCustomer->get('phone')); 63 | } 64 | 65 | public function testGetCustomerThrowsException() 66 | { 67 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 68 | $mockCustomerResource->shouldReceive('get') 69 | ->withAnyArgs() 70 | ->once() 71 | ->andReturn(new \Exception()); 72 | 73 | $this->setExpectedException(\Exception::class); 74 | $customerModel = new Customer($mockCustomerResource); 75 | $customerModel->getCustomer($this->customerCreateResponseData['customer_code']); 76 | } 77 | 78 | public function testUpdateCustomerReturnsCustomer() 79 | { 80 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 81 | $mockCustomerResource->shouldReceive('get') 82 | ->withAnyArgs() 83 | ->once() 84 | ->andReturn($this->customerRetrievedResponseData); 85 | 86 | $mockCustomerResource->shouldReceive('update') 87 | ->withAnyArgs() 88 | ->once() 89 | ->andReturn($this->customerUpdatedResponseData); 90 | 91 | $customerModel = new Customer($mockCustomerResource); 92 | $updatedCustomer = $customerModel->getCustomer($this->customerCreateResponseData['customer_code']) 93 | ->setUpdateData(['last_name' => 'new_last_name'])->save(); 94 | 95 | $this->assertInstanceOf(Customer::class, $updatedCustomer); 96 | $this->assertEquals('new_last_name', $updatedCustomer->get('last_name')); 97 | } 98 | 99 | public function testUpdateCustomerThrowsException() 100 | { 101 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 102 | $mockCustomerResource->shouldReceive('get') 103 | ->withAnyArgs() 104 | ->once() 105 | ->andReturn($this->customerRetrievedResponseData); 106 | 107 | $mockCustomerResource->shouldReceive('update') 108 | ->withAnyArgs() 109 | ->once() 110 | ->andReturn(new \Exception()); 111 | 112 | $this->setExpectedException(\Exception::class); 113 | 114 | $customerModel = new Customer($mockCustomerResource); 115 | $customerModel->getCustomer($this->customerCreateResponseData['customer_code']) 116 | ->setUpdateData(['last_name' => 'new_last_name'])->save(); 117 | } 118 | 119 | public function testUpdateWithInvalidParamsThrowException() 120 | { 121 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 122 | $mockCustomerResource->shouldReceive('get') 123 | ->withAnyArgs() 124 | ->once() 125 | ->andReturn($this->customerRetrievedResponseData); 126 | 127 | $this->setExpectedException(\Exception::class); 128 | 129 | $customerModel = new Customer($mockCustomerResource); 130 | $customerModel->getCustomer($this->customerCreateResponseData['customer_code']) 131 | ->setUpdateData([])->save(); 132 | } 133 | 134 | public function testDeleteCustomerReturnsException() 135 | { 136 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 137 | $mockCustomerResource->shouldReceive('get') 138 | ->withAnyArgs() 139 | ->once() 140 | ->andReturn($this->customerRetrievedResponseData); 141 | 142 | $this->setExpectedException(PaystackUnsupportedOperationException::class); 143 | 144 | $customerModel = new Customer($mockCustomerResource); 145 | $customerModel->getCustomer($this->customerCreateResponseData['customer_code'])->delete(); 146 | } 147 | 148 | public function testAttemptToSaveEmptyDataThrowsException() 149 | { 150 | $this->setExpectedException(\InvalidArgumentException::class); 151 | $customerModel = new Customer($this->customerResource); 152 | $customerModel->save(); 153 | } 154 | 155 | public function tearDown() 156 | { 157 | parent::tearDown(); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /Tests/Models/OneTimeTransactionTest.php: -------------------------------------------------------------------------------- 1 | transactionResource = new TransactionResource(PaystackHttpClientFactory::make()); 20 | } 21 | 22 | public function testInitializeOneTimeTransaction() 23 | { 24 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 25 | $mockTransactionResource->shouldReceive('initialize') 26 | ->once() 27 | ->andReturn($this->initOneTimeTransactionResourceResponseData); 28 | 29 | $oneTimeTransaction = OneTimeTransaction::make($this->planData['amount'], $this->customerData['email'], ''); 30 | $oneTimeTransaction->setTransactionResource($mockTransactionResource); 31 | $initOneTimeTransaction = $oneTimeTransaction->initialize(); 32 | 33 | $this->assertEquals($this->initOneTimeTransactionResourceResponseData, $initOneTimeTransaction); 34 | } 35 | 36 | public function tearDown() 37 | { 38 | parent::tearDown(); // TODO: Change the autogenerated stub 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Tests/Models/PlanTest.php: -------------------------------------------------------------------------------- 1 | planResource = new PlanResource(PaystackHttpClientFactory::make()); 22 | } 23 | 24 | public function testCreatePlanSuccessful() 25 | { 26 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 27 | $mockPlanResource->shouldReceive('save')->withAnyArgs()->andReturn($this->planCreatedResourceResponseData); 28 | 29 | $plan = new Plan($mockPlanResource); 30 | $createdPlan = $plan->make( 31 | $this->planData['name'], 32 | $this->planData['description'], 33 | $this->planData['amount'], 34 | $this->planData['currency'] 35 | )->save(); 36 | 37 | $this->assertInstanceOf(Plan::class, $createdPlan); 38 | $this->assertArraySubset($this->planData, $createdPlan->get(['name', 'description', 'amount', 'currency'])); 39 | } 40 | 41 | public function testCreatePlanReturnsException() 42 | { 43 | $errorResponse = new \stdClass(); 44 | $errorResponse->message = 'Paystack Validation Exception'; 45 | 46 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 47 | $mockPlanResource->shouldReceive('save') 48 | ->withAnyArgs() 49 | ->andReturn( 50 | new PaystackValidationException( 51 | $errorResponse, 52 | 400 53 | ) 54 | ); 55 | 56 | $plan = new Plan($mockPlanResource); 57 | 58 | $this->setExpectedException(PaystackValidationException::class); 59 | 60 | $createdPlan = $plan->make( 61 | $this->planData['name'], 62 | $this->planData['description'], 63 | $this->planData['amount'], 64 | $this->planData['currency'] 65 | )->save(); 66 | } 67 | 68 | public function testCreatePlanOnEmptyPlanObject() 69 | { 70 | $plan = new Plan($this->planResource); 71 | 72 | $this->setExpectedException(\InvalidArgumentException::class); 73 | 74 | $plan->save(); 75 | } 76 | 77 | public function testUpdatePlanSuccessfully() 78 | { 79 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 80 | $mockPlanResource->shouldReceive('get')->withAnyArgs()->andReturn($this->planRetrievedResourceResponseData); 81 | $mockPlanResource->shouldReceive('update')->withAnyArgs()->andReturn($this->planUpdatedResourceResponseData); 82 | 83 | $plan = new Plan($mockPlanResource); 84 | $updatedPlan = $plan->getPlan($this->planRetrievedResourceResponseData['plan_code']) 85 | ->setUpdateData(['description' => 'new plan description'])->save(); 86 | 87 | $this->assertInstanceOf(Plan::class, $updatedPlan); 88 | $this->assertEquals('new plan description', $updatedPlan->get('description')); 89 | } 90 | 91 | public function testRetrievePlanSuccessfully() 92 | { 93 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 94 | $mockPlanResource->shouldReceive('get')->withAnyArgs()->andReturn($this->planRetrievedResourceResponseData); 95 | 96 | $plan = new Plan($mockPlanResource); 97 | $retrievedPlan = $plan->getPlan($this->planRetrievedResourceResponseData['plan_code']); 98 | 99 | $this->assertInstanceOf(Plan::class, $retrievedPlan); 100 | $this->assertArraySubset($this->planData, $retrievedPlan->get(['name', 'description', 'amount', 'currency'])); 101 | } 102 | 103 | public function testRetrievePlanThrowsException() 104 | { 105 | $errorResponse = new \stdClass(); 106 | $errorResponse->message = 'Paystack Validation Exception'; 107 | 108 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 109 | $mockPlanResource->shouldReceive('get') 110 | ->withAnyArgs() 111 | ->andReturn( 112 | new PaystackValidationException( 113 | $errorResponse, 114 | 400 115 | ) 116 | ); 117 | 118 | $plan = new Plan($mockPlanResource); 119 | 120 | $this->setExpectedException(PaystackValidationException::class); 121 | 122 | $retrievedPlan = $plan->getPlan($this->planRetrievedResourceResponseData['plan_code']); 123 | } 124 | 125 | public function testTransformPlan() 126 | { 127 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 128 | $mockPlanResource->shouldReceive('get')->withAnyArgs()->andReturn($this->planRetrievedResourceResponseData); 129 | 130 | $plan = new Plan($mockPlanResource); 131 | $retrievedPlan = $plan->getPlan($this->planRetrievedResourceResponseData['plan_code'])->transform(); 132 | $this->assertArraySubset($this->planData, $retrievedPlan); 133 | } 134 | 135 | public function testDeletePlanThrowsUnsupportedException() 136 | { 137 | $this->setExpectedException(PaystackUnsupportedOperationException::class); 138 | 139 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 140 | $mockPlanResource->shouldReceive('get')->withAnyArgs()->andReturn($this->planRetrievedResourceResponseData); 141 | 142 | $plan = new Plan($mockPlanResource); 143 | $plan->getPlan($this->planRetrievedResourceResponseData['plan_code'])->delete(); 144 | } 145 | 146 | public function tearDown() 147 | { 148 | parent::tearDown(); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /Tests/Models/ReturningTransactionTest.php: -------------------------------------------------------------------------------- 1 | transactionResource = new TransactionResource(PaystackHttpClientFactory::make()); 20 | } 21 | 22 | public function testChargeReturningTransaction() 23 | { 24 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 25 | $mockTransactionResource->shouldReceive('chargeAuthorization') 26 | ->once() 27 | ->andReturn($this->chargeReturningTransactionResourceResponseData); 28 | 29 | $returningTransaction = ReturningTransaction::make('AUTH_jonwwppn', $this->planData['amount'], $this->customerData['email'], ''); 30 | $returningTransaction->setTransactionResource($mockTransactionResource); 31 | $chargeReturningTransaction = $returningTransaction->charge(); 32 | 33 | $this->assertEquals($this->chargeReturningTransactionResourceResponseData, $chargeReturningTransaction); 34 | } 35 | 36 | public function tearDown() 37 | { 38 | parent::tearDown(); // TODO: Change the autogenerated stub 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Tests/Models/TransactionModelObjectTest.php: -------------------------------------------------------------------------------- 1 | transactionDetailsResponseData); 22 | 23 | $this->assertInstanceOf(Transaction::class, $transactionObject); 24 | $this->assertEquals($this->transactionDetailsResponseData['reference'], $transactionObject->get('reference')); 25 | 26 | $this->assertTrue(is_array($transactionObject->_toArray())); 27 | } 28 | 29 | public function tearDown() 30 | { 31 | parent::tearDown(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tests/PaystackLibTest.php: -------------------------------------------------------------------------------- 1 | paystack = Paystack::make(); 31 | $this->paystackHttpClient = PaystackHttpClientFactory::make(); 32 | $this->customerResource = new CustomerResource($this->paystackHttpClient); 33 | $this->planResource = new PlanResource($this->paystackHttpClient); 34 | $this->transactionResource = new TransactionResource($this->paystackHttpClient); 35 | } 36 | 37 | public function testGetCustomerByIdReturnsCustomer() 38 | { 39 | //mock customer resource 40 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 41 | $mockCustomerResource->shouldReceive('get') 42 | ->withAnyArgs() 43 | ->once() 44 | ->andReturn($this->customerRetrievedResponseData); 45 | //create new customer model 46 | $customerModel = new Customer($mockCustomerResource); 47 | //set customer model to customer model with mocked customer resource 48 | $this->paystack->setCustomerModel($customerModel); 49 | //check response 50 | $retrievedCustomer = $this->paystack->getCustomer($this->customerCreateResponseData['customer_code']); 51 | $this->assertTrue(is_array($retrievedCustomer->toArray())); 52 | $this->assertInstanceOf(Customer::class, $retrievedCustomer); 53 | $this->assertEquals($this->customerData['first_name'], $retrievedCustomer->get('first_name')); 54 | $this->assertEquals($this->customerData['last_name'], $retrievedCustomer->get('last_name')); 55 | $this->assertEquals($this->customerData['email'], $retrievedCustomer->get('email')); 56 | $this->assertEquals($this->customerData['phone'], $retrievedCustomer->get('phone')); 57 | } 58 | 59 | public function testGetCustomerByIdReturnsException() 60 | { 61 | //mock customer resource 62 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 63 | $mockCustomerResource->shouldReceive('get') 64 | ->withAnyArgs() 65 | ->once() 66 | ->andReturn(new \Exception()); 67 | //create new customer model 68 | $customerModel = new Customer($mockCustomerResource); 69 | //set customer model to customer model with mocked customer resource 70 | $this->paystack->setCustomerModel($customerModel); 71 | 72 | //check response 73 | $this->setExpectedException(\Exception::class); 74 | $this->paystack->getCustomer($this->customerCreateResponseData['customer_code']); 75 | } 76 | 77 | public function testGetAllCustomersReturnsCustomers() 78 | { 79 | //mock customer resource 80 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 81 | $mockCustomerResource->shouldReceive('getAll') 82 | ->withAnyArgs() 83 | ->once() 84 | ->andReturn($this->customersRetrievedResponseData); 85 | 86 | $this->paystack->setCustomerResource($mockCustomerResource); 87 | 88 | $retrievedCustomers = $this->paystack->getCustomers(); 89 | //check assertions 90 | $this->assertTrue(is_array($retrievedCustomers)); 91 | $this->assertGreaterThanOrEqual(1, $retrievedCustomers); 92 | $this->assertInstanceOf(Customer::class, $retrievedCustomers[0]); 93 | $this->assertTrue(is_array($retrievedCustomers[0]->toArray())); 94 | $this->assertArrayHasKey('email', $retrievedCustomers[0]->toArray()); 95 | } 96 | 97 | public function testGetAllCustomersReturnsError() 98 | { 99 | //mock customer resource 100 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 101 | $mockCustomerResource->shouldReceive('getAll') 102 | ->withAnyArgs() 103 | ->once() 104 | ->andReturn(new \Exception()); 105 | //set customer model to customer model with mocked customer resource 106 | $this->paystack->setCustomerResource($mockCustomerResource); 107 | //set expected exception 108 | $this->setExpectedException(\Exception::class); 109 | $retrievedCustomers = $this->paystack->getCustomers(); 110 | } 111 | 112 | public function testCreateCustomerCreatesCustomerSuccessfully() 113 | { 114 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 115 | $mockCustomerResource->shouldReceive('save') 116 | ->withAnyArgs() 117 | ->once() 118 | ->andReturn($this->customerCreateResponseData); 119 | 120 | $customerModel = new Customer($mockCustomerResource); 121 | $this->paystack->setCustomerModel($customerModel); 122 | $createdCustomer = $this->paystack->createCustomer( 123 | $this->customerData['first_name'], 124 | $this->customerData['last_name'], 125 | $this->customerData['email'], 126 | $this->customerData['phone'] 127 | ); 128 | 129 | $this->assertInstanceOf(Customer::class, $createdCustomer); 130 | $this->assertEquals($this->customerData['first_name'], $createdCustomer->get('first_name')); 131 | $this->assertEquals($this->customerData['last_name'], $createdCustomer->get('last_name')); 132 | $this->assertEquals($this->customerData['email'], $createdCustomer->get('email')); 133 | $this->assertEquals($this->customerData['phone'], $createdCustomer->get('phone')); 134 | } 135 | 136 | public function testCreateCustomerReturnsException() 137 | { 138 | $this->setExpectedException(PaystackValidationException::class); 139 | $this->paystack->createCustomer('', '', '', ''); 140 | } 141 | 142 | public function testUpdateCustomerReturnsCustomer() 143 | { 144 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 145 | $mockCustomerResource->shouldReceive('get') 146 | ->withAnyArgs() 147 | ->once() 148 | ->andReturn($this->customerRetrievedResponseData); 149 | 150 | $mockCustomerResource->shouldReceive('update') 151 | ->withAnyArgs() 152 | ->once() 153 | ->andReturn($this->customerUpdatedResponseData); 154 | 155 | $this->paystack->setCustomerModel(new Customer($mockCustomerResource)); 156 | 157 | $updatedCustomer = $this->paystack->updateCustomerData( 158 | $this->customerCreateResponseData['customer_code'], 159 | ['last_name' => 'new_last_name'] 160 | ); 161 | 162 | $this->assertInstanceOf(Customer::class, $updatedCustomer); 163 | $this->assertEquals('new_last_name', $updatedCustomer->get('last_name')); 164 | } 165 | 166 | public function testUpdateCustomerReturnsException() 167 | { 168 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 169 | $mockCustomerResource->shouldReceive('get') 170 | ->withAnyArgs() 171 | ->once() 172 | ->andReturn($this->customerRetrievedResponseData); 173 | 174 | $mockCustomerResource->shouldReceive('update') 175 | ->withAnyArgs() 176 | ->once() 177 | ->andReturn(new \Exception()); 178 | 179 | $this->paystack->setCustomerModel(new Customer($mockCustomerResource)); 180 | $this->setExpectedException(\Exception::class); 181 | $updatedCustomer = $this->paystack->updateCustomerData( 182 | $this->customerCreateResponseData['customer_code'], 183 | ['last_name' => 'new_last_name'] 184 | ); 185 | } 186 | 187 | public function testDeleteCustomerReturnsException() 188 | { 189 | $mockCustomerResource = \Mockery::mock($this->customerResource)->makePartial(); 190 | $mockCustomerResource->shouldReceive('get') 191 | ->withAnyArgs() 192 | ->once() 193 | ->andReturn($this->customerRetrievedResponseData); 194 | 195 | $this->paystack->setCustomerModel(new Customer($mockCustomerResource)); 196 | $this->setExpectedException(PaystackUnsupportedOperationException::class); 197 | $this->paystack->deleteCustomer($this->customerCreateResponseData['customer_code']); 198 | } 199 | 200 | public function testGetPlanReturnsPlanObject() 201 | { 202 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 203 | $mockPlanResource->shouldReceive('get')->withAnyArgs()->andReturn($this->planRetrievedResourceResponseData); 204 | 205 | $this->paystack->setPlanModel(new Plan($mockPlanResource)); 206 | $retrievedPlan = $this->paystack->getPlan($this->planRetrievedResourceResponseData['plan_code']); 207 | 208 | $this->assertInstanceOf(Plan::class, $retrievedPlan); 209 | $this->assertArraySubset($this->planData, $retrievedPlan->get(['name', 'description', 'amount', 'currency'])); 210 | } 211 | 212 | public function testGetPlanReturnsException() 213 | { 214 | $errorResponse = new \stdClass(); 215 | $errorResponse->message = 'Paystack Validation Exception'; 216 | 217 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 218 | $mockPlanResource->shouldReceive('get') 219 | ->withAnyArgs() 220 | ->andReturn( 221 | new PaystackValidationException( 222 | $errorResponse, 223 | 400 224 | ) 225 | ); 226 | $this->paystack->setPlanModel(new Plan($mockPlanResource)); 227 | 228 | $this->setExpectedException(PaystackValidationException::class); 229 | $retrievedPlan = $this->paystack->getPlan($this->planRetrievedResourceResponseData['plan_code']); 230 | } 231 | 232 | public function testGetPlansReturnsPlans() 233 | { 234 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 235 | $mockPlanResource->shouldReceive('getAll')->withAnyArgs()->andReturn($this->plansRetrievedResourceResponseData); 236 | 237 | $this->paystack->setPlanResource($mockPlanResource); 238 | 239 | $retrievedPlans = $this->paystack->getPlans(); 240 | $this->assertGreaterThanOrEqual(1, count($retrievedPlans)); 241 | $this->assertInstanceOf(Plan::class, $retrievedPlans[0]); 242 | $this->assertTrue(is_array($retrievedPlans[0]->get(['name', 'description', 'amount', 'currency']))); 243 | $this->assertTrue(is_array($retrievedPlans[0]->toArray())); 244 | $this->assertArrayHasKey('name', $retrievedPlans[0]->get(['name', 'description', 'amount', 'currency'])); 245 | $this->assertArrayHasKey('description', $retrievedPlans[0]->get(['name', 'description', 'amount', 'currency'])); 246 | $this->assertArrayHasKey('amount', $retrievedPlans[0]->get(['name', 'description', 'amount', 'currency'])); 247 | $this->assertArrayHasKey('currency', $retrievedPlans[0]->get(['name', 'description', 'amount', 'currency'])); 248 | } 249 | 250 | public function testGetPlansReturnsError() 251 | { 252 | $this->planResource = new PlanResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 253 | $this->paystack->setPlanResource($this->planResource); 254 | 255 | $this->setExpectedException(PaystackUnauthorizedException::class); 256 | $retrievedPlans = $this->paystack->getPlans(); 257 | } 258 | 259 | public function testCreatePlanReturnsPlan() 260 | { 261 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 262 | $mockPlanResource->shouldReceive('save')->withAnyArgs()->andReturn($this->planCreatedResourceResponseData); 263 | 264 | $this->paystack->setPlanModel(new Plan($mockPlanResource)); 265 | $createdPlan = $this->paystack->createPlan( 266 | $this->planData['name'], 267 | $this->planData['description'], 268 | $this->planData['amount'], 269 | $this->planData['currency'] 270 | )->save(); 271 | 272 | $this->assertInstanceOf(Plan::class, $createdPlan); 273 | $this->assertArraySubset($this->planData, $createdPlan->get(['name', 'description', 'amount', 'currency'])); 274 | } 275 | 276 | public function testCreatePlanReturnsException() 277 | { 278 | $this->paystack->setPlanModel(new Plan($this->planResource)); 279 | $this->setExpectedException(PaystackValidationException::class); 280 | $createdPlan = $this->paystack->createPlan('', '', '', '')->save(); 281 | } 282 | 283 | public function testUpdatePlanReturnsUpdatedPlan() 284 | { 285 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 286 | $mockPlanResource->shouldReceive('get')->withAnyArgs()->andReturn($this->planRetrievedResourceResponseData); 287 | $mockPlanResource->shouldReceive('update')->withAnyArgs()->andReturn($this->planUpdatedResourceResponseData); 288 | 289 | $this->paystack->setPlanModel(new Plan($mockPlanResource)); 290 | $updatedPlan = $this->paystack->updatePlan( 291 | $this->planRetrievedResourceResponseData['plan_code'], 292 | ['description' => 'new plan description'] 293 | ); 294 | 295 | $this->assertInstanceOf(Plan::class, $updatedPlan); 296 | $this->assertEquals('new plan description', $updatedPlan->get('description')); 297 | } 298 | 299 | public function testUpdatePlanThrowsException() 300 | { 301 | $errorResponse = new \stdClass(); 302 | $errorResponse->message = 'Paystack Validation Exception'; 303 | 304 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 305 | $mockPlanResource->shouldReceive('get')->withAnyArgs()->andReturn($this->planRetrievedResourceResponseData); 306 | $mockPlanResource->shouldReceive('update')->withAnyArgs()->andReturn( 307 | new PaystackValidationException( 308 | $errorResponse, 309 | 400 310 | ) 311 | ); 312 | 313 | $this->paystack->setPlanModel(new Plan($mockPlanResource)); 314 | $this->setExpectedException(PaystackValidationException::class); 315 | $updatedPlan = $this->paystack->updatePlan( 316 | $this->planRetrievedResourceResponseData['plan_code'], 317 | ['description' => 'new plan description'] 318 | ); 319 | } 320 | 321 | public function testDeletePlanThrowsException() 322 | { 323 | $mockPlanResource = \Mockery::mock($this->planResource)->makePartial(); 324 | $mockPlanResource->shouldReceive('get')->withAnyArgs()->andReturn($this->planRetrievedResourceResponseData); 325 | 326 | $this->paystack->setPlanModel(new Plan($mockPlanResource)); 327 | 328 | $this->setExpectedException(PaystackUnsupportedOperationException::class); 329 | $retrievedPlan = $this->paystack->deletePlan($this->planRetrievedResourceResponseData['plan_code']); 330 | } 331 | 332 | public function testStartOneTimeTransactionSuccessful() 333 | { 334 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 335 | $mockTransactionResource->shouldReceive('initialize') 336 | ->once() 337 | ->andReturn($this->initOneTimeTransactionResourceResponseData); 338 | $this->paystack->setTransactionResource($mockTransactionResource); 339 | 340 | $initOneTimeTransaction = $this->paystack->startOneTimeTransaction( 341 | $this->planData['amount'], 342 | $this->customerData['email'], 343 | '' 344 | ); 345 | $this->assertEquals($this->initOneTimeTransactionResourceResponseData, $initOneTimeTransaction); 346 | } 347 | 348 | public function testStartOneTimeTransactionReturnsError() 349 | { 350 | $this->setExpectedException(PaystackValidationException::class); 351 | $initOneTimeTransaction = $this->paystack->startOneTimeTransaction('', '', ''); 352 | } 353 | 354 | public function testReturningTransactionSuccessful() 355 | { 356 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 357 | $mockTransactionResource->shouldReceive('chargeAuthorization') 358 | ->once() 359 | ->andReturn($this->chargeReturningTransactionResourceResponseData); 360 | 361 | $this->paystack->setTransactionResource($mockTransactionResource); 362 | 363 | $chargeReturningTransaction = $this->paystack->chargeReturningTransaction( 364 | 'AUTH_jonwwppn', 365 | $this->planData['amount'], 366 | $this->customerData['email'], 367 | '' 368 | ); 369 | 370 | $this->assertEquals($this->chargeReturningTransactionResourceResponseData, $chargeReturningTransaction); 371 | } 372 | 373 | public function testReturningTransactionReturnsError() 374 | { 375 | $this->setExpectedException(PaystackValidationException::class); 376 | $chargeReturningTransaction = $this->paystack->chargeReturningTransaction('', '', '', ''); 377 | } 378 | 379 | public function testVerifyTransactionSuccessful() 380 | { 381 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 382 | $mockTransactionResource->shouldReceive('verify') 383 | ->once() 384 | ->andReturn($this->verifyTransactionResponseData); 385 | 386 | $transactionHelper = Transaction::make(); 387 | $transactionHelper->setTransactionResource($mockTransactionResource); 388 | $this->paystack->setTransactionHelper($transactionHelper); 389 | 390 | $verify = $this->paystack->verifyTransaction($this->initOneTimeTransactionResourceResponseData['reference']); 391 | 392 | $this->assertTrue(is_array($verify)); 393 | $this->assertArrayHasKey('customer', $verify); 394 | $this->assertArrayHasKey('amount', $verify); 395 | $this->assertArrayHasKey('plan', $verify); 396 | } 397 | 398 | public function testVerifyTransactionThrowsException() 399 | { 400 | $this->transactionResource = new TransactionResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 401 | $transactionHelper = Transaction::make(); 402 | $transactionHelper->setTransactionResource($this->transactionResource); 403 | $this->paystack->setTransactionHelper($transactionHelper); 404 | 405 | $this->setExpectedException(PaystackUnauthorizedException::class); 406 | $verify = $this->paystack->verifyTransaction($this->initOneTimeTransactionResourceResponseData['reference']); 407 | } 408 | 409 | public function testVerifyTransactionNotSuccessful() 410 | { 411 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 412 | $mockTransactionResource->shouldReceive('verify') 413 | ->once() 414 | ->andReturn(['status' => 'unsuccessful']); 415 | 416 | $transactionHelper = Transaction::make(); 417 | $transactionHelper->setTransactionResource($mockTransactionResource); 418 | $this->paystack->setTransactionHelper($transactionHelper); 419 | 420 | $verify = $this->paystack->verifyTransaction($this->initOneTimeTransactionResourceResponseData['reference']); 421 | $this->assertFalse($verify); 422 | } 423 | 424 | public function testGetTransactionDetailsReturnsTransactionDetails() 425 | { 426 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 427 | $mockTransactionResource->shouldReceive('get') 428 | ->once() 429 | ->andReturn($this->transactionDetailsResponseData); 430 | 431 | $transactionHelper = Transaction::make(); 432 | $transactionHelper->setTransactionResource($mockTransactionResource); 433 | $this->paystack->setTransactionHelper($transactionHelper); 434 | 435 | $transaction = $this->paystack->transactionDetails('9663'); 436 | 437 | $this->assertInstanceOf(\MAbiola\Paystack\Models\Transaction::class, $transaction); 438 | $this->assertEquals($this->transactionDetailsResponseData['reference'], $transaction->get('reference')); 439 | 440 | $this->assertTrue(is_array($transaction->_toArray())); 441 | } 442 | 443 | public function testGetTransactionDetailsThrowsException() 444 | { 445 | $invalidResponse = new \stdClass(); 446 | $invalidResponse->message = 'Transaction Not Found'; 447 | 448 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 449 | $mockTransactionResource->shouldReceive('get') 450 | ->once() 451 | ->andReturn(new PaystackNotFoundException($invalidResponse, 404)); 452 | 453 | $transactionHelper = Transaction::make(); 454 | $transactionHelper->setTransactionResource($mockTransactionResource); 455 | 456 | $this->paystack->setTransactionHelper($transactionHelper); 457 | 458 | $this->setExpectedException(PaystackNotFoundException::class); 459 | $this->paystack->transactionDetails('9663'); 460 | } 461 | 462 | public function testGetAllTransactionsReturnsTransactions() 463 | { 464 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 465 | $mockTransactionResource->shouldReceive('getAll') 466 | ->withAnyArgs() 467 | ->once() 468 | ->andReturn($this->allTransactionsResponseData); 469 | 470 | $transactionHelper = Transaction::make(); 471 | $transactionHelper->setTransactionResource($mockTransactionResource); 472 | $this->paystack->setTransactionHelper($transactionHelper); 473 | 474 | $allTransactions = $this->paystack->allTransactions(); 475 | 476 | $this->assertTrue(is_array($allTransactions)); 477 | $this->assertCount(4, $allTransactions); 478 | $this->assertInstanceOf(\MAbiola\Paystack\Models\Transaction::class, $allTransactions[0]); 479 | $this->assertArrayHasKey('customer', $allTransactions[0]->get(['customer'])); 480 | } 481 | 482 | public function testGetAllTransactionsReturnsException() 483 | { 484 | $invalidResponse = new \stdClass(); 485 | $invalidResponse->message = 'Transaction Not Found'; 486 | 487 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 488 | $mockTransactionResource->shouldReceive('getAll') 489 | ->withAnyArgs() 490 | ->once() 491 | ->andReturn(new PaystackNotFoundException($invalidResponse, 404)); 492 | 493 | $transactionHelper = Transaction::make(); 494 | $transactionHelper->setTransactionResource($mockTransactionResource); 495 | $this->paystack->setTransactionHelper($transactionHelper); 496 | 497 | $this->setExpectedException(PaystackNotFoundException::class); 498 | $this->paystack->allTransactions(); 499 | } 500 | 501 | public function testGetTotalsReturnsTotals() 502 | { 503 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 504 | $mockTransactionResource->shouldReceive('getTransactionTotals') 505 | ->once() 506 | ->andReturn($this->transactionTotalsResponseData); 507 | 508 | $transactionHelper = Transaction::make(); 509 | $transactionHelper->setTransactionResource($mockTransactionResource); 510 | $this->paystack->setTransactionHelper($transactionHelper); 511 | 512 | $transactionTotals = $this->paystack->transactionsTotals(); 513 | 514 | $this->assertTrue(is_array($transactionTotals)); 515 | $this->assertArrayHasKey('total_volume', $transactionTotals); 516 | $this->assertArrayHasKey('total_transactions', $transactionTotals); 517 | $this->assertArrayHasKey('pending_transfers', $transactionTotals); 518 | $this->assertEquals($this->transactionTotalsResponseData['total_transactions'], $transactionTotals['total_transactions']); 519 | } 520 | 521 | public function testGetTotalsThrowExceptions() 522 | { 523 | $invalidResponse = new \stdClass(); 524 | $invalidResponse->message = 'Authorization Not Found'; 525 | 526 | $mockTransactionResource = \Mockery::mock($this->transactionResource)->makePartial(); 527 | $mockTransactionResource->shouldReceive('getTransactionTotals') 528 | ->once() 529 | ->andReturn(new PaystackUnauthorizedException($invalidResponse, 401)); 530 | 531 | $this->setExpectedException(PaystackUnauthorizedException::class); 532 | $transactionHelper = Transaction::make(); 533 | $transactionHelper->setTransactionResource($mockTransactionResource); 534 | $this->paystack->setTransactionHelper($transactionHelper); 535 | 536 | $this->paystack->transactionsTotals(); 537 | } 538 | 539 | public function testMakePaystackLib() 540 | { 541 | $this->setExpectedException(PaystackUnauthorizedException::class); 542 | $paystackLib = Paystack::make('some-fake-random-key'); 543 | $paystackLib->transactionsTotals(); 544 | } 545 | 546 | public function tearDown() 547 | { 548 | $this->paystack = Paystack::make(); 549 | $this->paystackHttpClient = PaystackHttpClientFactory::make(); 550 | $this->customerResource = new CustomerResource($this->paystackHttpClient); 551 | $this->planResource = new PlanResource($this->paystackHttpClient); 552 | $this->transactionResource = new TransactionResource($this->paystackHttpClient); 553 | parent::tearDown(); // TODO: Change the autogenerated stub 554 | } 555 | } 556 | -------------------------------------------------------------------------------- /Tests/Repositories/CustomerResourceTest.php: -------------------------------------------------------------------------------- 1 | paystackHttpClient = PaystackHttpClientFactory::make(); 25 | } 26 | 27 | public function testCreateUserSuccessful() 28 | { 29 | $this->customerData = $this->getFakedCustomerData(); 30 | 31 | $customerResource = new CustomerResource($this->paystackHttpClient); 32 | $createdCustomer = $customerResource->save($this->customerData); 33 | 34 | $this->assertTrue(is_array($createdCustomer)); 35 | $this->assertEquals($this->customerData['first_name'], $createdCustomer['first_name']); 36 | $this->assertEquals($this->customerData['last_name'], $createdCustomer['last_name']); 37 | $this->assertEquals($this->customerData['email'], $createdCustomer['email']); 38 | $this->assertEquals($this->customerData['phone'], $createdCustomer['phone']); 39 | 40 | return $createdCustomer; 41 | } 42 | 43 | public function testCreateUserUnsuccessful() 44 | { 45 | $this->customerData = $this->getFakedCustomerData(); 46 | 47 | //test create user throws unauthorized 48 | $customerResource = new CustomerResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 49 | $createdCustomer = $customerResource->save($this->customerData); 50 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $createdCustomer); 51 | 52 | //test create user throws validation errors 53 | $customerResource = new CustomerResource($this->paystackHttpClient); 54 | $createdCustomer = $customerResource->save([]); 55 | $validationErrors = $createdCustomer->getValidationErrors(); 56 | 57 | $this->assertInstanceOf(PaystackValidationException::class, $createdCustomer); 58 | $this->assertTrue(is_array($validationErrors)); 59 | $this->assertGreaterThanOrEqual(1, count($validationErrors)); 60 | } 61 | 62 | /** 63 | * @depends testCreateUserSuccessful 64 | * 65 | * @param $createdCustomer 66 | */ 67 | public function testGetCustomerByIdReturnsCustomerDetails($createdCustomer) 68 | { 69 | $customerResource = new CustomerResource($this->paystackHttpClient); 70 | $retrievedCustomer = $customerResource->get($createdCustomer['customer_code']); 71 | 72 | $this->assertEquals($createdCustomer['customer_code'], $retrievedCustomer['customer_code']); 73 | $this->assertEquals($createdCustomer['first_name'], $retrievedCustomer['first_name']); 74 | $this->assertEquals($createdCustomer['last_name'], $retrievedCustomer['last_name']); 75 | $this->assertEquals($createdCustomer['email'], $retrievedCustomer['email']); 76 | $this->assertEquals($createdCustomer['phone'], $retrievedCustomer['phone']); 77 | } 78 | 79 | /** 80 | * @depends testCreateUserSuccessful 81 | * 82 | * @param $createdCustomer 83 | */ 84 | public function testGetCustomerByIdThrowsException($createdCustomer) 85 | { 86 | //test get user throws unauthorized 87 | $customerResource = new CustomerResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 88 | $retrieveUser = $customerResource->get($createdCustomer['customer_code']); 89 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $retrieveUser); 90 | } 91 | 92 | /** 93 | * @depends testCreateUserSuccessful 94 | * 95 | * @param $createdCustomer 96 | */ 97 | public function testUpdateCustomerByIsSuccessful($createdCustomer) 98 | { 99 | $customerResource = new CustomerResource($this->paystackHttpClient); 100 | $updatedCustomer = $customerResource->update($createdCustomer['customer_code'], ['last_name' => 'new_last_name_e']); 101 | 102 | $this->assertEquals($createdCustomer['customer_code'], $updatedCustomer['customer_code']); 103 | $this->assertEquals($createdCustomer['first_name'], $updatedCustomer['first_name']); 104 | $this->assertEquals('new_last_name_e', $updatedCustomer['last_name']); 105 | $this->assertEquals($createdCustomer['email'], $updatedCustomer['email']); 106 | $this->assertEquals($createdCustomer['phone'], $updatedCustomer['phone']); 107 | } 108 | 109 | /** 110 | * @depends testCreateUserSuccessful 111 | * 112 | * @param $createdCustomer 113 | */ 114 | // public function testUpdateCustomerThrowsException($createdCustomer) 115 | // { 116 | // $customerResource = new CustomerResource($this->paystackHttpClient); 117 | // $updatedCustomer = $customerResource->update($createdCustomer['customer_code'], ['email' => 'this-is-an-invalid-email']); 118 | // $validationErrors = $updatedCustomer->getValidationErrors(); 119 | // 120 | // $this->assertInstanceOf(PaystackValidationException::class, $updatedCustomer); 121 | // $this->assertTrue(is_array($validationErrors)); 122 | // $this->assertGreaterThanOrEqual(1, count($validationErrors)); 123 | // } 124 | 125 | /** 126 | * @depends testCreateUserSuccessful 127 | * 128 | * @param $createdCustomer 129 | */ 130 | public function testDeleteCustomerReturns404($createdCustomer) 131 | { 132 | $customerResource = new CustomerResource($this->paystackHttpClient); 133 | $deleteCustomer = $customerResource->delete($createdCustomer['customer_code']); 134 | 135 | $this->assertInstanceOf(PaystackNotFoundException::class, $deleteCustomer); 136 | } 137 | 138 | public function testGetAllCustomers() 139 | { 140 | $customerResource = new CustomerResource(PaystackHttpClientFactory::make()); 141 | $retrieveUsers = $customerResource->getAll(); 142 | $this->assertTrue(is_array($retrieveUsers)); 143 | $this->assertGreaterThanOrEqual(1, count($retrieveUsers)); 144 | } 145 | 146 | public function testGetAllCustomersThrowsException() 147 | { 148 | $customerResource = new CustomerResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 149 | $retrieveUsers = $customerResource->getAll(1); 150 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $retrieveUsers); 151 | } 152 | 153 | public function tearDown() 154 | { 155 | parent::tearDown(); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /Tests/Repositories/PlanResourceTest.php: -------------------------------------------------------------------------------- 1 | paystackHttpClient = PaystackHttpClientFactory::make(); 24 | } 25 | 26 | public function testCreatePlanSuccessful() 27 | { 28 | $planResource = new PlanResource($this->paystackHttpClient); 29 | $createdPlan = $planResource->save($this->planData); 30 | 31 | $this->assertTrue(is_array($createdPlan)); 32 | $this->assertEquals($this->planData['amount'], $createdPlan['amount']); 33 | $this->assertEquals($this->planData['description'], $createdPlan['description']); 34 | $this->assertEquals($this->planData['name'], $createdPlan['name']); 35 | 36 | return $createdPlan; 37 | } 38 | 39 | public function testCreatePlanReturnsErrors() 40 | { 41 | //test create plan returns unauthorized 42 | $planResource = new PlanResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 43 | $createdPlan = $planResource->save($this->planData); 44 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $createdPlan); 45 | 46 | //test create plan returns validation errors 47 | $planResource = new PlanResource($this->paystackHttpClient); 48 | $createdPlan = $planResource->save([]); 49 | 50 | $this->assertInstanceOf(PaystackValidationException::class, $createdPlan); 51 | 52 | $validationErrors = $createdPlan->getValidationErrors(); 53 | 54 | $this->assertTrue(is_array($validationErrors)); 55 | $this->assertGreaterThanOrEqual(1, count($validationErrors)); 56 | } 57 | 58 | /** 59 | * @depends testCreatePlanSuccessful 60 | * 61 | * @param $createdPlan 62 | */ 63 | public function testUpdatePlanSuccessful($createdPlan) 64 | { 65 | $planResource = new PlanResource($this->paystackHttpClient); 66 | $updatePlan = $planResource->update($createdPlan['plan_code'], ['interval' => 'weekly']); 67 | 68 | $this->assertTrue(is_array($updatePlan)); 69 | $this->assertTrue($updatePlan['status']); 70 | } 71 | 72 | /** 73 | * @depends testCreatePlanSuccessful 74 | * 75 | * @param $createdPlan 76 | */ 77 | public function testUpdatePlanThrowsException($createdPlan) 78 | { 79 | $planResource = new PlanResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 80 | $updatePlan = $planResource->update($createdPlan['plan_code'], ['interval' => 'weekly']); 81 | 82 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $updatePlan); 83 | } 84 | 85 | /** 86 | * @depends testCreatePlanSuccessful 87 | * 88 | * @param $createdPlan 89 | */ 90 | public function testGetPlanByIdSuccessful($createdPlan) 91 | { 92 | $planResource = new PlanResource($this->paystackHttpClient); 93 | $retrievedPlan = $planResource->get($createdPlan['plan_code']); 94 | 95 | $this->assertTrue(is_array($retrievedPlan)); 96 | $this->assertEquals($this->planData['amount'], $retrievedPlan['amount']); 97 | $this->assertEquals($this->planData['description'], $retrievedPlan['description']); 98 | $this->assertEquals($this->planData['name'], $retrievedPlan['name']); 99 | } 100 | 101 | /** 102 | * @depends testCreatePlanSuccessful 103 | * 104 | * @param $createdPlan 105 | */ 106 | public function testGetPlanByIdThrowsException($createdPlan) 107 | { 108 | $planResource = new PlanResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 109 | $retrievedPlan = $planResource->get($createdPlan['plan_code']); 110 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $retrievedPlan); 111 | } 112 | 113 | public function testGetAllPlansSuccessful() 114 | { 115 | $planResource = new PlanResource($this->paystackHttpClient); 116 | $retrievedPlans = $planResource->getAll(); 117 | 118 | $this->assertTrue(is_array($retrievedPlans)); 119 | $this->assertGreaterThanOrEqual(1, $retrievedPlans); 120 | $this->assertArrayHasKey('name', $retrievedPlans[0]); 121 | $this->assertArrayHasKey('amount', $retrievedPlans[0]); 122 | } 123 | 124 | public function testGetAllPlansThrowsError() 125 | { 126 | $planResource = new PlanResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 127 | $retrievedPlans = $planResource->getAll(); 128 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $retrievedPlans); 129 | } 130 | 131 | /** 132 | * @depends testCreatePlanSuccessful 133 | * 134 | * @param $createdPlan 135 | */ 136 | public function testDeletePlanReturnsA404($createdPlan) 137 | { 138 | $planResource = new PlanResource($this->paystackHttpClient); 139 | $deletePlan = $planResource->delete($createdPlan['plan_code']); 140 | $this->assertInstanceOf(PaystackNotFoundException::class, $deletePlan); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Tests/Repositories/TransactionResourceTest.php: -------------------------------------------------------------------------------- 1 | paystackHttpClient = PaystackHttpClientFactory::make(); 25 | } 26 | 27 | public function testInitializeSuccessful() 28 | { 29 | $transactionRequestBody = [ 30 | 'amount' => $this->planData['amount'], 31 | 'email' => $this->getFakedCustomerData()['email'], 32 | 'plan' => '', 33 | 'reference' => Utils::generateTransactionRef(), 34 | ]; 35 | $transactionResource = new TransactionResource($this->paystackHttpClient); 36 | $initTransaction = $transactionResource->initialize($transactionRequestBody); 37 | 38 | $this->assertArrayHasKey('reference', $initTransaction); 39 | $this->assertArrayHasKey('access_code', $initTransaction); 40 | $this->assertArrayHasKey('authorization_url', $initTransaction); 41 | 42 | return $transactionRequestBody; 43 | } 44 | 45 | public function testInitializeReturnsError() 46 | { 47 | $transactionResource = new TransactionResource($this->paystackHttpClient); 48 | $initTransaction = $transactionResource->initialize([]); 49 | $this->assertInstanceOf(PaystackValidationException::class, $initTransaction); 50 | } 51 | 52 | public function testGetAllTransactions() 53 | { 54 | $transactionResource = new TransactionResource($this->paystackHttpClient); 55 | $transactions = $transactionResource->getAll(); 56 | 57 | $this->assertGreaterThanOrEqual(1, count($transactions)); 58 | $this->assertArrayHasKey('reference', $transactions[0]); 59 | $this->assertArrayHasKey('amount', $transactions[0]); 60 | $this->assertArrayHasKey('customer', $transactions[0]); 61 | $this->assertTrue(is_array($transactions[0]['customer'])); 62 | 63 | return $transactions[0]; 64 | } 65 | 66 | public function testGetAllTransactionReturnsError() 67 | { 68 | $transactionResource = new TransactionResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 69 | $transactions = $transactionResource->getAll(); 70 | 71 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $transactions); 72 | } 73 | 74 | /** 75 | * @depends testInitializeSuccessful 76 | * 77 | * @param $initData 78 | */ 79 | public function testVerifyTransactionReturnsVerificationData($initData) 80 | { 81 | $transactionResource = new TransactionResource($this->paystackHttpClient); 82 | $transaction = $transactionResource->verify($initData['reference']); 83 | 84 | $this->assertEquals($initData['amount'], $transaction['amount']); 85 | $this->assertEquals($initData['reference'], $transaction['reference']); 86 | $this->assertArrayHasKey('status', $transaction); 87 | } 88 | 89 | /** 90 | * @depends testInitializeSuccessful 91 | * 92 | * @param $initData 93 | */ 94 | public function testVerifyTransactionReturnsError($initData) 95 | { 96 | $transactionResource = new TransactionResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 97 | $transaction = $transactionResource->verify($initData['reference']); 98 | 99 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $transaction); 100 | } 101 | 102 | /** 103 | * @depends testGetAllTransactions 104 | * 105 | * @param $transactionData 106 | */ 107 | public function testGetTransactionDetailsReturnsTransactionDetails($transactionData) 108 | { 109 | $transactionResource = new TransactionResource($this->paystackHttpClient); 110 | $transactionDetails = $transactionResource->get($transactionData['id']); 111 | 112 | $this->assertArrayHasKey('reference', $transactionDetails); 113 | $this->assertArrayHasKey('amount', $transactionDetails); 114 | $this->assertArrayHasKey('customer', $transactionDetails); 115 | $this->assertTrue(is_array($transactionDetails['customer'])); 116 | } 117 | 118 | /** 119 | * @depends testInitializeSuccessful 120 | * 121 | * @param $transactionData 122 | */ 123 | public function testGetTransactionDetailsReturnsError($transactionData) 124 | { 125 | $transactionResource = new TransactionResource($this->paystackHttpClient); 126 | $transactionDetails = $transactionResource->get($transactionData['reference']); 127 | 128 | $this->assertInstanceOf(PaystackNotFoundException::class, $transactionDetails); 129 | } 130 | 131 | public function testGetTransactionsTotals() 132 | { 133 | $transactionResource = new TransactionResource($this->paystackHttpClient); 134 | $transactionTotals = $transactionResource->getTransactionTotals(); 135 | 136 | $this->assertTrue(is_array($transactionTotals)); 137 | $this->assertArrayHasKey('total_volume', $transactionTotals); 138 | $this->assertArrayHasKey('total_transactions', $transactionTotals); 139 | $this->assertArrayHasKey('pending_transfers', $transactionTotals); 140 | } 141 | 142 | public function testGetTransactionTotalsReturnsError() 143 | { 144 | $transactionResource = new TransactionResource(PaystackHttpClientFactory::make($this->fakeAuthHeader)); 145 | $transactionTotals = $transactionResource->getTransactionTotals(); 146 | 147 | $this->assertInstanceOf(PaystackUnauthorizedException::class, $transactionTotals); 148 | $this->assertStringStartsWith('Format is Authorization', $transactionTotals->getErrors()); 149 | } 150 | 151 | public function testChargeAuthorizationReturnsError() 152 | { 153 | $transactionResource = new TransactionResource($this->paystackHttpClient); 154 | $chargeAuthorization = $transactionResource->chargeAuthorization([]); 155 | 156 | $this->assertInstanceOf(PaystackValidationException::class, $chargeAuthorization); 157 | } 158 | 159 | public function tearDown() 160 | { 161 | parent::tearDown(); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Change Log # 2 | 3 | ##Version## 4 | 1.0.0 5 | 6 | ###Changes### 7 | - Allow paystack keys to be specified when creating Paystack Library Object, so you can do; 8 | 9 | $paystackLibObject = \MAbiola\Paystack\Paystack::make("my-paystack-private-key"); 10 | 11 | - Allow CURL SSL verification to be disabled during local test mode 12 | 13 | 14 | ##Version## 15 | 1.0.1 16 | 17 | ###Changes### 18 | - Fix issue with transaction reference generation by adding dependency that could be causing issue 19 | - made changes to resource class because of Paystack's API change in plan update response 20 | - fixed test 21 | 22 | ___ -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mabiola/paystack-php-lib", 3 | "version": "1.0.1", 4 | "description": "A PHP Library for https://paystack.co", 5 | "keywords": ["library", "Paystack"], 6 | "type": "library", 7 | "require": { 8 | "vlucas/phpdotenv": "~2.2", 9 | "illuminate/support": "~5.1-dev", 10 | "illuminate/http": "~5.1-dev", 11 | "guzzlehttp/guzzle": "~6.0", 12 | "ramsey/uuid": "~3.5", 13 | "moontoast/math": "*" 14 | }, 15 | "require-dev": { 16 | "phpunit/phpunit": "~4.0", 17 | "mockery/mockery": "~0.9", 18 | "fzaninotto/faker" : "~1.0" 19 | }, 20 | "license": "MIT", 21 | "authors": [ 22 | { 23 | "name": "Malik Abiola", 24 | "email": "abiola.malik@gmail.com" 25 | } 26 | ], 27 | "autoload": { 28 | "psr-4": { 29 | "MAbiola\\Paystack\\": "src/", 30 | "MAbiola\\Paystack\\Tests\\": "Tests/" 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | ./Tests/ 18 | 19 | 20 | 21 | 22 | src/ 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 35 | -------------------------------------------------------------------------------- /phpunit_bootstrap.php: -------------------------------------------------------------------------------- 1 | load(); 5 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # PHP Library For [Paystack.co](http://paystack.co "Paystack.co") (Unofficial) # 2 | A PHP library for Paystack. 3 | 4 | **This library is no longer maintained. Please use the official library.** 5 | 6 | [![Build Status](https://travis-ci.org/MalikAbiola/paystack-php-lib.svg?branch=master)](https://travis-ci.org/MalikAbiola/paystack-php-lib) 7 | [![Coverage Status](https://coveralls.io/repos/github/MalikAbiola/paystack-php-lib/badge.svg?branch=master)](https://coveralls.io/github/MalikAbiola/paystack-php-lib?branch=master) 8 | # Requirements # 9 | 10 | - PHP 5.5+ 11 | - [Composer](https://getcomposer.org/doc/00-intro.md "Composer") 12 | 13 | # Installation # 14 | 15 | ### Via Composer ### 16 | Add the following to your `composer.json` file and run `composer install` 17 | 18 | "mabiola/paystack-php-lib" : "~1.0" 19 | 20 | Then use composer's autoload. 21 | 22 | require_once __DIR__ . '/vendor/autoload.php'; 23 | 24 | **NOTE:** if you are using a PHP Framework for example, [Laravel](https://laravel.com/), you do not need to add the composer autoload to your file(s) as it is already done. (see it in `bootstrap/autoload`; `bootstrap/app.php` for Lumen; ). 25 | 26 | ### Other Installation Methods ### 27 | 28 | **No other installation methods! Use composer!** 29 | 30 | **Why?** 31 | 32 | - It's doing PHP the right way! 33 | - It's the right thing to do. 34 | - If you still need convincing, [this](http://blog.nelm.io/2011/12/composer-part-1-what-why/) might help. 35 | 36 | Seriously, please... use composer. Thank you. 37 | 38 | # Configurations # 39 | 40 | Add the following keys to your .env file. 41 | 42 | #PAYSTACK LIB MODE [test | live] 43 | PAYSTACK_MODE = test 44 | #YOUR PAYSTACK KEYS 45 | PAYSTACK_LIVE_PUBLIC_KEY = my_paystack_live_public_keys 46 | PAYSTACK_LIVE_SECRET_KEY = my_paystack_live_secret_key 47 | PAYSTACK_TEST_PUBLIC_KEY = my_paystack_test_public_key 48 | PAYSTACK_TEST_SECRET_KEY = my_paystack_test_secret_key 49 | 50 | Replace the keys with your actual Paystack keys - you can find this on the `Developer/API` panel of your `settings` page. Use the `PAYSTACK_MODE` to switch between `live` and `test` mode for Paystack. 51 | 52 | That's is! You are ready to receive payments! 53 | 54 | # Usage # 55 | 56 | Using the library is simple, make a Paystack Library object and use this object to perform operations on Paystack. 57 | To create the Paystack Library object, do; 58 | 59 | $paystackLibObject = \MAbiola\Paystack\Paystack::make(); 60 | 61 | or if you'd rather provide the exact key (if you are not using an env file); 62 | 63 | $paystackLibObject = \MAbiola\Paystack\Paystack::make("my-paystack-private-key"); 64 | 65 | Now lets walk through some of the operations you can perform with the object you just created. 66 | 67 | 1. **Initialize a One Time Transaction** 68 | 69 | According to [Paystack's documentation](https://developers.paystack.co/docs/), to charge a customer, you create a one time transaction for which you get an authorization url which you redirect your page to so that your customer can enter their card details and pay for your service(s). To do this with the library, pass the amount to be charged, the customer email, and the optional plan (if this is a transaction to create a subscription. you can either enter the plan code here or the plan object - more on this coming soon). 70 | 71 | $getAuthorization = $paystackLibObject->startOneTimeTransaction('10000', 'me@me.com'); 72 | 73 | You will expect an array that contains the authorization url `authorization_url` to redirect to to accept this payment, and the unique auto-generated transaction reference `reference`. 74 | 75 | 2. **Verify Transactions** 76 | 77 | To verify a transaction, simply call the function like; 78 | 79 | $verifyTransaction = $paystackLibObject->verifyTransaction('unique_transaction_ref'); 80 | 81 | if transaction is successful, this function returns an array containing the transaction details else ` $verifyTransaction ` will be ` false `. 82 | 83 | 3. **Charging Returning Customers** 84 | 85 | Now, when you successfully charge a customer, an authorization key that represents the card of the customer is generated - you can find this in the array you get back when you verify a transaction. Therefore, the next time you want to charge this customer, you can use this authorization code to charge said customer. To do this, just call the function like; 86 | 87 | $chargeReturningCustomer = $paystackLibObject->chargeReturningTransaction('authorization_code', 'me@me.com', '10000'); 88 | 89 | if transaction is successful, this function returns an array containing the transaction details. 90 | 91 | 4. **Customer** 92 | 93 | - **Retrieve Customer Data** 94 | 95 | You can retrieve customer details by passing the customer code to the `getCustomer` to get a customer object. 96 | 97 | 98 | $customer = $paystackLibObject->getCustomer('customer_code'); 99 | 100 | If the operation is successful, you get a customer object which you can call a `$newCustomer->toArray()` to get the details as an array or you can do a `get` passing an attribute to retrieve, or a list of attributes as arguments or an array of attributes. e.g. `$newCustomer->get(['first_name', 'customer_code', 'subscriptions', 'authorizations']);` or `$newCustomer->get('subscriptions');` 101 | 102 | - **Create Customer** 103 | 104 | To create a customer, pass the customer first name, last name, email and phone to the `createCustomer` method, like; 105 | 106 | 107 | $newCustomer = $paystackLibObject->createCustomer('first_name', 'last_name', 'email', 'phone'); 108 | 109 | If the operation is successful, a customer object is returned. 110 | 111 | - **Update Customer Data** 112 | 113 | You can update the customer details by passing the customer code and update data as an array with attributes to update as keys and the update value as the value to the `updateCustomerData` method, like; 114 | 115 | $updatedCustomer = $paystackLibObject->updateCustomerData('customer_code',['last_name' => 'new_last_name']); 116 | 117 | If the operation is successful, the customer object is returned. 118 | 119 | - **Retrieve All Customers** 120 | 121 | To retrieve all your customers, call the `getCustomers` method on the PaystackLibObject. Expect an array of customer objects. 122 | 123 | $myCustomers = $paystackLibObject->getCustomers(); 124 | 125 | 5. **Plans** 126 | 127 | - **Retrieve Plan Details** 128 | 129 | You can retrieve the details of a plan by passing the plan code to the `getPlan` to get a plan object. 130 | 131 | 132 | $plan = $paystackLibObject->getPlan('plan_code'); 133 | 134 | If the operation is successful, you get a plan object which you can call a `$plan->toArray()` on to get the details as an array or you can do a `get`, passing an attribute to retrieve, or a list of attributes as arguments or an array of attributes. e.g. `$plan->get(['name', 'plan_code', 'subscriptions', 'hosted_page_url']);` or `$plan->get('subscriptions');` 135 | 136 | - **Create A New Plan** 137 | 138 | To create a plan, pass the plan's name, description, amount (not in kobo apparently) and the currency (NGN | USD) to the `createPlan` method, like; 139 | 140 | 141 | $newPlan = $paystackLibObject->createPlan('Random_Plan_1000', 'Random 1000NGN Plan', '1000', 'NGN'); 142 | 143 | If the operation is successful, a plan object is returned. 144 | 145 | - **Update Plan Data** 146 | 147 | You can update the plan details by passing the plan code and update data as an array with attributes to update as keys and the update value as the value to the `updatePlan` method, like; 148 | 149 | $updatedPlan = $paystackLibObject->updatePlan('plan_code', ['hosted_page_url' => 'http://somerandomu.rl', 'hosted_page' => true]); 150 | 151 | If the operation is successful, the plan object is returned. 152 | 153 | - **Retrieve All Plans** 154 | 155 | To retrieve all your plans, call the `getPlans` method on the PaystackLibObject. Expect an array of plans objects. 156 | 157 | $myPlans = $paystackLibObject->getPlans(); 158 | 159 | 6. **Other Transactions Operations** 160 | 161 | - **Get Details of A Transaction** 162 | To get the details of a transaction, pass the transaction id to the `transactionDetails` function. Expect a transaction object on success or a thrown exception. And as usual you can perform the `toArray` and `get` operations on it as you can on the customer and plan objects. Also, you can call `verify()` on this object to verify the transaction. 163 | 164 | $transactionDetails = $paystackLibObject->transactionDetails('transaction_id'); 165 | 166 | - **Get All Transactions** 167 | To retrieve all transactions, call the `allTranactions` function on the paystack library object. An array of transaction objects is returned on success or an exception thrown on error. 168 | 169 | $allMyTransactions = $paystackLibObject->allTransactions(); 170 | 171 | - **Transaction Totals** 172 | To get a cummulative view of your successful transactions, use the `transactionTotals` function. An array with `total_volume`, `total_transactions`, and `pending_transfers` as keys is returned. or ofcourse, an exception when something goes wrong. 173 | 174 | $totals = $paystackLibObject->transactionsTotals(); 175 | 176 | 7. **Exceptions** 177 | 178 | Errors are bound to occur, but not to worry, the library contain descriptive exceptions and methods/functions to get the error details. To get the error message when an exception is thrown, call `getErrors()` on the exception object. e.g. 179 | 180 | try { 181 | $paystackLibObject->getPlan('plan_code'); 182 | } catch (PaystackNotFoundException $e) { 183 | print_r($e->getErrors()); 184 | } 185 | 186 | Possible Exceptions; 187 | 188 | - **PaystackInternalServerError** 189 | - **PaystackInvalidTransactionException:** Thrown when a unique transaction reference could not be generated. 190 | - **PaystackNotFoundException:** Thrown when the requested object/resource can not be found 191 | - **PaystackUnauthorizedException:** Thrown when the authorization keys can not be found. 192 | - **PaystackUnsupportedOperationException:** Thrown when the operation you are trying to perform is not supported by Paystack. 193 | - **PaystackValidationException:** Thrown when validation errors occur. You can view validation errors by calling `getValidationErrors()` on the exception object. `getValidationErrors()` returns an array with attributes failing validation and the reasons. 194 | 195 | # Contributing # 196 | 197 | I very much welcome your contributions, fork and send me a pull request. Remember to write tests. Or you can open issues to report bugs. 198 | 199 | Also, if you like this library, star the repo. Or if you have questions or just want to give me a shout, you can reach me on [twitter](https://twitter.com/MalikAbiola_) 200 | 201 | # License # 202 | 203 | MIT. 204 | -------------------------------------------------------------------------------- /src/Abstractions/BaseTransaction.php: -------------------------------------------------------------------------------- 1 | transactionResource ?: new TransactionResource(PaystackHttpClientFactory::make()); 28 | } 29 | 30 | /** 31 | * Set transaction resource. 32 | * 33 | * @param mixed $transactionResource 34 | */ 35 | public function setTransactionResource(TransactionResource $transactionResource) 36 | { 37 | $this->transactionResource = $transactionResource; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Abstractions/Model.php: -------------------------------------------------------------------------------- 1 | 1) { 49 | //recalls itself to get attributes as array 50 | return call_user_func([get_class(), 'get'], $argsAsArray); 51 | } 52 | //if just args is not an array or comma separated list 53 | if (!is_array($attributes) && count($argsAsArray) == 1) { 54 | return isset($this->{$attributes}) ? $this->{$attributes} : null; 55 | } 56 | 57 | $attributesGet = []; 58 | foreach ($attributes as $attribute) { 59 | $attributesGet[$attribute] = isset($this->{$attribute}) ? $this->{$attribute} : null; 60 | } 61 | 62 | return $attributesGet; 63 | } 64 | 65 | /** 66 | * Set attributes of the model. 67 | * 68 | * @param $attributes 69 | * 70 | * @throws \Exception 71 | * 72 | * @return $this 73 | */ 74 | public function _setAttributes($attributes) 75 | { 76 | if (is_array($attributes)) { 77 | foreach ($attributes as $attribute => $value) { 78 | $this->{$attribute} = $value; 79 | } 80 | 81 | return $this; 82 | } 83 | 84 | //@todo: put real exception here cos exception' gon be thrown either ways, so put one that makes sense 85 | //or something else that has more meaning 86 | throw new \InvalidArgumentException('Invalid argument Passed to set attributes on object'); 87 | } 88 | 89 | /** 90 | * get Outward presentation of object. 91 | * 92 | * @param $transformMode 93 | * 94 | * @return mixed 95 | */ 96 | public function transform($transformMode = '') 97 | { 98 | switch ($transformMode) { 99 | case ModelInterface::TRANSFORM_TO_JSON_ARRAY: 100 | return json_encode($this->objectToArray($this)); 101 | default: 102 | return $this->objectToArray($this); 103 | } 104 | } 105 | 106 | /** 107 | * Explicitly convert model object to array. 108 | * 109 | * @return array 110 | */ 111 | public function toArray() 112 | { 113 | return $this->objectToArray($this); 114 | } 115 | 116 | /** 117 | * check if model is updatable. 118 | * 119 | * @return bool 120 | */ 121 | public function isUpdateable() 122 | { 123 | return $this->updateable; 124 | } 125 | 126 | /** 127 | * set model updateable. 128 | * 129 | * @param bool $updateable 130 | */ 131 | protected function setUpdateable($updateable) 132 | { 133 | $this->updateable = $updateable; 134 | } 135 | 136 | /** 137 | * check if model can be created. 138 | * 139 | * @return bool 140 | */ 141 | public function isCreatable() 142 | { 143 | return $this->creatable; 144 | } 145 | 146 | /** 147 | * set model can be created. 148 | * 149 | * @param bool $creatable 150 | */ 151 | protected function setCreatable($creatable) 152 | { 153 | $this->creatable = $creatable; 154 | } 155 | 156 | /** 157 | * check if model is deletable. 158 | * 159 | * @return bool 160 | */ 161 | public function isDeletable() 162 | { 163 | return $this->deletable; 164 | } 165 | 166 | /** 167 | * set model deletable. 168 | * 169 | * @param bool $deletable 170 | */ 171 | protected function setDeletable($deletable) 172 | { 173 | $this->deletable = $deletable; 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/Abstractions/Resource.php: -------------------------------------------------------------------------------- 1 | getBody()->getContents()); 38 | 39 | if (Response::HTTP_OK !== $request->getStatusCode() && Response::HTTP_CREATED !== $request->getStatusCode()) { 40 | return ExceptionHandler::handle(get_class($this), $response, $request->getStatusCode()); 41 | } 42 | 43 | return (isset($response->data)) ? json_decode(json_encode($response->data), true) : json_decode(json_encode($response), true); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Contracts/ModelInterface.php: -------------------------------------------------------------------------------- 1 | getMessage(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Exceptions/ExceptionHandler.php: -------------------------------------------------------------------------------- 1 | response = $response; 15 | parent::__construct(isset($response->message) ? $response->message : 'Gateway Timeout Error', $code); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Exceptions/PaystackInvalidTransactionException.php: -------------------------------------------------------------------------------- 1 | message, $code); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Exceptions/PaystackNotFoundException.php: -------------------------------------------------------------------------------- 1 | message) ? $response->message : 'Resource Not Found', $code); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Exceptions/PaystackUnauthorizedException.php: -------------------------------------------------------------------------------- 1 | message, $code); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Exceptions/PaystackUnsupportedOperationException.php: -------------------------------------------------------------------------------- 1 | response = $response; 17 | parent::__construct($response->message, $code); 18 | } 19 | 20 | /** 21 | * Get validation errors that occurred in requests. 22 | * 23 | * @return array 24 | */ 25 | public function getValidationErrors() 26 | { 27 | $errors = []; 28 | if (isset($this->response->errors)) { 29 | foreach ($this->response->errors as $error => $reasons) { 30 | $errors[] = [ 31 | 'attribute' => $error, 32 | 'reason' => $this->getValidationReasonsAsString($reasons), 33 | ]; 34 | } 35 | } 36 | 37 | return $errors; 38 | } 39 | 40 | private function getValidationReasonsAsString($reasons) 41 | { 42 | $concatenatedReasons = ''; 43 | 44 | foreach ($reasons as $reason) { 45 | $concatenatedReasons .= "{$reason->message} \r\n"; 46 | } 47 | 48 | return $concatenatedReasons; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Factories/PaystackHttpClientFactory.php: -------------------------------------------------------------------------------- 1 | 'https://api.paystack.co', 29 | 'headers' => [ 30 | 'Authorization' => 'Bearer '.$authorization, 31 | 'Content-Type' => 'application/json', 32 | ], 33 | 'http_errors' => false, 34 | 'verify' => self::env('PAYSTACK_MODE') == 'test' ? false : true, //add so local developments can work 35 | 'handler' => HandlerStack::create(new CurlHandler()), //use native curl 36 | ]; 37 | 38 | if (!empty($config)) { 39 | $defaults = array_merge($defaults, $config); 40 | } 41 | 42 | return new Client($defaults); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Helpers/Transaction.php: -------------------------------------------------------------------------------- 1 | getTransactionResource()->verify($transactionRef); 33 | 34 | if ($transactionData instanceof \Exception) { 35 | throw $transactionData; 36 | } 37 | 38 | if ($transactionData['status'] == TransactionContract::TRANSACTION_STATUS_SUCCESS) { 39 | return [ 40 | 'authorization' => $transactionData['authorization'], 41 | 'customer' => $transactionData['customer'], 42 | 'amount' => $transactionData['amount'], 43 | 'plan' => $transactionData['plan'], 44 | ]; 45 | } 46 | 47 | return false; 48 | } 49 | 50 | /** 51 | * Get transaction details. 52 | * 53 | * @param $transactionId 54 | * 55 | * @throws \Exception|mixed 56 | * 57 | * @return \MAbiola\Paystack\Models\Transaction 58 | */ 59 | public function details($transactionId) 60 | { 61 | $transactionData = $this->getTransactionResource()->get($transactionId); 62 | 63 | if ($transactionData instanceof \Exception) { 64 | throw $transactionData; 65 | } 66 | 67 | return TransactionObject::make($transactionData); 68 | } 69 | 70 | /** 71 | * Get all transactions. per page. 72 | * 73 | * @param $page 74 | * 75 | * @throws \Exception|mixed 76 | * 77 | * @return array 78 | */ 79 | public function allTransactions($page) 80 | { 81 | $transactions = []; 82 | $transactionData = $this->getTransactionResource()->getAll($page); 83 | 84 | if ($transactionData instanceof \Exception) { 85 | throw $transactionData; 86 | } 87 | 88 | foreach ($transactionData as $transaction) { 89 | $transactions[] = TransactionObject::make($transaction); 90 | } 91 | 92 | return $transactions; 93 | } 94 | 95 | /** 96 | * Get merchant transaction total. 97 | * 98 | * @throws \Exception 99 | * 100 | * @return mixed 101 | */ 102 | public function transactionsTotals() 103 | { 104 | $transactions = $this->getTransactionResource()->getTransactionTotals(); 105 | if ($transactions instanceof \Exception) { 106 | throw $transactions; 107 | } 108 | 109 | return $transactions; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/Helpers/Utils.php: -------------------------------------------------------------------------------- 1 | toString()); 52 | } catch (UnsatisfiedDependencyException $e) { 53 | return null; 54 | } 55 | } 56 | 57 | /** 58 | * Converts a bowl of object to an array. 59 | * 60 | * @todo: replace with function that only shows accessible properties of the object 61 | * 62 | * @param $object 63 | * 64 | * @return array 65 | */ 66 | public function objectToArray($object) 67 | { 68 | if (!is_object($object) && !is_array($object)) { 69 | return $object; 70 | } 71 | if (is_object($object)) { 72 | $object = get_object_vars($object); 73 | } 74 | 75 | return array_map([get_class(), 'objectToArray'], $object); 76 | } 77 | 78 | /** 79 | * Gets the value of an environment variable. Supports boolean, empty and null. 80 | * From Laravel/lumen-framework/src/helpers.php. 81 | * 82 | * @param string $key 83 | * @param mixed $default 84 | * 85 | * @return mixed 86 | */ 87 | public static function env($key, $default = null) 88 | { 89 | $value = getenv($key); 90 | if ($value === false) { 91 | return value($default); 92 | } 93 | switch (strtolower($value)) { 94 | case 'true': 95 | case '(true)': 96 | return true; 97 | case 'false': 98 | case '(false)': 99 | return false; 100 | case 'empty': 101 | case '(empty)': 102 | return ''; 103 | case 'null': 104 | case '(null)': 105 | return; 106 | } 107 | if (Str::startsWith($value, '"') && Str::endsWith($value, '"')) { 108 | return substr($value, 1, -1); 109 | } 110 | 111 | return $value; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/Models/Customer.php: -------------------------------------------------------------------------------- 1 | customerResource = $customerResource; 26 | } 27 | 28 | /** 29 | * Get customer by ID. 30 | * 31 | * @param $customerId 32 | * 33 | * @throws \Exception|mixed 34 | * 35 | * @return $this 36 | */ 37 | public function getCustomer($customerId) 38 | { 39 | //retrieve customer, set customer attributes 40 | $customerModel = $this->customerResource->get($customerId); 41 | if ($customerModel instanceof \Exception) { 42 | throw $customerModel; 43 | } 44 | 45 | $this->_setAttributes($customerModel); 46 | $this->setDeletable(true); 47 | 48 | return $this; 49 | } 50 | 51 | /** 52 | * set up a new customer object. 53 | * 54 | * @param $first_name 55 | * @param $last_name 56 | * @param $email 57 | * @param $phone 58 | * @param array $otherAttributes 59 | * 60 | * @return $this 61 | */ 62 | public function make($first_name, $last_name, $email, $phone, $otherAttributes = []) 63 | { 64 | $this->first_name = $first_name; 65 | $this->last_name = $last_name; 66 | $this->email = $email; 67 | $this->phone = $phone; 68 | 69 | $this->_setAttributes($otherAttributes); 70 | //set creatable 71 | $this->setCreatable(true); 72 | 73 | return $this; 74 | } 75 | 76 | /** 77 | * set update data on customer model. 78 | * 79 | * @param $updateAttributes 80 | * 81 | * @throws \Exception 82 | * 83 | * @return $this 84 | */ 85 | public function setUpdateData($updateAttributes) 86 | { 87 | if (empty($updateAttributes)) { 88 | throw new \InvalidArgumentException('Update Attributes Empty'); 89 | } 90 | 91 | $this->_setAttributes($updateAttributes); 92 | $this->setUpdateable(true); 93 | 94 | return $this; 95 | } 96 | 97 | /** 98 | * save/update customer model on paystack. 99 | * 100 | * @throws \Exception 101 | * @throws \Exception|mixed 102 | * @throws null 103 | * 104 | * @return $this 105 | */ 106 | public function save() 107 | { 108 | $resourceResponse = null; 109 | 110 | if ($this->isCreatable() && !$this->isUpdateable()) { //available for creation 111 | $resourceResponse = $this->customerResource->save( 112 | $this->transform(ModelInterface::TRANSFORM_TO_JSON_ARRAY) 113 | ); 114 | } 115 | 116 | if ($this->isUpdateable() && !$this->isCreatable()) { //available for update 117 | $resourceResponse = $this->customerResource->update( 118 | $this->customerId, 119 | $this->transform(ModelInterface::TRANSFORM_TO_JSON_ARRAY) 120 | ); 121 | } 122 | 123 | if ($resourceResponse == null) { 124 | throw new \InvalidArgumentException('You Cant Perform This Operation on an empty customer object'); 125 | } 126 | 127 | if ($resourceResponse instanceof \Exception) { 128 | throw $resourceResponse; 129 | } 130 | 131 | return $this->_setAttributes($resourceResponse); 132 | } 133 | 134 | /** 135 | * delete customer. 136 | * 137 | * @throws \Exception 138 | * @throws \Exception|mixed 139 | * 140 | * @return $this 141 | */ 142 | public function delete() 143 | { 144 | // if ($this->isDeletable()) { 145 | // $resourceResponse = $this->customerResource->delete($this->customerId); 146 | // if ($resourceResponse instanceof \Exception) { 147 | // throw $resourceResponse; 148 | // } 149 | // 150 | // return !!$resourceResponse['status']; 151 | // } 152 | 153 | throw new PaystackUnsupportedOperationException("Customer can't be deleted", 405); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/Models/OneTimeTransaction.php: -------------------------------------------------------------------------------- 1 | transactionRef = $transactionRef; 35 | $this->amount = $amount; 36 | $this->email = $email; 37 | $this->plan = $plan; 38 | 39 | // $this->transactionResource = $transactionResource; 40 | } 41 | 42 | /** 43 | * Make a new one time transaction object. 44 | * 45 | * @param $amount 46 | * @param $email 47 | * @param $plan 48 | * 49 | * @return static 50 | */ 51 | public static function make($amount, $email, $plan) 52 | { 53 | return new static(self::generateTransactionRef(), $amount, $email, $plan); 54 | } 55 | 56 | /** 57 | * Initialize one time transaction to get payment url. 58 | * 59 | * @return \Exception|mixed|PaystackInvalidTransactionException 60 | */ 61 | public function initialize() 62 | { 63 | return !is_null($this->transactionRef) ? 64 | $this->getTransactionResource()->initialize($this->_requestPayload()) : 65 | new PaystackInvalidTransactionException( 66 | json_decode( 67 | json_encode( 68 | [ 69 | 'message' => 'Transaction Reference Not Generated.', 70 | ] 71 | ), 72 | false 73 | ) 74 | ); 75 | } 76 | 77 | /** 78 | * Get transaction request body. 79 | * 80 | * @return string 81 | */ 82 | public function _requestPayload() 83 | { 84 | $payload = [ 85 | 'amount' => $this->amount, 86 | 'reference' => $this->transactionRef, 87 | 'email' => $this->email, 88 | ]; 89 | 90 | if (!empty($this->plan)) { 91 | $payload['plan'] = $this->plan; 92 | } 93 | 94 | return $this->toJson($payload); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Models/Plan.php: -------------------------------------------------------------------------------- 1 | planResource = $planResource; 52 | } 53 | 54 | /** 55 | * Get plan by plan code. 56 | * 57 | * @param $planCode 58 | * 59 | * @throws 60 | * @throws \Exception 61 | * 62 | * @return $this 63 | */ 64 | public function getPlan($planCode) 65 | { 66 | $plan = $this->planResource->get($planCode); 67 | if ($plan instanceof \Exception) { 68 | throw $plan; 69 | } 70 | 71 | $this->setDeletable(true); 72 | 73 | return $this->_setAttributes($plan); 74 | } 75 | 76 | /** 77 | * Create new Plan Object. 78 | * 79 | * @param $name 80 | * @param $description 81 | * @param $amount 82 | * @param $currency 83 | * @param array $otherAttributes 84 | * 85 | * @return $this 86 | */ 87 | public function make($name, $description, $amount, $currency, array $otherAttributes = []) 88 | { 89 | $this->name = $name; 90 | $this->description = $description; 91 | $this->amount = $amount; 92 | $this->currency = $currency; 93 | 94 | $this->_setAttributes($otherAttributes); 95 | $this->setCreatable(true); 96 | 97 | return $this; 98 | } 99 | 100 | /** 101 | * set attributes to update. 102 | * 103 | * @param array $updateData 104 | * 105 | * @return $this 106 | */ 107 | public function setUpdateData(array $updateData) 108 | { 109 | $this->_setAttributes($updateData); 110 | $this->setUpdateable(true); 111 | 112 | return $this; 113 | } 114 | 115 | /** 116 | * Save/Update plan object. 117 | * 118 | * @throws \Exception 119 | * @throws \Exception|mixed 120 | * @throws null 121 | * 122 | * @return $this|Plan 123 | */ 124 | public function save() 125 | { 126 | $resourceResponse = null; 127 | 128 | if ($this->isCreatable() && !$this->isUpdateable()) { //available for creation 129 | $resourceResponse = $this->planResource->save($this->transform(ModelInterface::TRANSFORM_TO_JSON_ARRAY)); 130 | } 131 | 132 | if ($this->isUpdateable() && !$this->isCreatable()) { //available for update 133 | $resourceResponse = $this->planResource->update( 134 | $this->plan_code, 135 | $this->transform(ModelInterface::TRANSFORM_TO_JSON_ARRAY) 136 | ); 137 | } 138 | 139 | if ($resourceResponse == null) { 140 | throw new \InvalidArgumentException('You Cant Perform This Operation on an empty plan'); 141 | } 142 | 143 | if ($resourceResponse instanceof \Exception) { 144 | throw $resourceResponse; 145 | } 146 | 147 | return $this->_setAttributes($resourceResponse); 148 | } 149 | 150 | /** 151 | * delete Plan. 152 | * 153 | * @throws \Exception 154 | * 155 | * @return $this 156 | */ 157 | public function delete() 158 | { 159 | // if ($this->isDeletable()) { 160 | // $resourceResponse = $this->planResource->delete($this->plan_code); 161 | // if ($resourceResponse instanceof \Exception) { 162 | // throw $resourceResponse; 163 | // } 164 | // 165 | // return !!$resourceResponse['status']; 166 | // } 167 | 168 | throw new PaystackUnsupportedOperationException("Plan can't be deleted", 405); 169 | } 170 | 171 | /** 172 | * Outward presentation of object. 173 | * 174 | * @param $transformMode 175 | * 176 | * @return mixed 177 | */ 178 | public function transform($transformMode = '') 179 | { 180 | $planObject = [ 181 | 'plan_code' => $this->plan_code, 182 | 'name' => $this->name, 183 | 'description' => $this->description, 184 | 'amount' => $this->amount, 185 | 'interval' => $this->interval, 186 | 'currency' => $this->currency, 187 | 'hosted_page' => $this->hosted_page, 188 | 'hosted_page_url' => $this->hosted_page_url, 189 | 'hosted_page_summary' => $this->hosted_page_summary, 190 | 'subscription_count' => count($this->subscriptions), 191 | ]; 192 | switch ($transformMode) { 193 | case ModelInterface::TRANSFORM_TO_JSON_ARRAY: 194 | return json_encode($planObject); 195 | default: 196 | return $planObject; 197 | } 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/Models/ReturningTransaction.php: -------------------------------------------------------------------------------- 1 | transactionRef = $transactionRef; 43 | $this->authorization = $authorization; 44 | $this->amount = $amount; 45 | $this->email = $email; 46 | $this->plan = $plan; 47 | } 48 | 49 | /** 50 | * Create a new returning transaction object. 51 | * 52 | * @param $authorization 53 | * @param $amount 54 | * @param $email 55 | * @param $plan 56 | * 57 | * @return static 58 | */ 59 | public static function make($authorization, $amount, $email, $plan) 60 | { 61 | return new static( 62 | self::generateTransactionRef(), 63 | $authorization, 64 | $amount, 65 | $email, 66 | $plan 67 | ); 68 | } 69 | 70 | /** 71 | * Charge returning transaction. 72 | * 73 | * @return \Exception|mixed|PaystackInvalidTransactionException 74 | */ 75 | public function charge() 76 | { 77 | return !is_null($this->transactionRef) ? 78 | $this->getTransactionResource()->chargeAuthorization($this->_requestPayload()) : 79 | new PaystackInvalidTransactionException( 80 | json_decode( 81 | json_encode( 82 | [ 83 | 'message' => 'Transaction Reference Not Generated.', 84 | ] 85 | ), 86 | false 87 | ) 88 | ); 89 | } 90 | 91 | /** 92 | * Get returning transaction request body. 93 | * 94 | * @return string 95 | */ 96 | public function _requestPayload() 97 | { 98 | $payload = [ 99 | 'authorization_code' => $this->authorization, 100 | 'amount' => $this->amount, 101 | 'reference' => $this->transactionRef, 102 | 'email' => $this->email, 103 | ]; 104 | 105 | if (!empty($this->plan)) { 106 | $payload['plan'] = $this->plan; 107 | } 108 | 109 | return $this->toJson($payload); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/Models/Transaction.php: -------------------------------------------------------------------------------- 1 | _setAttributes($attributes); 24 | } 25 | 26 | /** 27 | * make new transaction object. 28 | * 29 | * @param $attributes 30 | * 31 | * @return static 32 | */ 33 | public static function make($attributes) 34 | { 35 | return new static($attributes); 36 | } 37 | 38 | /** 39 | * Verify this transaction. 40 | */ 41 | public function verify() 42 | { 43 | return TransactionHelper::make()->verify($this->get('reference')); 44 | } 45 | 46 | /** 47 | * convert transaction object to array. 48 | * 49 | * @return mixed 50 | */ 51 | public function _toArray() 52 | { 53 | return $this->transform(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Paystack.php: -------------------------------------------------------------------------------- 1 | paystackHttpClient = $this->makePaystackHttpClient($key); 38 | 39 | $this->customerResource = new CustomerResource($this->paystackHttpClient); 40 | $this->customerModel = new Customer($this->customerResource); 41 | 42 | $this->transactionResource = new TransactionResource($this->paystackHttpClient); 43 | 44 | $this->planResource = new PlanResource($this->paystackHttpClient); 45 | $this->planModel = new Plan($this->planResource); 46 | 47 | $this->transactionHelper = TransactionHelper::make(); 48 | $this->transactionHelper->setTransactionResource($this->transactionResource); 49 | } 50 | 51 | /** 52 | * Make a new Paystack library object. 53 | * 54 | * @param null $key 55 | * 56 | * @return Paystack 57 | */ 58 | public static function make($key = null) 59 | { 60 | return new self($key); 61 | } 62 | 63 | /** 64 | * Get customer by ID. 65 | * 66 | * @param $customerId 67 | * 68 | * @throws \Exception|mixed 69 | * 70 | * @return Customer | \Exception 71 | */ 72 | public function getCustomer($customerId) 73 | { 74 | return $this->getCustomerModel()->getCustomer($customerId); 75 | } 76 | 77 | /** 78 | * Get all customers. 79 | * 80 | * @param string $page 81 | * 82 | * @throws \Exception|mixed 83 | * 84 | * @return \Exception|mixed 85 | */ 86 | public function getCustomers($page = '') 87 | { 88 | $customerObjects = []; 89 | $customers = $this->getCustomerResource()->getAll($page); 90 | 91 | if ($customers instanceof \Exception) { 92 | throw $customers; 93 | } 94 | 95 | foreach ($customers as $customer) { 96 | $customerObject = new Customer($this->getCustomerResource()); 97 | $customerObjects[] = $customerObject->_setAttributes($customer); 98 | } 99 | 100 | return $customerObjects; 101 | } 102 | 103 | /** 104 | * Create new customer. 105 | * 106 | * @param $first_name 107 | * @param $last_name 108 | * @param $email 109 | * @param $phone 110 | * 111 | * @throws \Exception|mixed 112 | * @throws null 113 | * 114 | * @return mixed 115 | */ 116 | public function createCustomer($first_name, $last_name, $email, $phone) 117 | { 118 | return $this->getCustomerModel()->make($first_name, $last_name, $email, $phone)->save(); 119 | } 120 | 121 | /** 122 | * Update customer by customer id/code. 123 | * 124 | * @param $customerId 125 | * @param array $updateData 126 | * 127 | * @throws \Exception|mixed 128 | * @throws null 129 | * 130 | * @return mixed 131 | */ 132 | public function updateCustomerData($customerId, $updateData) 133 | { 134 | return $this->getCustomerModel()->getCustomer($customerId) 135 | ->setUpdateData($updateData) 136 | ->save(); 137 | } 138 | 139 | /** 140 | * Delete customer by Id/Code. 141 | * 142 | * @param $customerId 143 | * 144 | * @return mixed 145 | */ 146 | public function deleteCustomer($customerId) 147 | { 148 | return $this->getCustomerModel()->getCustomer($customerId)->delete(); 149 | } 150 | 151 | /** 152 | * Get plan by plan id/code. 153 | * 154 | * @param $planCode 155 | * 156 | * @throws \Exception|mixed 157 | * 158 | * @return mixed 159 | */ 160 | public function getPlan($planCode) 161 | { 162 | return $this->getPlanModel()->getPlan($planCode); 163 | } 164 | 165 | /** 166 | * Get all plans. 167 | * 168 | * @param string $page 169 | * 170 | * @throws \Exception|mixed 171 | * 172 | * @return \Exception|mixed 173 | */ 174 | public function getPlans($page = '') 175 | { 176 | $planObjects = []; 177 | $plans = $this->getPlanResource()->getAll($page); 178 | 179 | if ($plans instanceof \Exception) { 180 | throw $plans; 181 | } 182 | 183 | foreach ($plans as $plan) { 184 | $planObject = new Plan($this->getPlanResource()); 185 | $planObjects[] = $planObject->_setAttributes($plan); 186 | } 187 | 188 | return $planObjects; 189 | } 190 | 191 | /** 192 | * Create new plan. 193 | * 194 | * @param $name 195 | * @param $description 196 | * @param $amount 197 | * @param $currency 198 | * 199 | * @throws \Exception|mixed 200 | * @throws null 201 | * 202 | * @return mixed 203 | */ 204 | public function createPlan($name, $description, $amount, $currency) 205 | { 206 | return $this->getPlanModel()->make($name, $description, $amount, $currency)->save(); 207 | } 208 | 209 | /** 210 | * Update plan. 211 | * 212 | * @param $planCode 213 | * @param $updateData 214 | * 215 | * @throws \Exception|mixed 216 | * @throws null 217 | * 218 | * @return mixed 219 | */ 220 | public function updatePlan($planCode, $updateData) 221 | { 222 | return $this->getPlanModel()->getPlan($planCode) 223 | ->setUpdateData($updateData) 224 | ->save(); 225 | } 226 | 227 | /** 228 | * delete plans. 229 | * 230 | * @param $planCode 231 | * 232 | * @return $this 233 | */ 234 | public function deletePlan($planCode) 235 | { 236 | return $this->getPlanModel()->getPlan($planCode)->delete(); 237 | } 238 | 239 | /** 240 | * Init a one time transaction to get payment page url. 241 | * 242 | * @param $amount 243 | * @param $email 244 | * @param string $plan 245 | * 246 | * @throws \Exception|mixed|Exceptions\PaystackInvalidTransactionException 247 | * 248 | * @return \Exception|mixed|Exceptions\PaystackInvalidTransactionException 249 | */ 250 | public function startOneTimeTransaction($amount, $email, $plan = '') 251 | { 252 | $oneTimeTransaction = OneTimeTransaction::make( 253 | $amount, 254 | $email, 255 | $plan instanceof Plan ? $plan->get('plan_code') : $plan 256 | ); 257 | $oneTimeTransaction->setTransactionResource($this->getTransactionResource()); 258 | $transaction = $oneTimeTransaction->initialize(); 259 | 260 | if ($transaction instanceof \Exception) { 261 | throw $transaction; 262 | } 263 | 264 | return $transaction; 265 | } 266 | 267 | /** 268 | * Charge a returning customer. 269 | * 270 | * @param $authorization 271 | * @param $amount 272 | * @param $email 273 | * @param string $plan 274 | * 275 | * @throws \Exception|mixed|Exceptions\PaystackInvalidTransactionException 276 | * 277 | * @return \Exception|mixed|Exceptions\PaystackInvalidTransactionException 278 | */ 279 | public function chargeReturningTransaction($authorization, $amount, $email, $plan = '') 280 | { 281 | $returningTransaction = ReturningTransaction::make( 282 | $authorization, 283 | $amount, 284 | $email, 285 | $plan instanceof Plan ? $plan->get('plan_code') : $plan 286 | ); 287 | $returningTransaction->setTransactionResource($this->getTransactionResource()); 288 | 289 | $transaction = $returningTransaction->charge(); 290 | 291 | if ($transaction instanceof \Exception) { 292 | throw $transaction; 293 | } 294 | 295 | return $transaction; 296 | } 297 | 298 | /** 299 | * Verify transaction. 300 | * 301 | * @param $transactionRef 302 | * 303 | * @return array|bool 304 | */ 305 | public function verifyTransaction($transactionRef) 306 | { 307 | return $this->getTransactionHelper()->verify($transactionRef); 308 | } 309 | 310 | /** 311 | * Get transaction details. 312 | * 313 | * @param $transactionId 314 | * 315 | * @throws \Exception|mixed 316 | * 317 | * @return static 318 | */ 319 | public function transactionDetails($transactionId) 320 | { 321 | return $this->getTransactionHelper()->details($transactionId); 322 | } 323 | 324 | /** 325 | * Get all transactions. per page. 326 | * 327 | * @param $page 328 | * 329 | * @throws \Exception|mixed 330 | * 331 | * @return array 332 | */ 333 | public function allTransactions($page = '') 334 | { 335 | return $this->getTransactionHelper()->allTransactions($page); 336 | } 337 | 338 | /** 339 | * Get successful transactions volume or totals. 340 | * 341 | * @throws 342 | * 343 | * @return mixed 344 | */ 345 | public function transactionsTotals() 346 | { 347 | return $this->getTransactionHelper()->transactionsTotals(); 348 | } 349 | 350 | /** 351 | * @return TransactionResource 352 | */ 353 | private function getTransactionResource() 354 | { 355 | return $this->transactionResource; 356 | } 357 | 358 | /** 359 | * @param TransactionResource $transactionResource 360 | */ 361 | public function setTransactionResource($transactionResource) 362 | { 363 | $this->transactionResource = $transactionResource; 364 | } 365 | 366 | /** 367 | * @return CustomerResource 368 | */ 369 | private function getCustomerResource() 370 | { 371 | return $this->customerResource; 372 | } 373 | 374 | /** 375 | * @param CustomerResource $customerResource 376 | */ 377 | public function setCustomerResource($customerResource) 378 | { 379 | $this->customerResource = $customerResource; 380 | } 381 | 382 | /** 383 | * @return PlanResource 384 | */ 385 | private function getPlanResource() 386 | { 387 | return $this->planResource; 388 | } 389 | 390 | /** 391 | * @param PlanResource $planResource 392 | */ 393 | public function setPlanResource($planResource) 394 | { 395 | $this->planResource = $planResource; 396 | } 397 | 398 | /** 399 | * @return Customer 400 | */ 401 | private function getCustomerModel() 402 | { 403 | return $this->customerModel; 404 | } 405 | 406 | /** 407 | * @param Customer $customerModel 408 | */ 409 | public function setCustomerModel($customerModel) 410 | { 411 | $this->customerModel = $customerModel; 412 | } 413 | 414 | /** 415 | * @return Plan 416 | */ 417 | private function getPlanModel() 418 | { 419 | return $this->planModel; 420 | } 421 | 422 | /** 423 | * @param Plan $planModel 424 | */ 425 | public function setPlanModel($planModel) 426 | { 427 | $this->planModel = $planModel; 428 | } 429 | 430 | /** 431 | * @return TransactionHelper 432 | */ 433 | private function getTransactionHelper() 434 | { 435 | return $this->transactionHelper; 436 | } 437 | 438 | /** 439 | * @param TransactionHelper $transactionHelper 440 | */ 441 | public function setTransactionHelper($transactionHelper) 442 | { 443 | $this->transactionHelper = $transactionHelper; 444 | } 445 | 446 | /** 447 | * Make a HTTP Client for making requests. 448 | * 449 | * @param $key 450 | * 451 | * @return \GuzzleHttp\Client 452 | */ 453 | private function makePaystackHttpClient($key) 454 | { 455 | return is_null($key) ? 456 | PaystackHttpClientFactory::make() : 457 | PaystackHttpClientFactory::make( 458 | [ 459 | 'headers' => [ 460 | 'Authorization' => 'Bearer '.$key, 461 | 'Content-Type' => 'application/json', 462 | ], 463 | ] 464 | ); 465 | } 466 | 467 | /** 468 | * Get the created HTTP Client. 469 | * 470 | * @return \GuzzleHttp\Client 471 | */ 472 | public function getPaystackHttpClient() 473 | { 474 | return $this->paystackHttpClient; 475 | } 476 | } 477 | -------------------------------------------------------------------------------- /src/Repositories/CustomerResource.php: -------------------------------------------------------------------------------- 1 | paystackHttpClient = $paystackHttpClient; 30 | } 31 | 32 | /** 33 | * Get customer by customer code/id. 34 | * 35 | * @param $id 36 | * 37 | * @return \Exception|mixed 38 | */ 39 | public function get($id) 40 | { 41 | $request = $this->paystackHttpClient->get( 42 | $this->transformUrl(Resource::CUSTOMERS_URL, $id) 43 | ); 44 | 45 | return $this->processResourceRequestResponse($request); 46 | } 47 | 48 | /** 49 | * Get all customer. per page. 50 | * 51 | * @param null $page 52 | * 53 | * @return \Exception|mixed 54 | */ 55 | public function getAll($page = null) 56 | { 57 | $page = !empty($page) ? "page={$page}" : ''; 58 | $request = $this->paystackHttpClient->get( 59 | $this->transformUrl(Resource::CUSTOMERS_URL, '').$page 60 | ); 61 | 62 | return $this->processResourceRequestResponse($request); 63 | } 64 | 65 | /** 66 | * create new customer. 67 | * 68 | * @param $body 69 | * 70 | * @return \Exception|mixed 71 | */ 72 | public function save($body) 73 | { 74 | $request = $this->paystackHttpClient->post( 75 | $this->transformUrl(Resource::CUSTOMERS_URL, ''), 76 | [ 77 | 'body' => is_array($body) ? $this->toJson($body) : $body, 78 | ] 79 | ); 80 | 81 | return $this->processResourceRequestResponse($request); 82 | } 83 | 84 | /** 85 | * update customer. 86 | * 87 | * @param $id 88 | * @param $body 89 | * 90 | * @return \Exception|mixed 91 | */ 92 | public function update($id, $body) 93 | { 94 | $request = $this->paystackHttpClient->put( 95 | $this->transformUrl(Resource::CUSTOMERS_URL, $id), 96 | [ 97 | 'body' => is_array($body) ? $this->toJson($body) : $body, 98 | ] 99 | ); 100 | 101 | return $this->processResourceRequestResponse($request); 102 | } 103 | 104 | /** 105 | * delete customer. 106 | * 107 | * @param $id 108 | * 109 | * @return \Exception|mixed 110 | */ 111 | public function delete($id) 112 | { 113 | $request = $this->paystackHttpClient->delete( 114 | $this->transformUrl(Resource::CUSTOMERS_URL, $id) 115 | ); 116 | 117 | return $this->processResourceRequestResponse($request); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/Repositories/PlanResource.php: -------------------------------------------------------------------------------- 1 | paystackHttpClient = $paystackHttpClient; 26 | } 27 | 28 | /** 29 | * Get Plan by id/code. 30 | * 31 | * @param $id 32 | * 33 | * @return \Exception|mixed 34 | */ 35 | public function get($id) 36 | { 37 | $request = $this->paystackHttpClient->get( 38 | $this->transformUrl(Resource::PLANS_URL, $id) 39 | ); 40 | 41 | return $this->processResourceRequestResponse($request); 42 | } 43 | 44 | /** 45 | * get all plans. per page. 46 | * 47 | * @param null $page 48 | * 49 | * @return \Exception|mixed 50 | */ 51 | public function getAll($page = null) 52 | { 53 | $page = !empty($page) ? "page={$page}" : ''; 54 | $request = $this->paystackHttpClient->get( 55 | $this->transformUrl(Resource::PLANS_URL, '').$page 56 | ); 57 | 58 | return $this->processResourceRequestResponse($request); 59 | } 60 | 61 | /** 62 | * save new plan. 63 | * 64 | * @param $body 65 | * 66 | * @return \Exception|mixed 67 | */ 68 | public function save($body) 69 | { 70 | $request = $this->paystackHttpClient->post( 71 | $this->transformUrl(Resource::PLANS_URL, ''), 72 | [ 73 | 'body' => is_array($body) ? $this->toJson($body) : $body, 74 | ] 75 | ); 76 | 77 | return $this->processResourceRequestResponse($request); 78 | } 79 | 80 | /** 81 | * update plan. 82 | * 83 | * @param $id 84 | * @param $body 85 | * 86 | * @return \Exception|mixed 87 | */ 88 | public function update($id, $body) 89 | { 90 | $request = $this->paystackHttpClient->put( 91 | $this->transformUrl(Resource::PLANS_URL, $id), 92 | [ 93 | 'body' => is_array($body) ? $this->toJson($body) : $body, 94 | ] 95 | ); 96 | 97 | return $this->processResourceRequestResponse($request); 98 | } 99 | 100 | /** 101 | * delete plan. 102 | * 103 | * @param $id 104 | * 105 | * @return \Exception|mixed 106 | */ 107 | public function delete($id) 108 | { 109 | $request = $this->paystackHttpClient->delete( 110 | $this->transformUrl(Resource::PLANS_URL, $id) 111 | ); 112 | 113 | return $this->processResourceRequestResponse($request); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Repositories/TransactionResource.php: -------------------------------------------------------------------------------- 1 | paystackHttpClient = $paystackHttpClient; 25 | } 26 | 27 | /** 28 | * get transaction by id. 29 | * 30 | * @param $id 31 | * 32 | * @return \Exception|mixed 33 | */ 34 | public function get($id) 35 | { 36 | $request = $this->paystackHttpClient->get( 37 | $this->transformUrl(Resource::GET_TRANSACTION, $id) 38 | ); 39 | 40 | return $this->processResourceRequestResponse($request); 41 | } 42 | 43 | /** 44 | * Get all transactions. 45 | * 46 | * @param string $page 47 | * 48 | * @return \Exception|mixed 49 | */ 50 | public function getAll($page = '') 51 | { 52 | $page = !empty($page) ? "/page={$page}" : ''; 53 | $request = $this->paystackHttpClient->get( 54 | $this->transformUrl(Resource::GET_TRANSACTION, '').$page 55 | ); 56 | 57 | return $this->processResourceRequestResponse($request); 58 | } 59 | 60 | /** 61 | * Get transactions totals. 62 | */ 63 | public function getTransactionTotals() 64 | { 65 | $request = $this->paystackHttpClient->get( 66 | Resource::GET_TRANSACTION_TOTALS 67 | ); 68 | 69 | return $this->processResourceRequestResponse($request); 70 | } 71 | 72 | /** 73 | * Verify Transaction by transaction reference. 74 | * 75 | * @param $reference 76 | * 77 | * @return \Exception|mixed 78 | */ 79 | public function verify($reference) 80 | { 81 | $request = $this->paystackHttpClient->get( 82 | $this->transformUrl(Resource::VERIFY_TRANSACTION, $reference, ':reference') 83 | ); 84 | 85 | return $this->processResourceRequestResponse($request); 86 | } 87 | 88 | /** 89 | * Initialize one time transaction. 90 | * 91 | * @param $body 92 | * 93 | * @return \Exception|mixed 94 | */ 95 | public function initialize($body) 96 | { 97 | $request = $this->paystackHttpClient->post( 98 | Resource::INITIALIZE_TRANSACTION, 99 | [ 100 | 'body' => is_array($body) ? $this->toJson($body) : $body, 101 | ] 102 | ); 103 | 104 | return $this->processResourceRequestResponse($request); 105 | } 106 | 107 | /** 108 | * charge returning transaction. 109 | * 110 | * @param $body 111 | * 112 | * @return \Exception|mixed 113 | */ 114 | public function chargeAuthorization($body) 115 | { 116 | $request = $this->paystackHttpClient->post( 117 | Resource::CHARGE_AUTHORIZATION, 118 | [ 119 | 'body' => is_array($body) ? $this->toJson($body) : $body, 120 | ] 121 | ); 122 | 123 | return $this->processResourceRequestResponse($request); 124 | } 125 | 126 | /** 127 | * Charge Token. 128 | * 129 | * @param $body 130 | * 131 | * @return \Exception|mixed 132 | */ 133 | public function chargeToken($body) 134 | { 135 | $request = $this->paystackHttpClient->post( 136 | Resource::CHARGE_TOKEN, 137 | [ 138 | 'body' => is_array($body) ? $this->toJson($body) : $body, 139 | ] 140 | ); 141 | 142 | return $this->processResourceRequestResponse($request); 143 | } 144 | } 145 | --------------------------------------------------------------------------------