PHPackages                             adelowo/gbowo - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. adelowo/gbowo

ActiveLibrary[Payment Processing](/categories/payments)

adelowo/gbowo
=============

Unified API for hippy Nigerian payment gateways..Batteries included. Comes with adapters for Paystack and Amplifypay

1.7.1(6y ago)221975[1 PRs](https://github.com/adelowo/gbowo/pulls)2MITPHPPHP ~7.0

Since Oct 22Pushed 4y ago1 watchersCompare

[ Source](https://github.com/adelowo/gbowo)[ Packagist](https://packagist.org/packages/adelowo/gbowo)[ RSS](/packages/adelowo-gbowo/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (5)Versions (17)Used By (2)

Gbowo - Unified API for Hippy Nigerian Payment Gateways
=======================================================

[](#gbowo---unified-api-for-hippy-nigerian-payment-gateways)

[![Latest Version on Packagist](https://camo.githubusercontent.com/2eb16bdc113d9c5f052a6718a4f63cb0bc1854ddf77b07e2024a31728c75836c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6164656c6f776f2f67626f776f2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/adelowo/gbowo)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Build Status](https://camo.githubusercontent.com/7e6f29a32078c153f8f3b112f6882e4f30153c55aed435d1f3de399c906776eb/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f6164656c6f776f2f67626f776f2f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/adelowo/gbowo)[![Scrutinizer Coverage](https://camo.githubusercontent.com/9615f2f21e9dfd3e91d9b8b70623bd16fe01dfe14df31f1d65a81a35586d7098/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f6164656c6f776f2f67626f776f2e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/adelowo/gbowo/?branch=master)[![Quality Score](https://camo.githubusercontent.com/447ba73a527c29d4f0e03d9a7bf29c67c074d0975a50403995e343cfeabe6e43/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f6164656c6f776f2f67626f776f2e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/adelowo/gbowo)[![Total Downloads](https://camo.githubusercontent.com/a32927c8d4075f3cd5a9c08d9726081cfeec29043e596623088e22194f570da5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6164656c6f776f2f67626f776f2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/adelowo/gbowo)

- [Installation](#installation)
- [Usage](#usage)
    - [Adapters](#adapters)
        - [Custom Adapters](#extend)
- [Plugins](#plugins)
- [Framework Integration/Bridges](#frameworks)
    - [Laravel](#laravel)
- [Example Application](#example)

Installation
-------------

[](#installation)

Install Gbowo via one of the following methods :

- [Composer](https://getcomposer.org) (Recommended) :

```
    composer require "adelowo/gbowo" : "~1.0"
```

 Usage
-------

[](#-usage-)

```
require_once 'vendor/autoload.php';

$adapter = new \Gbowo\Adapter\Paystack\PaystackAdapter();

$response = $adapter->charge();
```

For the paystack and amplifypay adapters, the response received would be a string, which denotes an *authorization\_\_url*. You are to make a redirect to the url to complete the transaction.

> Other adapters implementation may do something much different like redirect internally ( from the adapter) but this isn't done for good reasons. This is because different systems may have different ways of performing redirects via *Request* or *Response* objects, or whatever have they. So as long as you can get the returned url, you can use the *Adapter* in your framework or whatever have you.

A basic example would be something like

```
header("Location : {$response}");
exit();
```

Adapters
--------

[](#adapters)

#### Quick usage

[](#quick-usage)

```
$adapter = (new \Gbowo\GbowoFactory())->createAdapter("paystack"); //or "amplifypay"

return $adapter->charge();
```

#### Usage in depth

[](#usage-in-depth)

*Gbowo* ships with two adapters : one for [paystack](https://paystack.co) and the other for [Amplifypay](https://amplifypay.com).

While both payment gateway offer similar features, there are a few subtle differences (obviously).

*Gbowo* requires some value to be present in the environment i.e `$_ENV`. For paystack, this is `$_ENV['PAYSTACK_SECRET_KEY']` while the amplifypay adapter requires two values : your merchant id and an api key. This should be present in the following format : `$_ENV['AMPLIFYPAY_MERCHANT_ID']` and `$_ENV['AMPLIFYPAY_API_KEY']`.

> You are strongly advised to keep your keys and/or tokens out of your code and instead load them into `$_ENV` by some other means. We don't enforce this but it is a best practice, [12 Factor App Guideline](https://12factor.net/config). A library that would help with this is `vlucas/phpdotenv`. All it needs is a `.env` file and you are golden. Remember not to commit the `.env` else it still isn't out of your "code". A sample `.env.example` has been provided in the `resources` directory. You can copy and rename that to `.env` in your root dir.

```
$paystack = new \Gbowo\Adapter\Paystack\PaystackAdapter();

$amplifyPay = new \Gbowo\Adapter\Amplifypay\AmplifypayAdapter()
```

A GuzzleHttp `Client` instance would be created automatically and values gotten from the `$_ENV` would be used to set the appropriate authorization headers where applicable.

You can prevent this "auto-wiring" by providing an instance of Guzzlehttp Client in the constructor.

```
$client = new \GuzzleHttp\Client(['key' => "value"]);

$amplifyPay = new \Gbowo\Adapter\Amplifypay\AmplifypayAdapter($client)
```

The payment flow for both adapters is pretty much the same. User initiates first time / one time transaction and is redirected to a secure page where payment details are to be inputted. After this (a successful payment request), the gateway would issue a redirect to a url you have supplied them as a callback. In this url, you should fetch the details of a user (who is now a customer) such as an *authorization\_code* , *transaction\_reference* among others. This is for recurrent transactions and should be persisted to a storage mechanism.

Initiating the transaction should be performed by calling the `charge` method on the adapter. And making a redirect where applicable to the response as described earlier.

To fetch the data from the url callback you have registered on your chosen gateway, you have to call the `getPaymentData` method on the adapter. It's response would contain some data about the customer.

```
//paystack adapter
var_dump($adapter->getPaymentData($_GET['trxref'])) ; //you should clean this up.

//amplifypay adapter
var_dump($adapter->getPaymentData($_GET['tran_response'])); // clean up
```

> The `getPaymentData` method can also be called on some transaction reference you have stored in your db or some other form of storage mechanism.

> When you call the `getPaymentData` on the paystack adapter. The reference is verified by paystack before a response is sent

### Adapters Methods.

[](#adapters-methods)

[Paystack](https://paystack.co) :

- `charge(array $data = [])`
- `getCustomer(int $id)`
- `getAllCustomers()`
- `chargeWithToken(array $userToken)` // a token plus email address (or custom stuff)
- `getPaymentData(string $transRef)`
- `fetchPlan($planIdentifier)`
- `fetchAllPlans()`

> Checkout [gbowo-paystack](https://github.com/adelowo/gbowo-paystack) . It contains an additional set of [plugins](#plugins) for the paystack adapter.

[Amplifypay](https://amplifypay.com) :

- `charge(array $data = [])`
- `unsubcribeCustomerFromPlan(array $data)`
- `chargeWithToken(array $userToken)` //a token in amplifypay is a key pair of values.
- `getPaymentData(string $transRef)`
- `fetchPlan($planIdentifier)`
- `fetchAllPlans()`

> The `charge` method parameter (`array $data = []`) should contain stuffs like amount, email, x, y, z). Those would be handed over to the payment gateway

Custom Adapters
---------------

[](#custom-adapters)

> Using laravel, please check out how to [add your custom adapter](#laravel)

```
//let's assume it is an enterprisey app

$interswitch = new class implements \Gbowo\Contract\Adapter\AdapterInterface
{
    protected $interswitch;

    public function __construct()
    {
        $this->interswitch = new \stdClass(new \ArrayObject(new \stdClass())); // It wasn't me
    }

    public function charge(array $data = [])
    {
        return "charged by interswitch";
    }
};

$adapter = new \Gbowo\GbowoFactory(["interswitch" => $interswitch]); //add the interswith adapter as a custom one.

$interswitchAdapter = $adapter->createAdapter("interswitch");

$interswitchAdapter->charge(['a' => 'b', 'c' => 'd']);
```

Extending Adapters via Plugins
------------------------------

[](#extending-adapters-via-plugins)

Different gateways implement various features and there's no way we can support all of them without losing our sanity.

Supporting all features would lead to a bloat (an interface, class bloat). Take for instance : create `InterfaceX` to support feature X for `AdapterE` while `AdapterE` still makes use of features (and therefore interfaces) for `AdapterA`,`AdapterQ` and so on. Now imagine this scenario plays out for 4 -5 adapters.

Apart from the bloat, we cannot create a (visual) diagram of which interfaces are being used and it'd lead to a situation where we cannot remove a certain class or interface because we do not know who (what adapter) depends on them.

To prevent this, *Gbowo* implements a plugin architecture that eases extension or "adding new methods/behaviours" to an existing adapter without inheritance or touching core code. To achieve this, there is a `Pluggable` trait that contains the logic and **MUST** be imported by an adapter implementation.

A look at the [paystack adapter](src/Gbowo/Adapter/Paystack/PaystackAdapter.php) and [amplifypay](src/Gbowo/Adapter/Amplifypay/AmplifypayAdapter.php) would reveal that they do not have the methods described above in their public api. In fact they expose only 3 methods :

- `__construct(Client $client = null)` // if it counts as one
- `getHttpClient()`
- `charge(array $data = [])` //This is gotten from the `AdapterInterface` implemented.

But a look at their `registerPlugins` method - which is gotten from the **Pluggable** trait - tells how the methods described in the `Adapters method` section above come about.

A plugin is a plain PHP class that **MUST** implement the `PluginInterface`. This interface exposes two methods :

- `getPluginAccessor() : string`
- `setAdapter(Adapter $adapter)`
- `handle(string $reference)` //Typehint as much as you want. 2,3 args ? Your call.

> I have written a [detailed post about this here](https://lanreadelowo.com/blog/2017/03/08/extending-gbowo-via-plugins/)

```
namespace Vendor\AdapterName\Plugin;

use Gbowo/Contract/Plugin/PluginInterface;
use Gbowo\Exception\TransactionVerficationFailedException;

class ApiPinger implements PluginInterface
{

    public function getPluginAccessor():string
    {
        return "pingApi"; //Oops.. Let's confirm if the api isn't dead before making any request. And it must be a string without parenthesis
    }

    /**
     * You can also leave this method out but you must extend the `AbstractPlugin` class. Doing so, means you'd have to get rid of the plugin interface here as the abstract plugin already does that.
     */
    public function setAdapter(AdapterInterface $adapter)
    {
        //useful for helpers like getting stuffs from "accessors" on the adapter instance like the already configured HttpClient object
        $this->adapter = $adapter ;
        return $this;
    }

    /**
     * Ping the gateway Api
     * @param  bool $shouldThrow. Should an exception be thrown if the api is down ?.
     * @return bool true - if the api is up and running.
                   false - if the api is down and $throw is set to false.
     * @throws \Exception if the api is down and $throw is set to false.
     */
    public function handle(bool $shouldThrow = false)
    {
        $response = $this->adapter->getHttpClient()->get("https://api.homepage.com");

        if ($response->getStatusCode() === 200 ) {
            return true;
        }

        if ($shouldThrow) {
            throw TransactionVerficationFailedException::createFromResponse($response);
        }

        return false;
    }
}
```

> `createFromResponse` is a wrapper that allows client code inspect the response for why there was a failure (say an invalid HTTP status code).. You should call `getResponse` on the exception in other to inspect it. This is also true for official plugins provided by Gbowo.

The `getPluginAccessor` is of tremendous interest here since it determines what plugin the method call should be deferred to. This is done by the magic method `__call` in the [`Pluggable`](src/Gbowo/Traits/Pluggable.php) trait.

```
$adapter->addPlugin(new Vendor\AdapterName\Plugin\ApiPinger(PaystackAdapter::API_LINK));
//Usage like this

$adapter->pingApi(true);
$adapter->pingApi();
```

Not all plugins would make it to the core eventually and not even all plugins in the core would be "added" on instantiation. For instance, the `GetAllCustomers` plugin isn't added to the `PaystackAdapter` internally. To use the plugin, you'd have to add it yourself.

```
$adapter->addPlugin(new GetAllCustomers(PaystackAdapter::API_LINK))
```

 Framework Integration
----------------------

[](#-framework-integration)

Laravel
--------

[](#laravel-)

Prior to `v1.5.0`, a Laravel bridge was provided alongside this package but in light of best interests, it [has been moved to it's own repository](https://github.com/adelowo/laravel-gbowo).

If upgrading from a previous version to `v1.5.0`, please note that you would have to run `composer require adelowo/laravel-gbowo`

> Please note that the decision to give the Laravel bridge a life of it's own doesn't mean BC break. The namespaces were preserved and would continue to work as is.

-

[](#-)

##### Sample App

[](#sample-app)

[Gbowo-app](https://github.com/adelowo/gbowo-app) - Built with SlimPHP.

### Contributing

[](#contributing)

Awesome, I'd love that. Fork, send PR. But hey, unit testing is one honking great idea. Let's have more of that.

### Bug Reports, Issue tracking and Security Vulnerabilities

[](#bug-reports-issue-tracking-and-security-vulnerabilities)

Please make use of the [issue tracker](https://github.com/adelowo/gbowo/issues) for bug reports, feature request and others except Security issues. If you do discover a vulnerability, please send a mail to `me@lanreadelowo.com`.

### License

[](#license)

[MIT](http://opensource.org/licenses/MIT)

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity22

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity66

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~74 days

Recently: every ~221 days

Total

15

Last Release

2441d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2675d3dc5a82caaf86b7a8220727d46d72b92ee23c02386d050fb0bc39f07aed?d=identicon)[adelowo](/maintainers/adelowo)

---

Top Contributors

[![adelowo](https://avatars.githubusercontent.com/u/12677701?v=4)](https://github.com/adelowo "adelowo (19 commits)")

---

Tags

amplifypaypaystackphp7phpgithubpaymentspaystackAmplifyPayNigerian Payments

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/adelowo-gbowo/health.svg)

```
[![Health](https://phpackages.com/badges/adelowo-gbowo/health.svg)](https://phpackages.com/packages/adelowo-gbowo)
```

###  Alternatives

[unicodeveloper/laravel-paystack

A Laravel Package for Paystack

650975.6k11](/packages/unicodeveloper-laravel-paystack)[prevailexcel/laravel-nowpayments

A Laravel Package for NOWPayments

1414.2k](/packages/prevailexcel-laravel-nowpayments)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
