# Paystack GraphQL Schema ## Overview This document describes a GraphQL schema that represents the Paystack REST API domain model. Paystack is a Nigerian payments platform (acquired by Stripe in 2020) that provides payment processing across Nigeria, Ghana, South Africa, Kenya, Côte d'Ivoire, and Egypt. **Important:** Paystack does not publish a native GraphQL API. This schema is a faithful translation of the Paystack REST API surface into GraphQL types, enabling teams that want to expose Paystack data through a GraphQL gateway or federation layer to do so with well-defined types and relationships. Source REST API: https://paystack.com/docs/api/ GitHub: https://github.com/PaystackHQ --- ## Schema file `paystack-schema.graphql` --- ## Type inventory ### Core payment types | Type | Description | |---|---| | `Transaction` | A single payment event — initialized, abandoned, successful, or failed. | | `Charge` | A direct charge initiated programmatically, carrying its challenge step state. | | `Authorization` | A stored card authorization reusable for future charges. | | `Refund` | A full or partial reversal of a transaction. | | `BulkCharge` | A batch charge job against multiple stored authorizations. | | `BulkChargeItem` | An individual item in a bulk charge batch. | ### Customer and identity types | Type | Description | |---|---| | `Customer` | A Paystack customer profile with associated authorizations and risk state. | | `Identification` | A KYC identification submission attached to a customer. | | `BvnResolution` | Result of a BVN (Bank Verification Number) lookup. | | `AccountNumberResolution` | Resolved bank account name and metadata from an account number lookup. | | `CardBin` | Card BIN lookup result with brand, type, country, and bank details. | ### Subscription and billing types | Type | Description | |---|---| | `Plan` | A recurring billing plan definition (interval, amount, currency). | | `Subscription` | A customer's active subscription to a plan. | | `Invoice` | An invoice generated by a subscription cycle or payment request. | | `PaymentRequest` | An email-based invoice-style payment request sent to a customer. | ### Marketplace and split types | Type | Description | |---|---| | `Subaccount` | A vendor or merchant subaccount with its own settlement bank details. | | `Split` | A transaction split configuration routing a payment to multiple subaccounts. | | `SplitSubaccount` | Join type linking a subaccount to a split with its share value. | ### Transfer and payout types | Type | Description | |---|---| | `Transfer` | An outbound transfer from Paystack balance to a bank account or mobile money wallet. | | `TransferRecipient` | A named recipient for transfers (bank account or mobile money). | | `BulkTransfer` | A batch of transfers initiated in a single call. | | `Balance` | The current Paystack account balance per currency. | | `BalanceLedgerEntry` | A single entry in the balance ledger. | ### Product and page types | Type | Description | |---|---| | `Product` | An inventory product that can be sold via a payment page. | | `PaymentPage` | A Paystack-hosted payment page for collecting payments without checkout code. | | `PaymentPageProduct` | Join type linking a product to a payment page. | ### Settlement and financial types | Type | Description | |---|---| | `Settlement` | A net payout batch to the merchant's bank account. | | `SettlementTransaction` | A transaction record within a settlement batch. | | `Dispute` | A chargeback or dispute raised against a transaction. | | `DisputeEvidence` | Evidence attached to a dispute during the response workflow. | ### Banking and configuration types | Type | Description | |---|---| | `Bank` | A bank entry from the Paystack bank directory. | | `Country` | A supported country with its payment channels and integration metadata. | | `DedicatedAccount` | A dedicated NUBAN virtual account assigned to a customer. | | `DedicatedAccountProvider` | A bank provider available for dedicated account creation. | | `DedicatedAccountSplit` | A split routing rule on a dedicated virtual account. | ### Terminal and POS types | Type | Description | |---|---| | `Terminal` | A Paystack Terminal (POS) device. | | `Outlet` | A physical merchant outlet associated with a terminal. | ### Integration and miscellaneous types | Type | Description | |---|---| | `Integration` | Integration-level settings such as the payment session timeout. | | `PaymentChannel` | An enumeration of Paystack payment channels (card, bank, ussd, qr, mobile_money, bank_transfer, eft, apple_pay). | | `Currency` | An enumeration of supported currencies (NGN, GHS, ZAR, KES, XOF, EGP, USD). | | `TransactionStatus` | An enumeration of transaction statuses. | | `TransferStatus` | An enumeration of transfer statuses. | | `DisputeStatus` | An enumeration of dispute statuses. | | `RiskAction` | An enumeration of customer risk actions (allow, deny, default). | | `RecipientType` | An enumeration of transfer recipient types (nuban, mobile_money, basa, authorization). | | `SplitType` | An enumeration of split types (percentage, flat). | | `SubscriptionStatus` | An enumeration of subscription statuses. | | `PlanInterval` | An enumeration of billing plan intervals. | | `Metadata` | A generic key-value metadata map attached to many types. | --- ## Query operations | Operation | Description | |---|---| | `transaction(id: ID!)` | Fetch a single transaction by ID. | | `transactions(perPage: Int, page: Int, customer: ID, status: TransactionStatus, from: String, to: String, amount: Int)` | List transactions with filtering. | | `transactionTotals(from: String, to: String)` | Aggregate totals for transactions in a date range. | | `customer(emailOrCode: String!)` | Fetch a customer by email or customer code. | | `customers(perPage: Int, page: Int, from: String, to: String)` | List customers. | | `plan(idOrCode: String!)` | Fetch a plan by ID or plan code. | | `plans(perPage: Int, page: Int, interval: PlanInterval, amount: Int)` | List plans. | | `subscription(idOrToken: String!)` | Fetch a subscription by ID or subscription code. | | `subscriptions(perPage: Int, page: Int, customer: ID, plan: ID)` | List subscriptions. | | `subaccount(idOrCode: String!)` | Fetch a subaccount. | | `subaccounts(perPage: Int, page: Int, from: String, to: String)` | List subaccounts. | | `split(id: ID!)` | Fetch a transaction split. | | `splits(perPage: Int, page: Int, name: String, active: Boolean, sortBy: String)` | List splits. | | `transfer(idOrCode: String!)` | Fetch a transfer by ID or code. | | `transfers(perPage: Int, page: Int, customer: ID, from: String, to: String)` | List transfers. | | `transferRecipient(idOrCode: String!)` | Fetch a transfer recipient. | | `transferRecipients(perPage: Int, page: Int, from: String, to: String)` | List transfer recipients. | | `balance` | Fetch current balance(s). | | `balanceLedger(perPage: Int, page: Int, from: String, to: String)` | List balance ledger entries. | | `settlement(id: ID!)` | Fetch a settlement. | | `settlements(perPage: Int, page: Int, from: String, to: String, subaccount: String)` | List settlements. | | `settlementTransactions(id: ID!, perPage: Int, page: Int, from: String, to: String)` | List transactions in a settlement. | | `dispute(id: ID!)` | Fetch a dispute. | | `disputes(perPage: Int, page: Int, from: String, to: String, transaction: ID, status: DisputeStatus)` | List disputes. | | `refund(reference: String!)` | Fetch a refund. | | `refunds(perPage: Int, page: Int, reference: String, currency: Currency, from: String, to: String, transaction: ID)` | List refunds. | | `product(id: ID!)` | Fetch a product. | | `products(perPage: Int, page: Int)` | List products. | | `paymentPage(idOrSlug: String!)` | Fetch a payment page. | | `paymentPages(perPage: Int, page: Int)` | List payment pages. | | `paymentRequest(idOrCode: String!)` | Fetch a payment request. | | `paymentRequests(perPage: Int, page: Int, customer: ID, status: String, currency: Currency, from: String, to: String)` | List payment requests. | | `dedicatedAccount(id: ID!)` | Fetch a dedicated virtual account. | | `dedicatedAccounts(active: Boolean, currency: Currency, providerSlug: String, bankId: String, customer: ID)` | List dedicated accounts. | | `banks(country: String!, useCursor: Boolean, perPage: Int, next: String, previous: String, gateway: String, type: String, currency: Currency)` | List supported banks. | | `countries` | List supported countries. | | `verifyAccountNumber(accountNumber: String!, bankCode: String!)` | Resolve a bank account number. | | `cardBin(bin: String!)` | Look up a card BIN. | | `bulkCharge(idOrCode: String!)` | Fetch a bulk charge batch. | | `bulkCharges(perPage: Int, page: Int, from: String, to: String)` | List bulk charge batches. | | `terminal(terminalId: String!)` | Fetch a terminal. | | `terminals(perPage: Int, next: String, previous: String)` | List terminals. | | `integration` | Fetch integration settings. | --- ## Mutation operations | Operation | Description | |---|---| | `initializeTransaction(email: String!, amount: Int!, ...)` | Initialize a hosted checkout transaction and return an authorization URL. | | `chargeAuthorization(email: String!, amount: Int!, authorizationCode: String!, ...)` | Charge a stored authorization. | | `createCharge(email: String!, amount: Int!, ...)` | Create a direct charge. | | `submitPin(pin: String!, reference: String!)` | Submit PIN for a pending charge. | | `submitOtp(otp: String!, reference: String!)` | Submit OTP for a pending charge. | | `submitPhone(phone: String!, reference: String!)` | Submit phone for a pending charge. | | `submitBirthday(birthday: String!, reference: String!)` | Submit birthday for a pending charge. | | `submitAddress(address: String!, city: String!, state: String!, zipcode: String!, reference: String!)` | Submit address for a pending charge. | | `createRefund(transaction: String!, amount: Int, currency: Currency, customerNote: String, merchantNote: String)` | Create a refund. | | `createCustomer(email: String!, firstName: String, lastName: String, phone: String, metadata: String)` | Create a customer. | | `updateCustomer(code: String!, firstName: String, lastName: String, phone: String, metadata: String)` | Update a customer. | | `validateCustomer(customerCode: String!, country: String!, type: String!, value: String!, firstName: String!, lastName: String!, value2: String)` | Run KYC validation on a customer. | | `setRiskAction(customer: String!, riskAction: RiskAction!)` | Set risk action on a customer. | | `deactivateAuthorization(authorizationCode: String!)` | Deactivate a stored authorization. | | `createPlan(name: String!, interval: PlanInterval!, amount: Int!, ...)` | Create a billing plan. | | `updatePlan(idOrCode: String!, name: String, interval: PlanInterval, amount: Int, ...)` | Update a billing plan. | | `createSubscription(customer: String!, plan: String!, authorization: String, startDate: String)` | Create a subscription. | | `enableSubscription(code: String!, token: String!)` | Enable a disabled subscription. | | `disableSubscription(code: String!, token: String!)` | Disable a subscription. | | `generateSubscriptionLink(code: String!)` | Generate a self-service management link for a subscription. | | `sendSubscriptionLink(code: String!)` | Email the management link to the subscriber. | | `createSubaccount(businessName: String!, settlementBank: String!, accountNumber: String!, percentageCharge: Float!, ...)` | Create a subaccount. | | `updateSubaccount(idOrCode: String!, businessName: String, settlementBank: String, accountNumber: String, percentageCharge: Float, ...)` | Update a subaccount. | | `createSplit(name: String!, type: SplitType!, currency: Currency!, subaccounts: [SplitSubaccountInput!]!, bearerType: String!, bearerSubaccount: String!)` | Create a transaction split. | | `updateSplit(id: ID!, name: String, active: Boolean, bearerType: String, bearerSubaccount: String)` | Update a transaction split. | | `addSplitSubaccount(id: ID!, subaccount: String!, share: Float!)` | Add or update a subaccount on a split. | | `removeSplitSubaccount(id: ID!, subaccount: String!)` | Remove a subaccount from a split. | | `createTransferRecipient(type: RecipientType!, name: String!, accountNumber: String!, bankCode: String, currency: Currency, ...)` | Create a transfer recipient. | | `updateTransferRecipient(idOrCode: String!, name: String!, email: String)` | Update a transfer recipient. | | `deleteTransferRecipient(idOrCode: String!)` | Delete a transfer recipient. | | `initiateTransfer(source: String!, amount: Int!, recipient: String!, ...)` | Initiate a transfer. | | `finalizeTransfer(transferCode: String!, otp: String!)` | Finalize a transfer with OTP. | | `bulkTransfer(source: String!, transfers: [BulkTransferItemInput!]!)` | Initiate a bulk transfer. | | `createProduct(name: String!, description: String!, price: Int!, currency: Currency!, ...)` | Create a product. | | `updateProduct(id: ID!, name: String, description: String, price: Int, currency: Currency, ...)` | Update a product. | | `createPaymentPage(name: String!, ...)` | Create a payment page. | | `updatePaymentPage(idOrSlug: String!, name: String, description: String, amount: Int, active: Boolean)` | Update a payment page. | | `addProductsToPage(id: ID!, products: [Int!]!)` | Add products to a payment page. | | `createPaymentRequest(customer: String!, amount: Int!, ...)` | Create a payment request. | | `sendPaymentRequestNotification(idOrCode: String!)` | Send or resend a payment request notification. | | `finalizePaymentRequest(idOrCode: String!)` | Finalize a draft payment request. | | `archivePaymentRequest(idOrCode: String!)` | Archive a payment request. | | `createDedicatedAccount(customer: String!, preferredBank: String, subaccount: String, splitCode: String, firstName: String, lastName: String, phone: String)` | Create a dedicated virtual account. | | `assignDedicatedAccount(email: String!, firstName: String!, lastName: String!, phone: String!, preferredBank: String!, country: String!)` | Assign a dedicated account to a customer. | | `splitDedicatedAccount(customer: String!, subaccount: String, splitCode: String, preferredBank: String)` | Set split on a dedicated account. | | `removeSplitFromDedicatedAccount(account: String!)` | Remove a split from a dedicated account. | | `deactivateDedicatedAccount(dedicatedAccountId: Int!)` | Deactivate a dedicated account. | | `initiateBulkCharge(objects: [BulkChargeItemInput!]!)` | Initiate a bulk charge batch. | | `pauseBulkCharge(batchCode: String!)` | Pause a bulk charge batch. | | `resumeBulkCharge(batchCode: String!)` | Resume a bulk charge batch. | | `resolveDispute(id: ID!, resolution: String!)` | Resolve a dispute. | | `addDisputeEvidence(id: ID!, customerEmail: String!, customerName: String!, customerPhone: String, serviceDetails: String!, deliveryAddress: String, deliveryDate: String)` | Add evidence to a dispute. | | `getDisputeUploadUrl(id: ID!)` | Get a signed URL for uploading dispute evidence files. | | `exportDisputes(from: String!, to: String!, transaction: ID, status: DisputeStatus)` | Export disputes to a CSV download URL. | | `sendEvent(terminalId: String!, type: String!, action: String!, data: String!)` | Send an event to a terminal. | | `updateTerminal(terminalId: String!, name: String!, address: String!)` | Update a terminal. | | `commissionTerminal(serialNumber: String!)` | Commission a new terminal. | | `decommissionTerminal(terminalId: String!)` | Decommission a terminal. | | `updateIntegration(sessionTimeout: Int!)` | Update integration settings. | --- ## Notes on design - All monetary amounts follow Paystack convention: integers in the lowest currency denomination (kobo for NGN, pesewas for GHS, cents for ZAR/USD, etc.). - `metadata` fields are represented as JSON scalars (`String` in this schema) matching Paystack's free-form metadata object. - Pagination follows Paystack's cursor-less offset pagination (`page` + `perPage`) with cursor extensions for bank listings. - Enumerations map directly to Paystack's accepted string values. - This schema does not represent webhooks/events — see the AsyncAPI artifact for the event surface.