← Slimpay.ng

Used by every "Try It" panel across these docs to call app.slimpay.ng for real. Get one from Authentication — register or log in, then paste the token here. Stored only in this browser (localStorage), never sent anywhere but the Slimpay API, and auto-cleared after 8 hours.

SDKs

Webhooks

Slimpay POSTs a JSON notification to your webhook URL when a school-fee payment is confirmed. The REST-level payload and signature scheme are also described in School Webhooks.

Handling them

php
use Slimpay\School\{WebhookHandler, WebhookEvent};

$webhooks = (new WebhookHandler(getenv('SLIMPAY_WEBHOOK_SECRET')))
    ->on('payment.received', function (WebhookEvent $e) {
        if ($e->isTest()) {
            return;                                   // ignore "Send Test Webhook" pings
        }
        markFeePaid(
            studentId: $e->studentId(),
            amount:    $e->amount(),
            reference: $e->checkoutReference(),
        );
    });

$webhooks->handle(file_get_contents('php://input'), getallheaders());
http_response_code(200);
  • on('*', ...) receives every event type.
  • parse() verifies and returns the event without calling listeners, if you prefer to route yourself.
  • Respond with any 2xx quickly and do heavy work in a queue.

Payload reference

json
{
  "event": "payment.received",
  "checkout_reference": "SCH-XXXXXXXXXXXX",
  "student_name": "Jane Doe",
  "student_id": "STU-2201",
  "student_class": "SS3",
  "student_verified": true,
  "verified_student_data": { "name": "Jane Doe", "class": "SS3" },
  "amount": 25000,
  "school_net": 24625,
  "platform_fee": 375,
  "timestamp": "2026-07-21T10:32:00+00:00"
}
FieldNotes
checkout_referenceUnique per payment. Use it as your idempotency key.
student_id, student_name, student_classAs typed by the payer, or from your lookup when verified
student_verified / verified_student_dataOnly populated when student lookup confirmed the student; otherwise false / null
amountTotal paid, in naira
school_net / platform_feeYour share and Slimpay's fee
timestampISO-8601 time of the event

Some older payloads carry transaction_id instead of checkout_reference; WebhookEvent::checkoutReference() returns whichever is present. Every field is also available in $event->payload.

Signatures

When a signing secret exists for your school, each webhook carries X-Slimpay-Timestamp and X-Slimpay-Signature, the same scheme as lookups (see Security). Pass the secret to WebhookHandler and unsigned or forged requests are rejected with InvalidSignatureException (respond 401).

Generate a secret

Until you generate a webhook secret, webhooks are sent unsigned. Treat them as hints and verify payment status and amount before releasing anything valuable.

Idempotency

Slimpay does not auto-retry, but you can press Resend on a delivery, which re-sends the same payload. Your handler must tolerate duplicates:

php
->on('payment.received', function (WebhookEvent $e) {
    DB::transaction(function () use ($e) {
        // unique index on payments.slimpay_reference
        if (Payment::where('slimpay_reference', $e->checkoutReference())->exists()) {
            return;
        }
        Payment::create([...]);
    });
});

Failure behaviour

Your responseWhat Slimpay records
2xxDelivered
non-2xx, timeout (5 s), DNS or TLS errorFailed, with the status or error shown in the delivery log

Fix your endpoint, then use Resend on the failed delivery. It goes to your current webhook URL. Send Test Webhook on the Webhooks page sends a sample event with an SCH-TEST... reference, which $event->isTest() detects.