skills/paystack-refunds/SKILL.md
Paystack Refunds API — create full or partial refunds, retry failed refunds with customer bank details, list and fetch refund records. Use this skill whenever implementing refund functionality, processing customer refund requests, handling partial refunds, retrying refunds that need attention, or tracking refund status. Also use when you see references to refund.processed, refund.failed, refund.pending webhook events, or the /refund endpoint.
npx skillsauth add rexedge/paystack paystack-refundsInstall 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 Refunds API lets you create and manage refunds for transactions. Supports full and partial refunds.
Depends on: paystack-setup for the
paystackRequesthelper.
Related: paystack-webhooks forrefund.processed,refund.failed,refund.pendingevents.
| Method | Endpoint | Description |
| --- | --- | --- |
| POST | /refund | Create a refund |
| POST | /refund/retry_with_customer_details/:id | Retry a failed refund |
| GET | /refund | List refunds |
| GET | /refund/:id | Fetch a refund |
POST /refund
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| transaction | string | Yes | Transaction reference or ID |
| amount | integer | No | Amount in subunits (defaults to full transaction amount) |
| currency | string | No | Currency code |
| customer_note | string | No | Reason shown to customer |
| merchant_note | string | No | Internal reason for merchant |
const refund = await paystackRequest<{
status: string;
amount: number;
transaction: { reference: string; amount: number };
}>("/refund", {
method: "POST",
body: JSON.stringify({
transaction: "T685312322670591", // Transaction reference or ID
}),
});
// refund.message → "Refund has been queued for processing"
await paystackRequest("/refund", {
method: "POST",
body: JSON.stringify({
transaction: "T685312322670591",
amount: 5000, // Refund ₦50 of a larger transaction
customer_note: "Partial refund for damaged item",
merchant_note: "Customer reported damage on item #3",
}),
});
POST /refund/retry_with_customer_details/:id
Retry a refund with needs-attention status by providing the customer's bank account details.
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| refund_account_details | object | Yes | Customer's bank account details |
| refund_account_details.currency | string | Yes | Currency (same as original payment) |
| refund_account_details.account_number | string | Yes | Customer's bank account number |
| refund_account_details.bank_id | string | Yes | Bank ID (from List Banks endpoint) |
await paystackRequest(`/refund/retry_with_customer_details/${refundId}`, {
method: "POST",
body: JSON.stringify({
refund_account_details: {
currency: "NGN",
account_number: "1234567890",
bank_id: "9",
},
}),
});
GET /refund
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| transaction | string | No | Filter by transaction ID |
| currency | string | No | Filter by currency |
| from | date | No | Start date e.g. 2016-09-21 |
| to | date | No | End date |
| perPage | integer | No | Records per page (default: 50) |
| page | integer | No | Page number (default: 1) |
const refunds = await paystackRequest("/refund?perPage=20&page=1");
GET /refund/:id
const refund = await paystackRequest(`/refund/${refundId}`);
// refund.data.status → "pending" | "processing" | "processed" | "failed"
| Status | Description |
| --- | --- |
| pending | Refund initiated, awaiting processor |
| processing | Refund received by processor |
| processed | Refund successfully completed |
| failed | Refund failed — your account is credited back |
| needs-attention | Refund needs manual intervention (retry with customer details) |
Listen for these events to track refund lifecycle:
refund.pending — Refund initiatedrefund.processing — Refund being processedrefund.processed — Refund completed successfullyrefund.failed — Refund failed (amount credited back to your account)amount is omitted, the full transaction amount is refundedneeds-attention status, retry with customer's bank account detailsdevelopment
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.