opsofts / laravel-tgipay
A minimal TGIPay integration for Laravel, built directly on Laravel's own HTTP client.
Requires
- php: ^8.2
- illuminate/http: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
README
A minimal TGIPay integration for Laravel, built directly on Laravel's own HTTP client (Illuminate\Support\Facades\Http). No external HTTP SDK dependency — just illuminate/support/illuminate/http, which ship with every Laravel app and are maintained on the same cadence as the framework itself.
Built against TGIPay's user guide as of mid-2026.
What it does
- Initiate a payment —
POST /integration/api/v1/payment/initiate, server-to-server - Get the checkout URL —
GET /integration/api/v1/payment/{transactionReference}, returns a hosted payment page URL to redirect the customer to - Initialize a transaction — a convenience wrapper that does both of the above in one call, matching the shape of the other Opsofts payment packages
- Verify a transaction —
GET /integration/api/v1/payment/status/{transactionReference}, the authoritative source of truth for payment status
Requirements
- PHP 8.2+
- Laravel 11, 12, or 13
Install
composer require opsofts/laravel-tgipay php artisan vendor:publish --tag=tgipay-config
Set your key in .env. Generate it from the TGIPay merchant portal under Integrations:
TGIPAY_PUBLIC_KEY=...
TGIPay's docs don't describe a separate sandbox API host — Test vs Live mode is controlled by a toggle in the merchant dashboard and appears to just change which key is active, against the same integration-service.tgipay.com base URL. Override TGIPAY_BASE_URL if that turns out not to be the case for your account.
Usage
use Opsofts\LaravelTgipay\Facades\Tgipay; // Initialize a transaction (initiate + get checkout URL in one call) $transaction = Tgipay::initializeTransaction([ 'customerFirstName' => $customer->first_name, 'customerLastName' => $customer->last_name, 'customerEmail' => $customer->email, 'amount' => 1000, // decimal Naira, NOT kobo 'transactionReference' => (string) Str::uuid(), // you generate this 'currency' => 'NGN', // the only currency TGIPay's docs currently mention ]); // redirect the payer to $transaction['data']['url'] // ...or do it in two explicit steps if you want to store the reference // between initiating and generating the checkout link: Tgipay::initiatePayment($payload); $transaction = Tgipay::getPaymentUrl($payload['transactionReference']); // After the customer returns via your callback URL, ALWAYS verify // server-side before giving value -- see "What's missing" below for why // this step is not optional with TGIPay specifically. $result = Tgipay::verifyTransaction($transactionReference); if ($result['data']['paymentStatus'] === 'completed') { // mark the order/payment as paid }
What's missing (be aware of this before going live)
TGIPay's current public documentation does not describe:
- A refund API. No refund endpoint is documented anywhere in their user guide. If you need to refund a customer, that appears to currently be a merchant-dashboard/support-ticket operation, not something this package (or any API call) can do.
refund()is intentionally not implemented here — don't assume it exists. - A webhook signature scheme. TGIPay's redirect callback (
?status=success&ref={transactionReference}&tgipay=1) is a plain, unsigned query string — there's no HMAC header to verify, unlike Paystack/Flutterwave/Monnify. This means the callback alone is not cryptographically trustworthy;verifyTransaction()against the status endpoint is the only reliable way to confirm a payment, not just a best practice. Always call it before fulfilling an order, and never truststatus=successin the URL on its own. - A documented use for the Private Key. TGIPay's merchant portal lets you generate both a Public Key and a Private Key ("for server-side operations"), but every documented endpoint in the current user guide only uses the Public Key via the
integration-keyheader. This package accepts aTGIPAY_PRIVATE_KEYenv value and stores it in config for forward-compatibility, but nothing currently uses it — it may become relevant if TGIPay documents a webhook/refund capability later.
If TGIPay's documentation expands to cover any of these, open an issue/PR — the package is intentionally small and easy to extend (src/Tgipay.php).
What this package deliberately does not do
No card storage, no saved payment methods. It only ever talks to TGIPay's API and hands back what TGIPay returns — persisting references/statuses on your own models is the calling application's responsibility, same as with any SDK.
Testing
Http::fake() works exactly as it does for any Laravel HTTP client usage — fake the integration-service.tgipay.com/* pattern in your tests rather than hitting the real API. No custom test helpers are provided; standard Laravel HTTP testing covers this package fully.
License
MIT.