LaravelPackages.net
Acme Inc.
Toggle sidebar
bazzly/payoffice

Laravel package to use all fintech payment API and fetch server for pings

10
0
v0.1.0
About bazzly/payoffice

bazzly/payoffice is a Laravel package for laravel package to use all fintech payment api and fetch server for pings. It currently has 0 GitHub stars and 10 downloads on Packagist (latest version v0.1.0). Install it with composer require bazzly/payoffice. Discover more Laravel packages by bazzly or browse all Laravel packages to compare alternatives.

Last updated

Payoffice

All your payment providers in one place.

Latest Version Software License Total Downloads

Payoffice is a Laravel package that solves one specific problem: a payment provider's API can go down or slow down, and your checkout shouldn't blindly trust it. Before sending a customer to a payment gateway, Payoffice can ping the provider's API host and report whether it's up, down, and how fast it's responding — so your app can pick a healthy provider or warn the user instead of failing mid-checkout.

On top of that, it bundles ready-to-use integrations for popular fintech APIs so you don't have to wire each one up from scratch.

Table of contents

Features

  • Provider health check — ping a payment API's host over TCP and get back status (up/down) and latency in milliseconds before deciding whether to use it.
  • Paystack payments — initialize transactions, verify payments, manage plans, customers, subscriptions, payment pages, and subaccounts.
  • Paystack transfers — look up banks, resolve account numbers, create transfer recipients, and send money.
  • Secure transaction references — cryptographically random reference/token generator.
  • Config-driven, multi-provider — Paystack, Flutterwave, Interswitch, and Remita are pre-scaffolded in the published config file.

Requirements

| Requirement | Version | |---|---| | PHP | ^7.2 | ^8.0 | ^8.1 | ^8.2 | ^8.3 | ^8.4 | | Laravel (illuminate/support) | ^6 | ^7 | ^8 | ^9 | ^10 | ^11 | ^12 | ^13 | | guzzlehttp/guzzle | ^6 | ^7 | ^8 | ^9 |

Local development (running the test suite / examples/demo.php) is verified against the latest supported combination — PHP 8.4, Laravel 13, PHPUnit 13, orchestra/testbench 11 — via require-dev, regardless of which older Laravel/PHP version you build against.

Installation

Install via Composer:

composer require bazzly/payoffice

Laravel's package auto-discovery will register Bazzly\Payoffice\PaymentServiceProvider automatically — no manual entry in config/app.php is needed.

Publish the config file and the pings_monitoring migration:

php artisan vendor:publish --provider="Bazzly\Payoffice\PaymentServiceProvider" --tag="config"
php artisan vendor:publish --provider="Bazzly\Payoffice\PaymentServiceProvider" --tag="pings_monitoring"
php artisan migrate

Publishing the config is required — the package reads provider settings from config/payoffice.php once it exists in your app, not from the package's internal copy.

Configuration

The published config/payoffice.php is a list of provider entries. Fill in credentials via your .env file:

# Paystack
PAYSTACK_PUBLIC_KEY=
PAYSTACK_SECRET_KEY=
PAYSTACK_PAYMENT_URL=https://api.paystack.co
PAYSTACK_MERCHANT_EMAIL=
PAYSTACK_MERCHANT_CURRENCY=NGN

# Flutterwave
FLW_PUBLIC_KEY=
FLW_SECRET_KEY=
FLW_SECRET_HASH=

# Interswitch
INTERSWITCH_GATEWAY_TYPE=WEBPAY
INTERSWITCH_CURRENCY=566
INTERSWITCH_SITE_REDIRECT_URL=
INTERSWITCH_ENV=TEST
INTERSWITCH_SPLIT=false
INTERSWITCH_COLLEGE=
INTERSWITCH_SEND_MAIL=false
INTERSWITCH_MAC_KEY=
INTERSWITCH_PRODUCT_ID=
INTERSWITCH_PAY_ITEM_ID=

# Remita
MERCHANTID=
SERVICETYPEID=
FUNDINGACCOUNT=
FUNDINGBANKCODE=
APIKEY=
MANDATETPYE=DD

Each provider entry in config/payoffice.php has a name and APIURL key used by the health-ping feature, plus a provider-specific block (paystack, flutterwave, etc.) used by that provider's integration classes.

Usage

Server / API health ping

PingServer checks whether a payment API host is reachable and how fast it responds, so you can gate checkout on the provider actually being up.

use Bazzly\Payoffice\PingServer;

// PingServer(string $name, string $url, ?int $preferredPingMs = null)
$check = new PingServer('paystack', 'api.paystack.co', 100);

$result = $check->getUrlServerDetails();

// $result = [
//     'name'        => 'paystack',
//     'apiurl'      => 'api.paystack.co',
//     'serverStatus'=> 'up',     // PingServer::UPSTATUS / PingServer::DOWNSTATUS
//     'serverPing'  => 42,       // measured latency in ms
//     'userPing'    => 100,      // your preferred/acceptable threshold (defaults to 10)
// ];

if ($result['serverStatus'] === PingServer::UPSTATUS && $result['serverPing'] <= $result['userPing']) {
    // safe to redirect the customer to this provider
} else {
    // provider is down or too slow — fall back to another provider
}

To check every provider configured in config/payoffice.php in one pass:

use Bazzly\Payoffice\PingServer;

$providers = config('payoffice');

$statuses = collect($providers)->map(function ($provider) {
    $ping = new PingServer($provider['name'], $provider['APIURL']);
    return $ping->getUrlServerDetails();
});

Persisting ping results

If you want a history of ping checks (e.g. for an internal status dashboard), the pings_monitoring migration and PingsMonitoring Eloquent model are included:

use Bazzly\Payoffice\Models\PingsMonitoring;
use Bazzly\Payoffice\PingServer;

$result = (new PingServer('paystack', 'api.paystack.co', 100))->getUrlServerDetails();

PingsMonitoring::create([
    'name'         => $result['name'],
    'apiurl'       => $result['apiurl'],
    'serverStatus' => $result['serverStatus'],
    'serverPing'   => $result['serverPing'],
    'userPing'     => $result['userPing'],
]);

This is a manual step — the package does not currently schedule ping checks for you. Wire it into your own app/Console/Kernel.php schedule if you want periodic checks.

Paystack — payments

GetPaid wraps the Paystack transactions/plans/customers/subscriptions/pages/subaccounts API. Most methods read their payload straight from the current request (i.e. they're meant to be called from a controller handling a form POST), but you can also pass an explicit $data array to bypass that.

use Bazzly\Payoffice\Paystack\GetPaid;

$paystack = new GetPaid();

// Initialize a transaction and redirect the customer to Paystack
public function pay(GetPaid $paystack)
{
    return $paystack->getAuthorizationUrl()->redirectNow();
}

// Or supply the payload explicitly instead of relying on request() input
$paystack->getAuthorizationUrl([
    'amount'    => 500000, // kobo
    'email'     => '[email protected]',
    'reference' => $paystack->genTranxRef(),
]);

// Verify a transaction after the customer returns from Paystack
public function callback(GetPaid $paystack)
{
    if ($paystack->isTransactionVerificationValid()) {
        $payment = $paystack->getPaymentData();
        // mark the order as paid
    }
}

Other available methods:

| Method | Purpose | |---|---| | genTranxRef() | Generate a unique transaction reference | | getAllCustomers() / createCustomer() / fetchCustomer($id) / updateCustomer($id) | Customer management | | getAllPlans() / createPlan() / fetchPlan($code) / updatePlan($code) | Subscription plan management | | createSubscription() / getAllSubscriptions() / getCustomerSubscriptions($id) / getPlanSubscriptions($id) / enableSubscription() / disableSubscription() / fetchSubscription($id) | Subscription management | | createPage() / getAllPages() / fetchPage($id) / updatePage($id) | Paystack payment pages | | createSubAccount() / fetchSubAccount($code) / listSubAccounts($perPage, $page) / updateSubAccount($code) | Split-payment subaccounts | | exportTransactions() / getAllTransactions() | Transaction reporting |

Paystack — transfers & banks

Transfer handles paying money out — bank lookups, recipient creation, and transfers.

use Bazzly\Payoffice\Paystack\Transfer;

$transfer = new Transfer();

// List supported banks
$banks = $transfer->getBanks('nigeria');

// Confirm an account number belongs to the expected owner
$account = $transfer->confirmAccount('0123456789', '058');

// Send money to a bank account
$transfer->sendMonyToAccDetails(
    accName: 'Jane Doe',
    accNumber: '0123456789',
    bankName: 'Guaranty Trust Bank',
    metadata: [
        'bankCode' => '058',
        'source'   => 'balance',
        'amount'   => 500000, // kobo
        'reference'=> $transfer->getBanks() ? uniqid('trf_') : null,
        'reason'   => 'Vendor payout',
    ]
);

// Check your Paystack balance
$balance = $transfer->getBalance();

// Verify a transfer by its reference
$status = $transfer->getVerifyTransfer('trf_abc123');

Transaction reference generator

TransRef generates cryptographically-random reference strings/tokens (useful for anything needing a unique, non-guessable identifier — not limited to Paystack).

use Bazzly\Payoffice\TransRef;

$reference = TransRef::getHashedToken(); // 25-char alphanumeric token by default
$reference = TransRef::getHashedToken(12); // custom length

Testing

composer install
vendor/bin/phpunit

PingServer, GetPaid, and Transfer all have automated coverage. The Paystack tests don't hit the real API — they inject a Guzzle MockHandler via an optional constructor argument (new GetPaid($handlerStack) / new Transfer($handlerStack)), so the suite runs offline with no credentials needed:

use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;

$mock = new MockHandler([
    new Response(200, [], json_encode(['status' => true, 'data' => [/* ... */]])),
]);

$paystack = new GetPaid(HandlerStack::create($mock));

Omit the argument in real usage (new GetPaid()) and it talks to the real Paystack API as normal.

Tests use PHPUnit's #[Test] attribute (PHPUnit\Framework\Attributes\Test), not the older /** @test */ docblock — the latter was removed in PHPUnit 11+. Match that convention for any new test you add.

Local simulation

examples/demo.php is a runnable, no-credentials-needed walkthrough of the whole package — a real network health check via PingServer, plus a mocked Paystack payment and payout flow via GetPaid/Transfer (same MockHandler approach as the tests). Useful for seeing the package work end-to-end without setting up a Laravel app or real API keys:

composer install
php examples/demo.php

Roadmap / known limitations

This package is under active development. Known rough edges before you rely on it in production:

  • Scheduled/periodic pinging and automatic persistence to PingsMonitoring are not wired up yet; you must trigger and store checks yourself.
  • The Paystack integration is a fork of unicodeveloper/laravel-paystack adapted to this package's config structure — behavior should match the upstream package, but hasn't yet been independently re-verified end-to-end here.

Credits

  • ALLI BAZEET — author
  • unicodeveloper — the Paystack integration in src/Paystack is adapted from laravel-paystack; enormous credit for the original, well-documented implementation this was built on.

License

The MIT License (MIT). See LICENSE for details.

Comments