skills/paystack-plans/SKILL.md
Paystack Plans API — create, list, fetch, and update subscription plans with intervals (daily, weekly, monthly, quarterly, biannually, annually). Use this skill whenever creating pricing tiers or recurring billing plans on Paystack, setting up subscription intervals, configuring invoice limits, managing plan currencies, or building a SaaS pricing page. Also use when you see references to plan_code, PLN_ prefixed codes, or the /plan endpoint.
npx skillsauth add rexedge/paystack paystack-plansInstall 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 Plans API lets you create and manage installment/recurring payment options. Plans define the billing cycle, amount, and currency for subscriptions.
Depends on: paystack-setup for the
paystackRequesthelper.
Related: paystack-subscriptions for subscribing customers to plans.
| Method | Endpoint | Description |
| --- | --- | --- |
| POST | /plan | Create a plan |
| GET | /plan | List plans |
| GET | /plan/:id_or_code | Fetch a plan |
| PUT | /plan/:id_or_code | Update a plan |
POST /plan
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| name | string | Yes | Name of the plan |
| amount | integer | Yes | Amount in subunits (e.g. 500000 = ₦5,000) |
| interval | string | Yes | daily, weekly, monthly, quarterly, biannually, annually |
| description | string | No | Plan description |
| send_invoices | boolean | No | Send invoices to customers (default: true) |
| send_sms | string | No | Send SMS to customers (default: true) |
| currency | string | No | Currency code e.g. NGN, GHS, ZAR, USD |
| invoice_limit | integer | No | Max invoices to raise during subscription |
const plan = await paystackRequest<{
name: string;
plan_code: string;
amount: number;
interval: string;
}>("/plan", {
method: "POST",
body: JSON.stringify({
name: "Pro Plan",
amount: 500000, // ₦5,000
interval: "monthly",
currency: "NGN",
send_invoices: true,
invoice_limit: 0, // 0 = unlimited
}),
});
// plan.data.plan_code → "PLN_gx2wn530m0i3w3m"
GET /plan
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| perPage | integer | No | Records per page (default: 50) |
| page | integer | No | Page number (default: 1) |
| status | string | No | Filter by plan status |
| interval | string | No | Filter by interval |
| amount | integer | No | Filter by amount (in subunits) |
const plans = await paystackRequest("/plan?perPage=20&page=1&interval=monthly");
GET /plan/:id_or_code
Returns plan details including associated subscriptions array.
const plan = await paystackRequest(
`/plan/${encodeURIComponent("PLN_gx2wn530m0i3w3m")}`
);
PUT /plan/:id_or_code
All body params are the same as Create Plan, plus:
| Param | Type | Required | Description |
| --- | --- | --- | --- |
| update_existing_subscriptions | boolean | No | Apply changes to existing subscriptions (default: true) |
await paystackRequest(`/plan/${encodeURIComponent("PLN_gx2wn530m0i3w3m")}`, {
method: "PUT",
body: JSON.stringify({
name: "Pro Plan (Updated)",
amount: 750000,
update_existing_subscriptions: false, // Only affect new subscriptions
}),
});
| Interval | Description |
| --- | --- |
| daily | Charge every day |
| weekly | Charge every 7 days |
| monthly | Charge every month |
| quarterly | Charge every 3 months |
| biannually | Charge every 6 months |
| annually | Charge every 12 months |
async function createPricingTiers() {
const tiers = [
{ name: "Starter", amount: 200000, interval: "monthly" as const },
{ name: "Pro", amount: 500000, interval: "monthly" as const },
{ name: "Enterprise", amount: 2000000, interval: "monthly" as const },
];
const plans = await Promise.all(
tiers.map((tier) =>
paystackRequest("/plan", {
method: "POST",
body: JSON.stringify({
...tier,
currency: "NGN",
send_invoices: true,
}),
})
)
);
return plans.map((p: any) => ({
name: p.data.name,
code: p.data.plan_code,
amount: p.data.amount,
}));
}
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.