paystack-subaccounts

Paystack Subaccounts API — create and manage subaccounts for split payments between your main account and sub-merchants. Configure percentage charges, settlement banks, settlement schedules, and contact details. Use this skill whenever building a marketplace, implementing split payments, onboarding sub-merchants, configuring payout schedules (auto/weekly/monthly/manual), or managing multi-vendor payment flows. Also use when you see references to subaccount_code, ACCT_ prefixed codes, percentage_charge, or the /subaccount endpoint.

Paystack Subaccounts

The Subaccounts API lets you create and manage subaccounts for split payments. Subaccounts represent sub-merchants/vendors who receive a portion of each payment.

Depends on: paystack-setup for the paystackRequest helper.
Related: paystack-splits for multi-party split configurations.

Endpoints

MethodEndpointDescription
POST/subaccountCreate a subaccount
GET/subaccountList subaccounts
GET/subaccount/:id_or_codeFetch a subaccount
PUT/subaccount/:id_or_codeUpdate a subaccount

Create Subaccount

POST /subaccount

ParamTypeRequiredDescription
business_namestringYesName of the sub-merchant business
bank_codestringYesBank code (from List Banks endpoint)
account_numberstringYesBank account number for settlements
percentage_chargefloatYesPercentage the main account receives from each payment
descriptionstringNoDescription of the subaccount
primary_contact_emailstringNoContact email
primary_contact_namestringNoContact person name
primary_contact_phonestringNoContact phone number
metadatastringNoStringified JSON with custom fields
const subaccount = await paystackRequest<{
  subaccount_code: string;
  business_name: string;
  percentage_charge: number;
}>("/subaccount", {
  method: "POST",
  body: JSON.stringify({
    business_name: "Vendor Store",
    settlement_bank: "058",        // GTBank
    account_number: "0123456047",
    percentage_charge: 20,         // Main account gets 20%, subaccount gets 80%
    description: "Electronics vendor",
    primary_contact_email: "[email protected]",
  }),
});
// subaccount.data.subaccount_code → "ACCT_6uujpqtzmnufzkw"

List Subaccounts

GET /subaccount

ParamTypeRequiredDescription
perPageintegerNoRecords per page (default: 50)
pageintegerNoPage number (default: 1)
fromdatetimeNoStart date
todatetimeNoEnd date
const subaccounts = await paystackRequest("/subaccount?perPage=20&page=1");

Fetch Subaccount

GET /subaccount/:id_or_code

const sub = await paystackRequest(
  `/subaccount/${encodeURIComponent("ACCT_6uujpqtzmnufzkw")}`
);

Update Subaccount

PUT /subaccount/:id_or_code

ParamTypeRequiredDescription
business_namestringYesBusiness name
descriptionstringYesDescription
bank_codestringNoNew bank code
account_numberstringNoNew account number
activebooleanNotrue to activate, false to deactivate
percentage_chargefloatNoUpdated percentage
settlement_schedulestringNoauto (T+1), weekly, monthly, or manual
primary_contact_emailstringNoUpdated contact email
primary_contact_namestringNoUpdated contact name
primary_contact_phonestringNoUpdated contact phone
metadatastringNoStringified JSON
await paystackRequest(
  `/subaccount/${encodeURIComponent("ACCT_6uujpqtzmnufzkw")}`,
  {
    method: "PUT",
    body: JSON.stringify({
      business_name: "Vendor Store Global",
      description: "International electronics vendor",
      settlement_schedule: "weekly",
      percentage_charge: 15,
    }),
  }
);

Settlement Schedules

ScheduleDescription
autoPayout is T+1 (next business day) — default
weeklyPayout every week
monthlyPayout every month
manualPayout only when requested

Using Subaccounts in Transactions

Pass the subaccount code when initializing a transaction:

// Initialize transaction with subaccount split
const tx = await paystackRequest("/transaction/initialize", {
  method: "POST",
  body: JSON.stringify({
    email: "[email protected]",
    amount: 500000,
    subaccount: "ACCT_6uujpqtzmnufzkw",
    // Optional overrides:
    // transaction_charge: 10000,  // Fixed charge in subunits (overrides percentage)
    // bearer: "subaccount",       // Who bears Paystack fees: "account" or "subaccount"
  }),
});

Marketplace Pattern

// 1. Onboard vendor → create subaccount
const vendor = await paystackRequest("/subaccount", {
  method: "POST",
  body: JSON.stringify({
    business_name: "Vendor A",
    settlement_bank: "058",
    account_number: "0123456789",
    percentage_charge: 10, // Platform takes 10%
  }),
});

// 2. Customer buys from vendor → charge with subaccount
await paystackRequest("/transaction/initialize", {
  method: "POST",
  body: JSON.stringify({
    email: "[email protected]",
    amount: 100000,
    subaccount: vendor.data.subaccount_code,
    bearer: "subaccount", // Vendor bears Paystack fees
  }),
});
// Platform gets 10%, Vendor gets 90% minus Paystack fees
paystack-subaccounts — skill by rexedge | Shared Context