diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 0000000..5c6751f --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +{"version":1,"defects":[],"times":{"Unicodeveloper\\Paystack\\Test\\HelpersTest::it_returns_instance_of_paystack":0.213,"Unicodeveloper\\Paystack\\Test\\PaystackTest::testAllCustomersAreReturned":0.089,"Unicodeveloper\\Paystack\\Test\\PaystackTest::testAllTransactionsAreReturned":0.001,"Unicodeveloper\\Paystack\\Test\\PaystackTest::testAllPlansAreReturned":0.001}} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 2185801..bcd5b04 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,22 +1,15 @@ language: php php: - - 5.5 - - 5.6 - - 7.0 - - hhvm - -matrix: - allow_failures: - - php: hhvm + - 7.3 install: travis_retry composer install --no-interaction --prefer-source script: - mkdir -p build/logs - - php vendor/bin/phpunit -c phpunit.xml.dist - - phpunit --coverage-text --coverage-clover=coverage.clover - - phpunit --coverage-clover build/logs/clover.xml + - vendor/bin/phpunit -c phpunit.xml.dist + - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover + - vendor/bin/phpunit --coverage-clover build/logs/clover.xml after_script: - wget https://scrutinizer-ci.com/ocular.phar diff --git a/CHANGELOG.md b/CHANGELOG.md index ff38a33..73df5fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,4 +3,11 @@ All Notable changes to `laravel-paystack` will be documented in this file ## 2015-11-04 -- Initial release \ No newline at end of file +- Initial release + +## 2020-05-23 +- Support for Laravel 7 +- Support for splitting payments into subaccounts +- Support for more than one currency. Now you can use USD! +- Support for multiple quantities +- Support for helpers \ No newline at end of file diff --git a/README.md b/README.md index 134ef7a..f57e23d 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,14 @@ You'll then need to run `composer install` or `composer update` to download it a Once Laravel Paystack is installed, you need to register the service provider. Open up `config/app.php` and add the following to the `providers` key. +```php +'providers' => [ + ... + Unicodeveloper\Paystack\PaystackServiceProvider::class, + ... +] +``` + > If you use **Laravel >= 5.5** you can skip this step and go to [**`configuration`**](https://github.com/unicodeveloper/laravel-paystack#configuration) * `Unicodeveloper\Paystack\PaystackServiceProvider::class` @@ -87,23 +95,23 @@ return [ ``` -##General payment flow +## General payment flow Though there are multiple ways to pay an order, most payment gateways expect you to follow the following flow in your checkout process: -###1. The customer is redirected to the payment provider -After the customer has gone through the checkout process and is ready to pay, the customer must be redirected to site of the payment provider. +### 1. The customer is redirected to the payment provider +After the customer has gone through the checkout process and is ready to pay, the customer must be redirected to the site of the payment provider. -The redirection is accomplished by submitting a form with some hidden fields. The form must post to the site of the payment provider. The hidden fields minimally specify the amount that must be paid, the order id and a hash. +The redirection is accomplished by submitting a form with some hidden fields. The form must send a POST request to the site of the payment provider. The hidden fields minimally specify the amount that must be paid, the order id and a hash. The hash is calculated using the hidden form fields and a non-public secret. The hash used by the payment provider to verify if the request is valid. -###2. The customer pays on the site of the payment provider -The customer arrived on the site of the payment provider and gets to choose a payment method. All steps necessary to pay the order are taken care of by the payment provider. +### 2. The customer pays on the site of the payment provider +The customer arrives on the site of the payment provider and gets to choose a payment method. All steps necessary to pay the order are taken care of by the payment provider. -###3. The customer gets redirected back -After having paid the order the customer is redirected back. In the redirection request to the shop-site some values are returned. The values are usually the order id, a paymentresult and a hash. +### 3. The customer gets redirected back to your site +After having paid the order the customer is redirected back. In the redirection request to the shop-site some values are returned. The values are usually the order id, a payment result and a hash. The hash is calculated out of some of the fields returned and a secret non-public value. This hash is used to verify if the request is valid and comes from the payment provider. It is paramount that this hash is thoroughly checked. @@ -118,6 +126,7 @@ PAYSTACK_SECRET_KEY=xxxxxxxxxxxxx PAYSTACK_PAYMENT_URL=https://api.paystack.co MERCHANT_EMAIL=unicodeveloper@gmail.com ``` +*If you are using a hosting service like heroku, ensure to add the above details to your configuration variables.* Set up routes and controller methods like so: @@ -127,7 +136,7 @@ Note: Make sure you have `/payment/callback` registered in Paystack Dashboard [h ```php // Laravel 5.1.17 and above -Route::post('/pay', 'PaymentController@redirectToGateway')->name('pay'); +Route::post('/pay', 'PaymentController@redirectToGateway')->name('pay'); ``` OR @@ -138,6 +147,13 @@ Route::post('/pay', [ 'as' => 'pay' ]); ``` +OR + +```php +// Laravel 8 & 9 +Route::post('/pay', [App\Http\Controllers\PaymentController::class, 'redirectToGateway'])->name('pay'); +``` + ```php Route::get('/payment/callback', 'PaymentController@handleGatewayCallback'); @@ -149,7 +165,14 @@ OR // Laravel 5.0 Route::get('payment/callback', [ 'uses' => 'PaymentController@handleGatewayCallback' -]); +]); +``` + +OR + +```php +// Laravel 8 & 9 +Route::get('/payment/callback', [App\Http\Controllers\PaymentController::class, 'handleGatewayCallback']); ``` ```php @@ -161,6 +184,7 @@ use Illuminate\Http\Request; use App\Http\Requests; use App\Http\Controllers\Controller; +use Illuminate\Support\Facades\Redirect; use Paystack; class PaymentController extends Controller @@ -172,7 +196,11 @@ class PaymentController extends Controller */ public function redirectToGateway() { - return Paystack::getAuthorizationUrl()->redirectNow(); + try{ + return Paystack::getAuthorizationUrl()->redirectNow(); + }catch(\Exception $e) { + return Redirect::back()->withMessage(['msg'=>'The paystack token has expired. Please refresh the page and try again.', 'type'=>'error']); + } } /** @@ -191,16 +219,43 @@ class PaymentController extends Controller } ``` +```php +/** + * In the case where you need to pass the data from your + * controller instead of a form + * Make sure to send: + * required: email, amount, reference, orderID(probably) + * optionally: currency, description, metadata + * e.g: + * + */ +$data = array( + "amount" => 700 * 100, + "reference" => '4g4g5485g8545jg8gj', + "email" => 'user@mail.com', + "currency" => "NGN", + "orderID" => 23456, + ); + +return Paystack::getAuthorizationUrl($data)->redirectNow(); + +``` + Let me explain the fluent methods this package provides a bit here. ```php /** * This fluent method does all the dirty work of sending a POST request with the form data * to Paystack Api, then it gets the authorization Url and redirects the user to Paystack - * Payment Page. I abstracted all of it, so you don't have to worry about that. + * Payment Page. We've abstracted all of it, so you don't have to worry about that. * Just eat your cookies while coding! */ Paystack::getAuthorizationUrl()->redirectNow(); +/** + * Alternatively, use the helper. + */ +paystack()->getAuthorizationUrl()->redirectNow(); + /** * This fluent method does all the dirty work of verifying that the just concluded transaction was actually valid, * It verifies the transaction reference with Paystack Api and then grabs the data returned from Paystack. @@ -209,18 +264,35 @@ Paystack::getAuthorizationUrl()->redirectNow(); */ Paystack::getPaymentData(); +/** + * Alternatively, use the helper. + */ +paystack()->getPaymentData(); + /** * This method gets all the customers that have performed transactions on your platform with Paystack * @returns array */ Paystack::getAllCustomers(); +/** + * Alternatively, use the helper. + */ +paystack()->getAllCustomers(); + + /** * This method gets all the plans that you have registered on Paystack * @returns array */ Paystack::getAllPlans(); +/** + * Alternatively, use the helper. + */ +paystack()->getAllPlans(); + + /** * This method gets all the transactions that have occurred * @returns array @@ -228,44 +300,93 @@ Paystack::getAllPlans(); Paystack::getAllTransactions(); /** - * This method generates a unique super secure cryptograhical hash token to use as transaction reference + * Alternatively, use the helper. + */ +paystack()->getAllTransactions(); + +/** + * This method generates a unique super secure cryptographic hash token to use as transaction reference * @returns string */ Paystack::genTranxRef(); /** -* This method creates a subaccount to be used for split payments + * Alternatively, use the helper. + */ +paystack()->genTranxRef(); + + +/** +* This method creates a subaccount to be used for split payments * @return array */ Paystack::createSubAccount(); +/** + * Alternatively, use the helper. + */ +paystack()->createSubAccount(); + /** -* This method fetches the details of a subaccount +* This method fetches the details of a subaccount * @return array */ Paystack::fetchSubAccount(); +/** + * Alternatively, use the helper. + */ +paystack()->fetchSubAccount(); + /** -* This method lists the subaccounts associated with your paystack account +* This method lists the subaccounts associated with your paystack account * @return array */ Paystack::listSubAccounts(); /** -* This method Updates a subaccount to be used for split payments + * Alternatively, use the helper. + */ +paystack()->listSubAccounts(); + + +/** +* This method Updates a subaccount to be used for split payments * @return array */ Paystack::updateSubAccount(); + +/** + * Alternatively, use the helper. + */ +paystack()->updateSubAccount(); ``` A sample form will look like so: +```php + "percentage", + "currency" => "KES", + "subaccounts" => [ + [ "subaccount" => "ACCT_li4p6kte2dolodo", "share" => 10 ], + [ "subaccount" => "ACCT_li4p6kte2dolodo", "share" => 30 ], + ], + "bearer_type" => "all", + "main_account_share" => 70 +]; +?> +``` + ```html