paystack-dedicated-accounts
SKILL.md
Paystack Dedicated Virtual Accounts
The Dedicated Virtual Account API lets you create and manage unique payment account numbers for your customers. Available for Nigerian and Ghanaian merchants.
Depends on: paystack-setup for the
paystackRequesthelper.
Related: paystack-subaccounts and paystack-splits for splitting DVA transactions.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /dedicated_account |
Create DVA for existing customer |
| POST | /dedicated_account/assign |
Create customer + assign DVA in one step |
| GET | /dedicated_account |
List dedicated accounts |
| GET | /dedicated_account/:id |
Fetch a dedicated account |
| GET | /dedicated_account/requery |
Requery for new transactions |
| DELETE | /dedicated_account/:id |
Deactivate a dedicated account |
| POST | /dedicated_account/split |
Add split to DVA transactions |
| DELETE | /dedicated_account/split |
Remove split from DVA |
| GET | /dedicated_account/available_providers |
List available bank providers |
Fetch Bank Providers
Always check available providers first:
const providers = await paystackRequest<Array<{
provider_slug: string;
bank_id: number;
bank_name: string;
}>>("/dedicated_account/available_providers");
// e.g. [{ provider_slug: "wema-bank", bank_id: 20, bank_name: "Wema Bank" }]
Create DVA for Existing Customer
POST /dedicated_account
| Param | Type | Required | Description |
|---|---|---|---|
customer |
string | Yes | Customer ID or code |
preferred_bank |
string | No | Bank slug (e.g. wema-bank, access-bank) |
subaccount |
string | No | Subaccount code for split payments |
split_code |
string | No | Split code for multi-party splits |
first_name |
string | No | Customer first name |
last_name |
string | No | Customer last name |
phone |
string | No | Customer phone number |
const dva = await paystackRequest<{
bank: { name: string; slug: string };
account_name: string;
account_number: string;
assigned: boolean;
active: boolean;
}>("/dedicated_account", {
method: "POST",
body: JSON.stringify({
customer: "CUS_dy1r7ts03zixbq5",
preferred_bank: "wema-bank",
}),
});
// dva.data.account_number → "9930000737"
Assign DVA (Create Customer + DVA)
POST /dedicated_account/assign — creates the customer, validates, and assigns a DVA in one step.
| Param | Type | Required | Description |
|---|---|---|---|
email |
string | Yes | Customer email |
first_name |
string | Yes | First name |
last_name |
string | Yes | Last name |
phone |
string | Yes | Phone number |
preferred_bank |
string | Yes | Bank slug |
country |
string | Yes | NG or GH |
account_number |
string | No | Customer's account number |
bvn |
string | No | Bank Verification Number (Nigeria) |
bank_code |
string | No | Customer's bank code |
subaccount |
string | No | Subaccount code for split |
split_code |
string | No | Split code for multi-party split |
await paystackRequest("/dedicated_account/assign", {
method: "POST",
body: JSON.stringify({
email: "janedoe@test.com",
first_name: "Jane",
last_name: "Doe",
phone: "+2348100000000",
preferred_bank: "wema-bank",
country: "NG",
}),
});
// Response: { status: true, message: "Assign dedicated account in progress" }
List Dedicated Accounts
GET /dedicated_account
| Param | Type | Required | Description |
|---|---|---|---|
active |
boolean | No | Filter by active status |
currency |
string | No | NGN or GHS |
provider_slug |
string | No | Bank slug filter |
bank_id |
string | No | Bank ID filter |
customer |
string | No | Customer ID filter |
const accounts = await paystackRequest("/dedicated_account?active=true¤cy=NGN");
Fetch Dedicated Account
const account = await paystackRequest(`/dedicated_account/${dedicatedAccountId}`);
Requery for New Transactions
await paystackRequest(
`/dedicated_account/requery?account_number=9930000737&provider_slug=wema-bank&date=2024-01-15`
);
Deactivate Dedicated Account
await paystackRequest(`/dedicated_account/${dedicatedAccountId}`, {
method: "DELETE",
});
Split DVA Transactions
Add a split to DVA incoming payments:
await paystackRequest("/dedicated_account/split", {
method: "POST",
body: JSON.stringify({
customer: "CUS_dy1r7ts03zixbq5",
split_code: "SPL_e7jnRLtzla",
// OR use subaccount instead of split_code:
// subaccount: "ACCT_6uujpqtzmnufzkw",
}),
});
Remove a split:
await paystackRequest("/dedicated_account/split", {
method: "DELETE",
body: JSON.stringify({
account_number: "0033322211",
}),
});
Full DVA Flow
// 1. Check available providers
const providers = await paystackRequest("/dedicated_account/available_providers");
// 2. Create customer first (or use existing)
const customer = await paystackRequest("/customer", {
method: "POST",
body: JSON.stringify({
email: "user@example.com",
first_name: "John",
last_name: "Doe",
phone: "+2348012345678",
}),
});
// 3. Create DVA for the customer
const dva = await paystackRequest("/dedicated_account", {
method: "POST",
body: JSON.stringify({
customer: customer.data.customer_code,
preferred_bank: "wema-bank",
}),
});
// 4. Display account details to user for bank transfer
console.log(`Pay to: ${dva.data.account_number} (${dva.data.bank.name})`);
// 5. Listen for charge.success webhook to confirm payment
// See paystack-webhooks skill for webhook handling
Weekly Installs
8
Repository
rexedge/paystackGitHub Stars
1
First Seen
8 days ago
Security Audits
Installed on
github-copilot8
cursor8
opencode8
cline7
codex7
kimi-cli7