PHPackages                             wayaquick/payment-sdk - 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. wayaquick/payment-sdk

ActiveLibrary

wayaquick/payment-sdk
=====================

PHP client for the WayaPay Merchant API v2: collect, payout, accounts, identity, transactions.

v2.0.0(1mo ago)11↓75%1MITPHPPHP &gt;=8.1

Since May 26Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/WAYA-MULTI-LINK/WAYA-PAY-CHAT-2.0-PHP-LIBRARY)[ Packagist](https://packagist.org/packages/wayaquick/payment-sdk)[ RSS](/packages/wayaquick-payment-sdk/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (1)Versions (4)Used By (0)

WayaPay PHP
===========

[](#wayapay-php)

PHP client for the **WayaPay Merchant API v2**. Collect payments, send payouts, verify bank accounts, and run BVN identity checks in Nigeria.

One client, four resources, a single transport that handles auth headers and the shared response envelope so you never parse `success`/`code` by hand. No Guzzle, no PSR-18 stack — just `ext-curl` and `ext-json`. **Server-side only** — your secret key must never leave your server.

Requirements
------------

[](#requirements)

PHP 8.1 or newer, with the `curl` and `json` extensions (both standard).

Install
-------

[](#install)

```
composer require wayaquick/payment-sdk
```

Or drop the folder in and point any PSR-4 autoloader at `WayaPay\` =&gt; `src/`.

Quickstart
----------

[](#quickstart)

```
use WayaPay\WayaPay;

$client = new WayaPay([
    'merchantId' => getenv('WAYA_MERCHANT_ID'),  // MER_...
    'secretKey'  => getenv('WAYA_SECRET_KEY'),   // WAYASECK_TEST_... or WAYASECK_...
]);
```

The client targets the production base URL. Test with a `WAYASECK_TEST_...` key, then swap in your live `WAYASECK_...` key when ready — the rest of your code stays the same. Pass `baseUrl` to point at a different host.

What you get back
-----------------

[](#what-you-get-back)

Every method returns the envelope's `data` payload directly, already decoded into an associative array. The `success`, `code`, and `timestamp` fields only matter when something fails — and failures throw — so the happy path stays clean:

```
$acct = $client->payouts->verifyAccount(['accountNumber' => '0123456789', 'bankCode' => '044']);
echo $acct['accountName']; // straight to the useful part
```

List banks
----------

[](#list-banks)

```
$banks = $client->payouts->listBanks();
// [['code' => '044', 'name' => 'Access Bank', 'id' => '044', 'status' => true], ...]
```

Verify an account
-----------------

[](#verify-an-account)

Always verify before sending a payout — confirms the account exists and returns the registered name.

```
$result = $client->payouts->verifyAccount([
    'accountNumber' => '0123456789',
    'bankCode'      => '044',       // omit only when enquiryType is 'WAYABANK'
    'enquiryType'   => 'OTHERS',    // default
]);
echo $result['accountName']; // "JOHN DOE"
```

Initiate a payout
-----------------

[](#initiate-a-payout)

```
$payout = $client->payouts->initiate([
    'amount'        => 25000,
    'accountNumber' => '0123456789',
    'bankCode'      => '058',
    'accountName'   => 'JOHN DOE',  // match the verified name
    'narration'     => 'April salary',
    // currency defaults to 'NGN', reference auto-generated if omitted
]);
// $payout['status'] === 'PROCESSING' means accepted, not settled

// Reconcile by the reference you sent at initiation:
$status = $client->payouts->getStatus($payout['transactionReference'] ?? $payout['payoutReference']);
// interpret $status['status'] with WayaPay\Status\PayoutStatus::fromApi(...)
```

Collect a payment
-----------------

[](#collect-a-payment)

```
$link = $client->collect->create([
    'paymentLinkName' => 'Order #1234',
    'description'     => 'Order #1234 - 2 items',
    'payableAmount'   => 1500,
    'redirectLink'    => 'https://merchant.example.com/callback',
    // paymentLinkType defaults to 'ONE_TIME_PAYMENT_LINK', currency to 'NGN'
]);
// Send the customer to $link['shortUrl']. Keep $link['paymentLinkReference'] to reconcile.

// Reconcile a deposit by its refNo (the gateway transactionId / webhook orderId):
$collectStatus = $client->collect->getStatus($refNo);
// interpret $collectStatus['status'] with WayaPay\Status\CollectionStatus::fromApi(...)
```

If you set `'linkCanExpire' => true`, you must also pass `'expiryDate'`. The library enforces it before the call leaves your server. `collect->create` also fails unless you have whitelisted your server IPs and configured payment preferences on the dashboard.

BVN identity check
------------------

[](#bvn-identity-check)

```
$bvn = $client->identity->verifyBvn('22212345678'); // 11 digits, validated locally
echo "{$bvn['firstName']} {$bvn['lastName']}";
// treat anything other than "False" on $bvn['watchListed'] with care
```

BVN data is sensitive personal information. Store, transmit, and log it only as your data-protection obligations allow.

A payout returning `PROCESSING` is accepted, not settled. Poll `payouts->getStatus` with the reference until it reaches a terminal status.

The resources
-------------

[](#the-resources)

ResourceMethodEndpoint`$client->payouts``listBanks``GET /get-bank-list``$client->payouts``verifyAccount``POST /verify-account``$client->payouts``initiate``POST /payment-payout/initiate``$client->payouts``getStatus``GET /payment-payout/status/{reference}``$client->collect``create``POST /payment-collect/initiate``$client->collect``getStatus``GET /payment-collect/status/{refNo}``$client->identity``verifyBvn``POST /identity-verification/bvn``$client->webhooks``constructEvent` / `verifySignature`— (verifies inbound webhooks)References
----------

[](#references)

In v2, the unique `reference` you supply is your dedup and reconciliation key. Generate a fresh one per logical operation so retries map to the original record instead of spawning duplicates. The library auto-fills it on payouts when you leave it out, or generate your own:

```
$ref = WayaPay::generateReference('PAYOUT'); // PAYOUT-1748160000000-A1B2C3D4
```

Errors
------

[](#errors)

Everything that fails throws a `WayaPayException`. Branch on `type` for the category and `errorCode` for the WayaPay code. (It is `errorCode`, not `code`, because PHP's base `Exception` already owns `getCode()` and that one is an int.)

```
use WayaPay\WayaPayException;

try {
    $client->payouts->initiate([/* ... */]);
} catch (WayaPayException $e) {
    $e->type;         // 'api' | 'validation' | 'network' | 'timeout' | 'config'
    $e->errorCode;    // WayaPay code, e.g. "07". null when not an API error.
    $e->status;       // HTTP status when known
    $e->getMessage(); // human readable
    $e->raw;          // raw body or underlying error, for your logs
}
```

Validation errors fire **before** any network call, so a missing field or a malformed BVN never burns a request.

Timeouts and retries
--------------------

[](#timeouts-and-retries)

Configurable on the constructor:

```
new WayaPay([
    'merchantId' => '...', 'secretKey' => '...',
    'timeout'    => 30000,   // milliseconds
    'maxRetries' => 2,
]);
```

Retries apply to **GET only** (bank list, status checks) and only on timeouts, network errors, 429, or 5xx, with exponential backoff. Writes (payout, account verify, collect, BVN) never auto-retry, because retrying a write you are unsure about is how you pay someone twice. Retry those yourself, with the same `reference`, once you have checked the transaction status.

Custom transport (testing)
--------------------------

[](#custom-transport-testing)

The constructor accepts a `transport` callable so you can test without touching the network. Signature: `function (string $method, string $url, array $headers, ?string $body): array` returning `[int $status, string $rawBody]`. Throw a `WayaPayException` of type `network` or `timeout` to simulate transport failures.

```
$client = new WayaPay([
    'merchantId' => 'm', 'secretKey' => 's',
    'transport' => fn ($method, $url, $headers, $body) => [200, json_encode([
        'success' => true, 'code' => '00', 'data' => [/* ... */],
    ])],
]);
```

This is exactly how the test suite runs — see [tests/](tests/).

Full example
------------

[](#full-example)

See [samples/usage.php](samples/usage.php) for a runnable end-to-end demo covering every resource.

```
WAYA_MERCHANT_ID=MER_... WAYA_SECRET_KEY=WAYASECK_TEST_... php samples/usage.php
```

Before you go live
------------------

[](#before-you-go-live)

On the merchant dashboard: finish KYC, grab your Merchant ID, generate your secret key under **Settings → API Keys and Webhooks**, whitelist your server IPs, and configure payment preferences. Payment Collect refuses to work until the last two are done. Then swap your `WAYASECK_TEST_...` key for the live `WAYASECK_...` key — the rest of your code stays the same.

Contributing
------------

[](#contributing)

See [CONTRIBUTING.md](CONTRIBUTING.md).

License
-------

[](#license)

MIT

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance90

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 58.8% 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 ~51 days

Total

2

Last Release

45d ago

Major Versions

v1.0.0 → v2.0.02026-07-16

PHP version history (2 changes)v1.0.0PHP &gt;=7.4

v2.0.0PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/8a2d752971df2f77e79b55dc64e39e64526ed53ee9dd47c87162e11931367d6c?d=identicon)[wayaquick](/maintainers/wayaquick)

---

Top Contributors

[![Pils36](https://avatars.githubusercontent.com/u/35952059?v=4)](https://github.com/Pils36 "Pils36 (20 commits)")[![010binary](https://avatars.githubusercontent.com/u/99992586?v=4)](https://github.com/010binary "010binary (8 commits)")[![SemzyTheMan](https://avatars.githubusercontent.com/u/92394924?v=4)](https://github.com/SemzyTheMan "SemzyTheMan (6 commits)")

---

Tags

paymentsNigeriacollectfintechpayoutbvnwayapaywayaquick

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/wayaquick-payment-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/wayaquick-payment-sdk/health.svg)](https://phpackages.com/packages/wayaquick-payment-sdk)
```

PHPackages © 2026

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