skills/paystack-customers/SKILL.md
Paystack Customers API — create, list, fetch, update, validate identity, whitelist/blacklist, manage authorizations, and direct debit operations. Use this skill whenever creating or managing customer records on Paystack, validating customer identity with BVN or bank account, whitelisting or blacklisting customers by risk action, deactivating saved card authorizations, setting up direct debit mandates, or building customer management dashboards. Also use when you see references to customer_code, CUS_ prefixed codes, risk_action, or /customer/authorization endpoints.
npx skillsauth add rexedge/paystack paystack-customersInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The Customers API lets you create and manage customer records on your integration. Customers are automatically created on first charge, but you can also create them explicitly.
Depends on: paystack-setup for the
paystackRequesthelper and environment config.
| Method | Endpoint | Description |
| --- | --- | --- |
| POST | /customer | Create a customer |
| GET | /customer | List customers |
| GET | /customer/:email_or_code | Fetch a customer |
| PUT | /customer/:code | Update a customer |
| POST | /customer/:code/identification | Validate customer identity |
| POST | /customer/set_risk_action | Whitelist/Blacklist a customer |
| POST | /customer/authorization/initialize | Initialize authorization |
| GET | /customer/authorization/verify/:reference | Verify authorization |
| POST | /customer/:id/initialize-direct-debit | Initialize direct debit |
| PUT | /customer/:id/directdebit-activation-charge | Activate direct debit |
| GET | /customer/:id/directdebit-mandate-authorizations | Fetch mandate authorizations |
| POST | /customer/authorization/deactivate | Deactivate an authorization |
POST /customer
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| email | string | Yes | Customer's email address |
| first_name | string | No | Customer's first name |
| last_name | string | No | Customer's last name |
| phone | string | No | Customer's phone number |
| metadata | object | No | Key/value pairs for additional info |
Note:
first_name,last_name, andphonebecome required when assigning a Dedicated Virtual Account to customers in Betting, Financial Services, or General Service business categories.
const customer = await paystackRequest<{
email: string;
customer_code: string;
id: number;
}>("/customer", {
method: "POST",
body: JSON.stringify({
email: "[email protected]",
first_name: "Zero",
last_name: "Sum",
phone: "+2348123456789",
}),
});
// customer.data.customer_code → "CUS_xnxdt6s1zg1f4nx"
GET /customer
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| perPage | integer | No | Records per page (default: 50) |
| page | integer | No | Page number (default: 1) |
| from | datetime | No | Start date e.g. 2016-09-24T00:00:05.000Z |
| to | datetime | No | End date |
const customers = await paystackRequest("/customer?perPage=20&page=1");
GET /customer/:email_or_code
Returns full customer details including transactions, subscriptions, and authorizations arrays.
const customer = await paystackRequest(
`/customer/${encodeURIComponent("CUS_xnxdt6s1zg1f4nx")}`
);
// Includes: customer.data.authorizations[].authorization_code
PUT /customer/:code
await paystackRequest(`/customer/${encodeURIComponent("CUS_xnxdt6s1zg1f4nx")}`, {
method: "PUT",
body: JSON.stringify({
first_name: "BoJack",
last_name: "Horseman",
}),
});
POST /customer/:code/identification
Validates a customer's identity via bank account verification. Returns 202 Accepted — validation happens asynchronously. Listen for customeridentification.success or customeridentification.failed webhooks.
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| country | string | Yes | 2-letter country code (e.g. NG) |
| type | string | Yes | bank_account (only supported type) |
| account_number | string | Yes | Customer's bank account number |
| bvn | string | Yes | Bank Verification Number |
| bank_code | string | Yes | Bank code (from List Banks endpoint) |
| first_name | string | Yes | Customer's first name |
| last_name | string | Yes | Customer's last name |
| middle_name | string | No | Customer's middle name |
await paystackRequest(
`/customer/${encodeURIComponent("CUS_xnxdt6s1zg1f4nx")}/identification`,
{
method: "POST",
body: JSON.stringify({
country: "NG",
type: "bank_account",
account_number: "0123456789",
bvn: "20012345677",
bank_code: "007",
first_name: "Asta",
last_name: "Lavista",
}),
}
);
// Returns: { status: true, message: "Customer Identification in progress" }
POST /customer/set_risk_action
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| customer | string | Yes | Customer code or email |
| risk_action | string | No | default, allow (whitelist), or deny (blacklist) |
await paystackRequest("/customer/set_risk_action", {
method: "POST",
body: JSON.stringify({
customer: "CUS_xr58yrr2ujlft9k",
risk_action: "deny", // Blacklist this customer
}),
});
POST /customer/authorization/initialize
Create a reusable authorization code for recurring direct debit transactions.
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| email | string | Yes | Customer's email |
| channel | string | Yes | direct_debit (only supported option) |
| callback_url | string | No | URL to redirect customer after authorization |
| account | object | No | { number, bank_code } for bank account details |
| address | object | No | { street, city, state } for customer address |
const auth = await paystackRequest<{
redirect_url: string;
access_code: string;
reference: string;
}>("/customer/authorization/initialize", {
method: "POST",
body: JSON.stringify({
email: "[email protected]",
channel: "direct_debit",
callback_url: "https://example.com/callback",
}),
});
// Redirect customer to auth.data.redirect_url
GET /customer/authorization/verify/:reference
const result = await paystackRequest(
`/customer/authorization/verify/${encodeURIComponent(reference)}`
);
// result.data.authorization_code, result.data.active
POST /customer/:id/initialize-direct-debit
Link a bank account to a customer for direct debit transactions.
const result = await paystackRequest(
`/customer/${customerId}/initialize-direct-debit`,
{
method: "POST",
body: JSON.stringify({
account: { number: "0123456789", bank_code: "058" },
address: { street: "Some Where", city: "Ikeja", state: "Lagos" },
}),
}
);
// Redirect customer to result.data.redirect_url
PUT /customer/:id/directdebit-activation-charge
Trigger an activation charge on an inactive mandate.
await paystackRequest(`/customer/${customerId}/directdebit-activation-charge`, {
method: "PUT",
body: JSON.stringify({ authorization_id: 1069309917 }),
});
GET /customer/:id/directdebit-mandate-authorizations
const mandates = await paystackRequest(
`/customer/${customerId}/directdebit-mandate-authorizations`
);
// mandates.data[].status, mandates.data[].authorization_code
POST /customer/authorization/deactivate
Permanently deactivate a saved card/authorization so it can no longer be used for charges.
await paystackRequest("/customer/authorization/deactivate", {
method: "POST",
body: JSON.stringify({
authorization_code: "AUTH_xxxIjkZVj5",
}),
});
development
Paystack webhook integration — signature validation with HMAC SHA512, event parsing, IP whitelisting, retry policy, and all supported event types. Use this skill whenever setting up a webhook endpoint for Paystack, validating x-paystack-signature headers, handling charge.success or transfer.success events, debugging webhook delivery failures, implementing idempotent event processing, or building any server-side Paystack event listener. Also use when encountering webhook timeout issues or needing the list of Paystack webhook IP addresses.
tools
Paystack Verification API — KYC verification tools for resolving bank accounts, validating account ownership, and looking up card BIN information. Use this skill whenever verifying bank account details before transfers, confirming account holder names, validating customer identity for compliance, looking up card brand/type/bank from BIN, or implementing KYC flows. Also use when you see references to /bank/resolve, /bank/validate, /decision/bin endpoints, or need to match account numbers to names.
development
Paystack Transfers API — send money to bank accounts and mobile wallets. Initiate single and bulk transfers, finalize OTP-verified transfers, list, fetch, and verify transfer status. Use this skill whenever implementing payouts, disbursements, vendor payments, withdrawal flows, or any feature that sends money from your Paystack balance to recipients. Also use when you see references to transfer_code, TRF_ prefixed codes, the /transfer endpoint, or need to handle transfer OTP verification.
development
Paystack Transfer Recipients API — create, list, fetch, update, and delete transfer recipients (beneficiaries) for payouts. Supports NUBAN (Nigeria), GHIPSS (Ghana), Mobile Money, BASA (South Africa), and authorization-based recipients. Use this skill whenever adding bank accounts or mobile wallets as payout destinations, creating transfer recipients before initiating transfers, managing beneficiary lists, or doing bulk recipient creation. Also use when you see references to recipient_code, RCP_ prefixed codes, or the /transferrecipient endpoint.