Taking payment
Check a PIN
Look up a PIN before you redeem it: its balance, currency, status and whether your account can redeem it. Nothing is debited and the PIN is not changed.
HMAC-signed request with a unique Idempotency-Key header. Authentication
$afropin->brand->pins->check($params)afropin.brand.pins.check(params)afropin.brand.pins.check(params)afropin.brand().pins().check(params)Body parameters
The PIN code the customer gave you, with or without dashes. In test mode, use one of the test PINs.
The amount you intend to redeem. When given, the response says whether that exact amount can be redeemed, including the rule that single-use PINs must be redeemed in full.
Who would pay the redemption fee, as on Take payment with a PIN. With customer, redeemable_amount is the most you can redeem with the fee on top (for a single-use PIN, the exact amount to send).
Response fields
The PIN code with its middle digits hidden, safe to show or store.
What is left on the PIN, in currency.
The PIN's currency. Redeeming credits your wallet in this currency.
The PIN's status.
whole: must be redeemed for its whole balance in one go. partial: any amount up to the balance.
Whether a redeem call would succeed right now (for amount, when you sent one).
When can_redeem is false, the error code Take payment with a PIN would return, for example pin_expired or pin_not_accepted_here. With reason_message for display.
The most a redeem call may pass as amount now. For single-use PINs this is the exact amount to redeem. 0 when the PIN can't be redeemed here at all.
The PIN's daily spending limit, set by its customer, or null without one.
What is left of it today (it resets at midnight, Lagos time). redeemable_amount already allows for it; an amount over it makes reason pin_daily_limit_reached.
Your redemption fee on this PIN's product, as a percentage. 0 for test PINs.
As sent (default brand).
For the amount you sent: the fee, with amount_debited (what the PIN would pay) and amount_credited (what your wallet would get). null when no amount was sent.
pin_type_id and name of the PIN's product. null for test PINs.
When the PIN expires, ISO 8601. null for test PINs.
pin_code_unknown, pin_code_replaced or pin_checksum_failed (or test_pin_unknown in test mode). A PIN that is found but can't be redeemed by you returns 200 with can_redeem: false and the reason, so you can tell the customer before taking payment.rate_limited until the window passes. A successful lookup resets the count.Request
{
"pin_code": "2340-1000-0000-1001",
"amount": 2500
}
Response 200
{
"ok": true,
"data": {
"pin_mask": "2340-****-****-1001",
"balance": 25000,
"currency": "NGN",
"status": "active",
"spend_rule": "partial",
"redeemable_amount": 25000,
"redemption_fee_percent": 0,
"fee_paid_by": "brand",
"fee": 0,
"amount_debited": 2500,
"amount_credited": 2500,
"can_redeem": true,
"reason": null,
"reason_message": null,
"pin_type": null,
"expires_at": null,
"mode": "test"
}
}
Response not redeemable
{
"ok": true,
"data": {
"pin_mask": "2340-****-****-4004",
"balance": 12000,
"currency": "NGN",
"status": "blocked",
"spend_rule": "partial",
"redeemable_amount": 0,
"redemption_fee_percent": 0,
"fee_paid_by": "brand",
"fee": null,
"amount_debited": null,
"amount_credited": null,
"can_redeem": false,
"reason": "pin_blocked",
"reason_message": "This PIN is blocked",
"pin_type": null,
"expires_at": null,
"mode": "test"
}
}
Errors
Failed requests return a stable code with a translated message. Branch on code, never on the message.
validation_error
Some fields are missing or invalid
wrong_account_type
Your account type cannot use this endpoint
redeeming_disabled
Redeeming PINs is not switched on for your account. Contact support
pin_checksum_failed
This is not a valid PIN code: its check digit is wrong
pin_code_unknown
No PIN has this code
pin_code_replaced
This code has been replaced by a newer one; ask the customer for their latest code
test_pin_unknown
Test keys only accept the test PINs listed in the docs
rate_limited
Too many requests. Wait a moment and try again
internal_error
Something went wrong on our side. Try again; if it keeps happening, contact support
{
"ok": false,
"error": {
"code": "wrong_account_type",
"message": "Your account type cannot use this endpoint",
"fields": null
}
}
All error codes →