# Bumxpress Business documentation for LLMs This file is a consolidated plain-text copy of the Bumxpress Business developer documentation. Use it to answer implementation questions about authentication, customers, KYC, quotes, payins, payouts, transfers, webhooks, environments, errors, coverage, and the OpenAPI reference. Canonical documentation: https://docs.bumxpress.com Merchant dashboard: https://portal.bumxpress.com Production API base URL: https://api.business.bumxpress.com ## Navigation - Guides / Getting started / Welcome to Bumxpress Business: /index - Guides / Getting started / What Bumxpress Business does: /guides/what-is-bumxpress-business - Guides / Getting started / How payments work: /guides/how-payments-work - Guides / Getting started / Quickstart: /quickstart - Guides / Getting started / Environments: /guides/environments - Guides / Getting started / Authentication: /guides/authentication - Guides / Core concepts / Customers and KYC: /guides/customers-and-kyc - Guides / Core concepts / Quotes: /guides/quotes - Guides / Core concepts / Payins: /guides/payins - Guides / Core concepts / Payouts: /guides/payouts - Guides / Core concepts / Transfers: /guides/transfers - Guides / Practical flows / Mobile money payin: /guides/mobile-money-payin - Guides / Practical flows / Mobile money payout: /guides/mobile-money-payout - Guides / Practical flows / Cross-border transfer: /guides/cross-border-transfer - Guides / Supporting documentation / Coverage: /guides/coverage-map - Guides / Supporting documentation / Idempotency: /guides/idempotency - Guides / Supporting documentation / Errors: /guides/errors - Guides / Supporting documentation / Webhooks: /guides/webhooks - Guides / Operate / Go-live checklist: /guides/go-live-checklist - Guides / Operate / Changelog: /guides/changelog - API Reference / Customers / Create customer: /api-reference/customers/create-customer - API Reference / Customers / Get customer: /api-reference/customers/get-customer - API Reference / Customer KYC / Submit KYC documents: /api-reference/customer-kyc/submit-kyc-documents - API Reference / Customer KYC / Get customer KYC status: /api-reference/customer-kyc/get-customer-kyc-status - API Reference / Quotes / Create payin quote: /api-reference/quotes/create-payin-quote - API Reference / Quotes / Create payout quote: /api-reference/quotes/create-payout-quote - API Reference / Quotes / Create transfer quote: /api-reference/quotes/create-transfer-quote - API Reference / Quotes / Get quote: /api-reference/quotes/get-quote - API Reference / Payins / Create payin: /api-reference/payins/create-payin - API Reference / Payins / Get payin: /api-reference/payins/get-payin - API Reference / Payouts / Create payout: /api-reference/payouts/create-payout - API Reference / Payouts / Get payout: /api-reference/payouts/get-payout - API Reference / Transfers / Create transfer: /api-reference/transfers/create-transfer - API Reference / Transfers / Get transfer: /api-reference/transfers/get-transfer - API Reference / Transfers / Relaunch transfer payout: /api-reference/transfers/relaunch-transfer-payout --- # Welcome to Bumxpress Business Source: /index Section: Guides / Getting started --- title: "Welcome to Bumxpress Business" description: "Integrate collections, payouts, transfers, customers, KYC, and webhooks with the Bumxpress Business merchant API." --- Bumxpress Business lets merchants collect and disburse money through mobile money and other payment rails across supported African markets. Use these docs to create customers, generate quotes, initiate payins and payouts, launch transfers, and receive asynchronous webhook updates. Create your first authenticated merchant API request. Learn how `X-Api-Key` and `X-Api-Secret` protect merchant endpoints. Review supported countries, currencies, mobile money operators, and corridors. Browse the OpenAPI-generated merchant API reference. ## Core concepts - Quotes lock pricing for 15 minutes. - Payins, payouts, and transfers are asynchronous. - Write requests use `Idempotency-Key` for safe retries. - Merchant resources are scoped to the API key that creates or accesses them. - Final payment status should be read from webhooks or follow-up `GET` requests. --- # What Bumxpress Business does Source: /guides/what-is-bumxpress-business Section: Guides / Getting started --- title: "What Bumxpress Business does" description: "Understand the merchant payment platform before integrating the API." --- Bumxpress Business gives merchants API access to payment collection, disbursement, transfer, customer, KYC, and webhook workflows. The merchant API is designed for server-side integrations. Your backend creates customers, requests quotes, initiates money movement, stores returned resource IDs, and reconciles final status through webhooks or follow-up `GET` requests. ## What you can build Create quote-backed payins from supported customer payment rails. Disburse funds to recipients through supported local rails. Collect from a payer and disburse to a recipient in a two-leg flow. Receive asynchronous events as payment resources change state. ## Main resources | Resource | Purpose | | --- | --- | | Customer | The person or entity associated with a payment flow. | | KYC | Customer identity and compliance information. | | Quote | A short-lived pricing and routing lock for money movement. | | Payin | A collection from a payer. | | Payout | A disbursement to a recipient. | | Transfer | A two-leg collect-and-disburse flow. | | Webhook | An asynchronous event delivered to your integration. | ## Integration model Create requests return resource identifiers. Store those IDs in your own system and use them for reconciliation, customer support, retries, and webhook handling. --- # How payments work Source: /guides/how-payments-work Section: Guides / Getting started --- title: "How payments work" description: "Learn the quote-backed asynchronous payment model used by Bumxpress Business." --- Bumxpress Business payment flows are quote-backed and asynchronous. You first create a quote to lock pricing, routing, fees, FX, and amounts. Then you create the payment resource with that active quote. The create response usually returns a pending status, while the final status arrives later through webhooks or a `GET` endpoint. ## Single-leg payin or payout ```mermaid sequenceDiagram participant Merchant participant BumxpressAPI participant Provider participant CustomerPhone Merchant->>BumxpressAPI: POST /customers Merchant->>BumxpressAPI: POST /quotes/payin or /quotes/payout Merchant->>BumxpressAPI: POST /payins or /payouts BumxpressAPI-->>Merchant: 201 pending BumxpressAPI->>Provider: Async submission Provider->>CustomerPhone: Prompt or rail action Provider-->>BumxpressAPI: Status callback BumxpressAPI-->>Merchant: Webhook event ``` ## Two-leg transfer Transfers collect from a payer first and then disburse to a recipient. Use transfer quotes for cross-border or local two-leg flows where both legs must be tracked together. ## Important behaviors - Quotes are valid for 15 minutes. - Payins, payouts, and transfers are asynchronous. - Final status should be reconciled through webhooks or `GET` endpoints. - Write requests require `Idempotency-Key` unless the endpoint documentation says otherwise. - Operator and corridor availability depends on your merchant account routing. --- # Quickstart Source: /quickstart Section: Guides / Getting started --- title: "Quickstart" description: "Make your first authenticated request to the Bumxpress Business merchant API." --- ## Base URL ```text https://api.business.bumxpress.com ``` All merchant API requests and responses use JSON. ## Prerequisites - A Bumxpress Business merchant account - A merchant API key and secret from the dashboard - A unique `Idempotency-Key` for each create request Copy your API secret when it is created. The dashboard shows it once and cannot display it again later. ## Make a request Open the merchant dashboard and create an API key. You will use the public key as `X-Api-Key` and the secret as `X-Api-Secret`. ```bash curl -X POST "https://api.business.bumxpress.com/customers" \ -H "Content-Type: application/json" \ -H "X-Api-Key: bmx_pk_xxx" \ -H "X-Api-Secret: bmx_sk_xxx" \ -H "Idempotency-Key: customer_001" \ -d '{ "first_name": "Amina", "last_name": "Ndongo", "phone": "+237670000000", "country_code": "CM" }' ``` Generate a payin, payout, or transfer quote before initiating money movement. ```bash curl -X POST "https://api.business.bumxpress.com/quotes/payin" \ -H "Content-Type: application/json" \ -H "X-Api-Key: bmx_pk_xxx" \ -H "X-Api-Secret: bmx_sk_xxx" \ -H "Idempotency-Key: quote_payin_001" \ -d '{ "country_code": "CM", "operator_code": "CM_MTN_MOMO", "rail_type": "mobile_money", "send_amount": "10000", "send_currency": "XAF" }' ``` Use the quote ID from the quote response when creating a payin, payout, or transfer. ## Next steps Send the required merchant API headers. Walk through a complete mobile money collection. --- # Environments Source: /guides/environments Section: Guides / Getting started --- title: "Environments" description: "Use the correct Bumxpress Business API base URL and request conventions." --- ## Production ```text https://api.business.bumxpress.com ``` ## Conventions | Convention | Value | | --- | --- | | Request body | JSON with `Content-Type: application/json` | | Response body | JSON | | Amounts | Decimal strings, for example `"10000"` or `"25.00"` | | Country codes | ISO 3166-1 alpha-2, for example `CM`, `SN`, `CI` | | Currency codes | ISO 4217, for example `XAF`, `XOF`, `USD`, `UGX` | | Phone numbers | E.164 recommended, for example `+237670000000` | | Rail type | `mobile_money` or `bank_transfer` | Operator and corridor availability can vary by merchant account. The coverage map lists platform-supported values; your account may support a subset. --- # Authentication Source: /guides/authentication Section: Guides / Getting started --- title: "Authentication" description: "Authenticate merchant API requests with your API key and secret." --- All protected merchant endpoints require two headers: ```http X-Api-Key: bmx_pk_xxx X-Api-Secret: bmx_sk_xxx ``` | Header | Description | | --- | --- | | `X-Api-Key` | Public key that identifies the merchant API credential. | | `X-Api-Secret` | Secret shown once when the key is created in the merchant dashboard. | If authentication fails, the API returns `401 Unauthorized`. ## Credential handling - Create API keys in the merchant dashboard. - Store `X-Api-Secret` in a secret manager. - Never expose API secrets in mobile apps, browsers, logs, or public repositories. - Rotate or revoke credentials from the dashboard if a secret is exposed. ## Example ```http GET /customers/22222222-2222-2222-2222-222222222222 X-Api-Key: bmx_pk_xxx X-Api-Secret: bmx_sk_xxx ``` Merchant resources are scoped to the merchant attached to the API key. A key cannot access another merchant's customers, quotes, payments, transfers, or webhook configuration. --- # Customers and KYC Source: /guides/customers-and-kyc Section: Guides / Core concepts --- title: "Customers and KYC" description: "Create customer records and submit identity documents when payment providers or corridors require KYC." --- Customers represent the people or businesses that send or receive money through your integration. Create customers before payment flows so each quote, payin, payout, transfer, and webhook can be reconciled back to your internal records. Use `external_ref` to store your own customer identifier. ## Customer types | Type | Use case | Required identity fields | | --- | --- | --- | | `individual` | A person sending or receiving money. | `first_name`, `last_name` | | `retail` | A person identified mainly by document number. | `first_name`, `last_name`, `id_number` | | `business` | A business customer. | `business_name` | ## Recommended customer fields Provider requirements vary by country, operator, and corridor. For payout and transfer flows, collect the fullest profile you can: - Name or business name - Phone number in E.164 format - Email address - Country and nationality codes - Date of birth - Address and city - Occupation and source of funds For Yellow Card-backed payouts, make sure the customer profile includes `address_line1`, `city`, `occupation`, and `source_of_funds`. ## KYC documents Submit KYC documents through `POST /customers/{customer_id}/kyc`. Document files must be hosted at public HTTPS URLs that Bumxpress can fetch. Supported document examples include `national_id` and `passport`. At least one file URL is required per document, such as `front_file_url`, `back_file_url`, or `selfie_file_url`. ## Status tracking Read KYC state with `GET /customers/{customer_id}/kyc`. Store the returned `kyc_status` and document IDs in your system so support and compliance teams can reconcile provider requirements. --- # Quotes Source: /guides/quotes Section: Guides / Core concepts --- title: "Quotes" description: "Create quotes before initiating payins, payouts, or transfers." --- Quotes lock fees, FX, provider routing, and amounts for 15 minutes. Create a fresh quote before every payin, payout, or transfer. ## Quote types | Endpoint | Use case | | --- | --- | | `POST /quotes/payin` | Collect money from a customer. | | `POST /quotes/payout` | Send money to a recipient. | | `POST /quotes/transfer` | Collect from a payer and disburse to a recipient. | | `GET /quotes/{quote_id}` | Read an existing quote. | ## Payin quote example ```json { "country_code": "CM", "operator_code": "CM_MTN_MOMO", "rail_type": "mobile_money", "send_amount": "10000", "send_currency": "XAF" } ``` ## Statuses | Status | Meaning | | --- | --- | | `active` | The quote can be used to create a payin, payout, or transfer. | | `expired` | The quote is past `expires_at`; create a new quote. | --- # Payins Source: /guides/payins Section: Guides / Core concepts --- title: "Payins" description: "Collect money from customers with a quote-backed payin." --- Payins are asynchronous. `POST /payins` returns quickly with a pending resource. Poll `GET /payins/{payin_id}` or wait for a webhook to receive the final status. ## Flow Create a customer before initiating the collection. Use `POST /quotes/payin` with the country, operator, rail type, amount, and currency. Use the active `quote_id` and source details such as phone and operator. Receive the final status by webhook or `GET /payins/{payin_id}`. ## Mobile money source ```json { "quote_id": "33333333-3333-3333-3333-333333333333", "customer_id": "22222222-2222-2222-2222-222222222222", "source": { "country_code": "CM", "rail_type": "mobile_money", "phone": "+237670000000", "operator_code": "CM_MTN_MOMO" } } ``` --- # Payouts Source: /guides/payouts Section: Guides / Core concepts --- title: "Payouts" description: "Send money to recipients with quote-backed payouts." --- Payouts are asynchronous. `POST /payouts` creates the payout and returns a pending resource. Poll `GET /payouts/{payout_id}` or wait for a webhook to receive the final status. ## Flow Use `POST /quotes/payout` to lock pricing and routing. Use the active `quote_id` and recipient details. Store the payout ID and wait for the webhook or poll the payout endpoint. ## Mobile money recipient ```json { "quote_id": "33333333-3333-3333-3333-333333333333", "customer_id": "22222222-2222-2222-2222-222222222222", "payment_reason_text": "Merchant payout", "recipient": { "country_code": "CM", "rail_type": "mobile_money", "phone": "+237670000000", "operator_code": "CM_MTN_MOMO" } } ``` --- # Transfers Source: /guides/transfers Section: Guides / Core concepts --- title: "Transfers" description: "Collect from a payer and disburse to a recipient in a two-leg transfer flow." --- Transfers are two-legged. Bumxpress first collects from the payer, then disburses to the recipient. ## Flow Use `POST /quotes/transfer` with the source and destination operators, amount, and currencies. Submit payer and recipient details with the active transfer quote. Read transfer status from webhooks or `GET /transfers/{transfer_id}`. ## Quote fields | Field | Required | Description | | --- | --- | --- | | `payer_operator_code` | Yes | Source-side operator for collection. | | `recipient_operator_code` | Yes | Destination-side operator for disbursement. | | `payin_amount` | Yes, unless quoting fixed payout | Amount collected from payer. | | `payin_currency` | Yes | Source-side currency. | | `payout_currency` | Yes | Destination-side currency. | | `payout_amount` | No | Optional fixed payout amount. | Your merchant account must have an active transfer corridor configured before transfer quotes succeed. --- # Mobile money payin Source: /guides/mobile-money-payin Section: Guides / Practical flows --- title: "Mobile money payin" description: "Collect a mobile money payment from a customer." --- Use this recipe when a customer pays your business from a mobile money wallet. ```bash curl -X POST "https://api.business.bumxpress.com/customers" \ -H "Content-Type: application/json" \ -H "X-Api-Key: bmx_pk_xxx" \ -H "X-Api-Secret: bmx_sk_xxx" \ -H "Idempotency-Key: customer_001" \ -d '{"first_name":"Amina","last_name":"Ndongo","phone":"+237670000000","country_code":"CM"}' ``` ```bash curl -X POST "https://api.business.bumxpress.com/quotes/payin" \ -H "Content-Type: application/json" \ -H "X-Api-Key: bmx_pk_xxx" \ -H "X-Api-Secret: bmx_sk_xxx" \ -H "Idempotency-Key: quote_payin_001" \ -d '{"country_code":"CM","operator_code":"CM_MTN_MOMO","rail_type":"mobile_money","send_amount":"10000","send_currency":"XAF"}' ``` ```bash curl -X POST "https://api.business.bumxpress.com/payins" \ -H "Content-Type: application/json" \ -H "X-Api-Key: bmx_pk_xxx" \ -H "X-Api-Secret: bmx_sk_xxx" \ -H "Idempotency-Key: payin_001" \ -d '{ "quote_id": "33333333-3333-3333-3333-333333333333", "customer_id": "22222222-2222-2222-2222-222222222222", "source": { "country_code": "CM", "rail_type": "mobile_money", "phone": "+237670000000", "operator_code": "CM_MTN_MOMO" } }' ``` --- # Mobile money payout Source: /guides/mobile-money-payout Section: Guides / Practical flows --- title: "Mobile money payout" description: "Send money to a recipient's mobile money wallet." --- Use this recipe when your business pays out to a recipient through mobile money. ```bash curl -X POST "https://api.business.bumxpress.com/quotes/payout" \ -H "Content-Type: application/json" \ -H "X-Api-Key: bmx_pk_xxx" \ -H "X-Api-Secret: bmx_sk_xxx" \ -H "Idempotency-Key: quote_payout_001" \ -d '{"country_code":"CM","operator_code":"CM_MTN_MOMO","rail_type":"mobile_money","send_amount":"25.00","send_currency":"USD"}' ``` ```bash curl -X POST "https://api.business.bumxpress.com/payouts" \ -H "Content-Type: application/json" \ -H "X-Api-Key: bmx_pk_xxx" \ -H "X-Api-Secret: bmx_sk_xxx" \ -H "Idempotency-Key: payout_001" \ -d '{ "quote_id": "33333333-3333-3333-3333-333333333333", "customer_id": "22222222-2222-2222-2222-222222222222", "payment_reason_text": "Merchant payout", "recipient": { "country_code": "CM", "rail_type": "mobile_money", "phone": "+237670000000", "operator_code": "CM_MTN_MOMO" } }' ``` --- # Cross-border transfer Source: /guides/cross-border-transfer Section: Guides / Practical flows --- title: "Cross-border transfer" description: "Collect from a payer and disburse to a recipient in another supported market." --- Use transfers for two-leg flows where Bumxpress collects from a payer and disburses to a recipient. ```bash curl -X POST "https://api.business.bumxpress.com/quotes/transfer" \ -H "Content-Type: application/json" \ -H "X-Api-Key: bmx_pk_xxx" \ -H "X-Api-Secret: bmx_sk_xxx" \ -H "Idempotency-Key: quote_transfer_001" \ -d '{ "payer_operator_code": "CM_MTN_MOMO", "recipient_operator_code": "CI_ORANGE_MOMO", "payin_amount": "100000", "payin_currency": "XAF", "payout_currency": "XOF" }' ``` Submit the active quote ID with payer and recipient details. Store the transfer ID and listen for webhook updates. --- # Coverage Source: /guides/coverage-map Section: Guides / Supporting documentation --- title: "Coverage" description: "Supported mobile money countries and operator codes for Bumxpress Business merchant integrations." --- Use this page to choose the correct `country_code`, `currency`, `rail_type`, and `operator_code` when creating quotes, payins, payouts, and transfers. Platform coverage can differ from the operators enabled on your merchant account. Confirm your account routing before going live. ## Supported countries | Country | `country_code` | Region | Currency | | --- | --- | --- | --- | | Cameroon | `CM` | Central Africa | `XAF` | | Senegal | `SN` | West Africa | `XOF` | | Benin | `BJ` | West Africa | `XOF` | | Togo | `TG` | West Africa | `XOF` | | Cote d'Ivoire | `CI` | West Africa | `XOF` | ## Mobile money operators All operators listed here use: | Field | Value | | --- | --- | | `rail_type` | `mobile_money` | | Amount format | Decimal string, for example `"10000"` | | Country format | ISO 3166-1 alpha-2 | | Currency format | ISO 4217 | XAF mobile money operators. XOF mobile money operators. XOF mobile money operators. XOF mobile money operators. XOF mobile money operators. ### Cameroon | Operator | Display name | `operator_code` | Currency | | --- | --- | --- | --- | | MTN Cameroon | MTN Mobile Money | `CM_MTN_MOMO` | `XAF` | | Orange Cameroon | Orange Money | `CM_ORANGE_MOMO` | `XAF` | ### Senegal | Operator | Display name | `operator_code` | Currency | | --- | --- | --- | --- | | Orange Senegal | Orange Money | `SN_ORANGE_MOMO` | `XOF` | | Free Money Senegal | Free Money | `SN_FREE_MOMO` | `XOF` | | Expresso Senegal | Expresso Money | `SN_EXPRESSO_MOMO` | `XOF` | ### Benin | Operator | Display name | `operator_code` | Currency | | --- | --- | --- | --- | | MTN Benin | MTN Mobile Money | `BJ_MTN_MOMO` | `XOF` | | Moov Benin | Moov Money | `BJ_MOOV_MOMO` | `XOF` | ### Togo | Operator | Display name | `operator_code` | Currency | | --- | --- | --- | --- | | T Money Togo | T Money | `TG_T_MONEY_MOMO` | `XOF` | ### Cote d'Ivoire | Operator | Display name | `operator_code` | Currency | | --- | --- | --- | --- | | MTN Cote d'Ivoire | MTN MoMo | `CI_MTN_MOMO` | `XOF` | | Orange Cote d'Ivoire | Orange Money | `CI_ORANGE_MOMO` | `XOF` | | Moov Cote d'Ivoire | Moov Money | `CI_MOOV_MOMO` | `XOF` | | Wave Cote d'Ivoire | Wave Mobile Money | `CI_WAVE_MOMO` | `XOF` | ## Usage Quote and payment requests must use matching country, currency, rail, and operator values. ```json { "country_code": "CM", "operator_code": "CM_MTN_MOMO", "rail_type": "mobile_money", "send_amount": "10000", "send_currency": "XAF" } ``` For transfer quotes, use source and destination operator codes: ```json { "corridor_code": "CM-CI-XAF-XOF", "payer_operator_code": "CM_MTN_MOMO", "recipient_operator_code": "CI_ORANGE_MOMO", "payin_amount": "100000", "payin_currency": "XAF", "payout_currency": "XOF" } ``` --- # Idempotency Source: /guides/idempotency Section: Guides / Supporting documentation --- title: "Idempotency" description: "Retry create requests safely with Idempotency-Key." --- Write endpoints that create customers, quotes, payins, payouts, transfers, or transfer relaunches require an `Idempotency-Key` header. ```http Idempotency-Key: payin_2026_06_08_0001 ``` ## Required endpoints | Endpoint | Purpose | | --- | --- | | `POST /customers` | Create customer | | `POST /quotes/payin` | Create payin quote | | `POST /quotes/payout` | Create payout quote | | `POST /quotes/transfer` | Create transfer quote | | `POST /payins` | Create payin | | `POST /payouts` | Create payout | | `POST /transfers` | Create transfer | | `POST /transfers/{id}/relaunch-payout` | Relaunch failed transfer disbursement | ## Rules - Use a unique key for each distinct business intent. - Reuse the same key only when retrying the exact same request body after a timeout or network error. - Use a new key when creating a new payment, quote, customer, or transfer. When a request is replayed successfully, the API marks the response metadata: ```json { "_meta": { "idempotency_key": "payin_2026_06_08_0001", "idempotency_replayed": true } } ``` --- # Errors Source: /guides/errors Section: Guides / Supporting documentation --- title: "Errors" description: "Understand the standard merchant API error shape and common HTTP statuses." --- Merchant API errors use a consistent JSON shape: ```json { "error": { "code": "bad_request", "message": "quote_id is required" } } ``` ## HTTP statuses | Status | Meaning | | --- | --- | | `400` | Invalid body, missing field, expired quote, quote mismatch, or insufficient balance. | | `401` | Missing, invalid, expired, or inactive API credentials. | | `404` | Resource not found for the authenticated merchant. | | `409` | Idempotency conflict or a request with the same key is still processing. | ## Handling recommendations - Show actionable validation errors to your operators or support team. - Retry network failures with the same `Idempotency-Key` only when the business intent and request body are unchanged. - Do not retry authentication errors until credentials have been fixed. - Store error responses with your internal payment record for reconciliation and support. --- # Webhooks Source: /guides/webhooks Section: Guides / Supporting documentation --- title: "Webhooks" description: "Receive signed event callbacks when payins, payouts, or transfers change status." --- Webhooks let Bumxpress push status changes to your backend instead of relying only on polling `GET` endpoints. Use them to update your internal records when payins, payouts, or transfers complete or fail. ## Configure your webhook In the merchant dashboard you configure: - **URL**: HTTPS endpoint on your backend, for example `https://api.yourapp.com/webhooks/bumxpress` - **Signing secret**: Shared secret used to verify signatures All webhook requests use: ```http POST /webhooks/bumxpress Content-Type: application/json X-Bumxpress-Signature: sha256= X-Bumxpress-Timestamp: 1779705120 X-Bumxpress-Event: payout.completed X-Bumxpress-Webhook-Id: 88888888-8888-8888-8888-888888888888 ``` ## Verify the signature Signatures use an HMAC over the timestamp and raw request body: ```text sha256=HMAC_SHA256(webhook_secret, timestamp + "." + raw_request_body) ``` Verify signatures **before** parsing JSON or applying side effects. ```ts import crypto from "node:crypto"; export function verifyBumxpressWebhook({ secret, timestamp, rawBody, signature, }: { secret: string; timestamp: string; rawBody: string; signature: string; }) { const expected = "sha256=" + crypto .createHmac("sha256", secret) .update(`${timestamp}.${rawBody}`) .digest("hex"); const expectedBuffer = Buffer.from(expected); const signatureBuffer = Buffer.from(signature); return ( expectedBuffer.length === signatureBuffer.length && crypto.timingSafeEqual(expectedBuffer, signatureBuffer) ); } ``` Always verify `X-Bumxpress-Signature` using the raw request body. Reject requests when verification fails. ## Event types Bumxpress emits a small set of payment events. Use the `event` and `data.type` fields to route handling logic. ```json { "id": "88888888-8888-8888-8888-888888888888", "event": "payin.completed", "created_at": "2026-06-08T10:40:00Z", "data": { "type": "payin", "id": "44444444-4444-4444-4444-444444444444", "object": { } } } ``` Supported events: - **payin.completed** / **payin.failed** (`data.type: "payin"`) - **payout.completed** / **payout.failed** (`data.type: "payout"`) - **transfer.payin.completed** / **transfer.payin.failed** (`data.type: "transfer"`) - **transfer.payout.completed** / **transfer.payout.failed** (`data.type: "transfer"`) - **transfer.completed** / **transfer.failed** (`data.type: "transfer"`) Transfer leg events are sent as each leg reaches a terminal state. Aggregate transfer events are still sent when the full transfer reaches a final state. The `data.object` field contains a snapshot of the resource at event time, including amounts, status, operator, wallet impact, and timestamps. ## Example payloads **Payin webhook** ```json { "id": "88888888-8888-8888-8888-888888888888", "event": "payin.completed", "created_at": "2026-06-08T10:40:00Z", "data": { "type": "payin", "id": "44444444-4444-4444-4444-444444444444", "object": { "id": "44444444-4444-4444-4444-444444444444", "status": "completed", "send_amount": "10000", "send_currency": "XAF", "receive_amount": "16", "receive_currency": "USD", "country_code": "CM", "operator_code": "CM_MTN_MOMO", "rail_type": "mobile_money", "wallet_impact": { "credit_amount": "16.00", "currency": "USD" }, "completed_at": "2026-06-08T10:39:30Z" } } } ``` **Payout webhook** ```json { "id": "99999999-9999-9999-9999-999999999999", "event": "payout.completed", "created_at": "2026-06-08T10:42:00Z", "data": { "type": "payout", "id": "66666666-6666-6666-6666-666666666666", "object": { "id": "66666666-6666-6666-6666-666666666666", "status": "completed", "send_amount": "25", "send_currency": "USD", "receive_amount": "15125", "receive_currency": "XAF", "operator_code": "CM_MTN_MOMO", "wallet_impact": { "debit_amount": "26.50", "currency": "USD" }, "completed_at": "2026-06-08T10:41:30Z" } } } ``` **Transfer webhook** ```json { "id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "event": "transfer.completed", "created_at": "2026-06-08T11:30:00Z", "data": { "type": "transfer", "id": "77777777-7777-7777-7777-777777777777", "object": { "id": "77777777-7777-7777-7777-777777777777", "status": "completed", "payin_status": "completed", "payout_status": "completed", "send_amount": "100000", "send_currency": "XAF", "receive_amount": "98500", "receive_currency": "XOF", "corridor_code": "CM-CI-XAF-XOF", "payer_operator_code": "CM_MTN_MOMO", "recipient_operator_code": "CI_ORANGE_MOMO", "collection_completed_at": "2026-06-08T11:15:00Z", "disbursement_completed_at": "2026-06-08T11:28:00Z" } } } ``` **Transfer payin leg webhook** ```json { "id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "event": "transfer.payin.completed", "created_at": "2026-06-08T11:15:05Z", "data": { "type": "transfer", "id": "77777777-7777-7777-7777-777777777777", "object": { "id": "77777777-7777-7777-7777-777777777777", "status": "disbursing", "payin_status": "completed", "payout_status": "pending", "payin_amount": "100000", "payin_currency": "XAF", "payout_amount": "98500", "payout_currency": "XOF", "payer_operator_code": "CM_MTN_MOMO", "recipient_operator_code": "CI_ORANGE_MOMO", "collection_reference": "TXN_COLLECTION_123", "collection_completed_at": "2026-06-08T11:15:00Z" } } } ``` **Transfer payout leg webhook** ```json { "id": "cccccccc-cccc-cccc-cccc-cccccccccccc", "event": "transfer.payout.failed", "created_at": "2026-06-08T11:28:05Z", "data": { "type": "transfer", "id": "77777777-7777-7777-7777-777777777777", "object": { "id": "77777777-7777-7777-7777-777777777777", "status": "failed", "payin_status": "completed", "payout_status": "failed", "payin_amount": "100000", "payin_currency": "XAF", "payout_amount": "98500", "payout_currency": "XOF", "payer_operator_code": "CM_MTN_MOMO", "recipient_operator_code": "CI_ORANGE_MOMO", "disbursement_reference": "TXN_PAYOUT_123", "disbursement_failed_at": "2026-06-08T11:28:00Z" } } } ``` ## Delivery and retries Return any **2xx** status code to acknowledge receipt. If your endpoint returns a non-2xx or times out, Bumxpress retries with exponential backoff: | Failed attempt | Next retry | | -------------- | ----------- | | 1 | 1 minute | | 2 | 5 minutes | | 3 | 15 minutes | | 4 | 1 hour | | 5 | 4 hours | | 6 | 12 hours | After the seventh failed attempt, delivery is marked failed. ## Recommended handler pattern Implement your webhook handler with these rules: 1. **Verify** the HMAC signature. 2. **Deduplicate** using `X-Bumxpress-Webhook-Id` or event `id`. 3. **Update** your local record using `data.id` and `data.type`. 4. **Acknowledge** with `200 OK` only after the update succeeds. 5. **Fallback** to `GET /payins/{id}`, `GET /payouts/{id}`, or `GET /transfers/{id}` when you need to recover from missed events. --- # Go-live checklist Source: /guides/go-live-checklist Section: Guides / Operate --- title: "Go-live checklist" description: "Prepare a Bumxpress Business merchant integration for production traffic." --- Use this checklist before moving real payment volume through the merchant API. ## Credentials - Create production API credentials in the merchant dashboard. - Store `X-Api-Secret` in a secret manager. - Confirm secrets are not exposed in browser, mobile, logs, analytics, or public repositories. - Document the credential rotation process. ## Payment flows - Store all resource IDs returned by create responses. - Use a unique `Idempotency-Key` for every distinct create request. - Confirm quote expiry handling creates a fresh quote. - Confirm payin, payout, and transfer records can move from pending to final status. - Confirm your merchant account has the required operators and corridors enabled. ## Webhooks - Configure production webhook endpoints. - Verify `X-Bumxpress-Signature` before processing events. - Process duplicate webhook deliveries idempotently. - Reconcile missed events with `GET` endpoints. - Return `2xx` only after accepting an event. ## Operations - Add internal dashboards or logs for customer, quote, payment, transfer, and webhook IDs. - Define support procedures for pending, failed, and duplicate-looking payments. - Monitor API error rates and webhook delivery failures. --- # Changelog Source: /guides/changelog Section: Guides / Operate --- title: "Changelog" description: "Merchant API documentation updates." --- ## July 2026 - Created the Mintlify documentation project. - Added starter guides, recipes, and API reference pages for the merchant API. - Added coverage, authentication, idempotency, and webhook documentation. --- # Create customer Source: /api-reference/customers/create-customer Section: API Reference / Customers --- title: "Create customer" description: "Create an individual, retail, or business customer." openapi: "POST /customers" --- Create a customer before starting payment flows so quotes, payments, transfers, and webhook events can be reconciled to your internal records. --- # Get customer Source: /api-reference/customers/get-customer Section: API Reference / Customers --- title: "Get customer" description: "Retrieve a merchant-scoped customer by ID." openapi: "GET /customers/{customer_id}" --- The authenticated API key can only access customers that belong to its merchant. --- # Submit KYC documents Source: /api-reference/customer-kyc/submit-kyc-documents Section: API Reference / Customer KYC --- title: "Submit KYC documents" description: "Submit identity documents for a customer." openapi: "POST /customers/{customer_id}/kyc" --- Document files must be available at public HTTP or HTTPS URLs so Bumxpress can fetch them. --- # Get customer KYC status Source: /api-reference/customer-kyc/get-customer-kyc-status Section: API Reference / Customer KYC --- title: "Get customer KYC status" description: "Read the latest KYC status and submitted documents for a customer." openapi: "GET /customers/{customer_id}/kyc" --- Use this endpoint to reconcile customer KYC state before payout or transfer flows that require provider compliance checks. --- # Create payin quote Source: /api-reference/quotes/create-payin-quote Section: API Reference / Quotes --- title: "Create payin quote" description: "Create a quote before initiating a payin." openapi: "POST /quotes/payin" --- Quotes lock fees, routing, FX, and amounts for 15 minutes. --- # Create payout quote Source: /api-reference/quotes/create-payout-quote Section: API Reference / Quotes --- title: "Create payout quote" description: "Create a quote before initiating a payout." openapi: "POST /quotes/payout" --- Use payout quotes before sending funds from your USD merchant wallet to a recipient in local currency. --- # Create transfer quote Source: /api-reference/quotes/create-transfer-quote Section: API Reference / Quotes --- title: "Create transfer quote" description: "Create a quote for a two-leg transfer flow." openapi: "POST /quotes/transfer" --- Use transfer quotes for flows that collect from a payer and disburse to a recipient. --- # Get quote Source: /api-reference/quotes/get-quote Section: API Reference / Quotes --- title: "Get quote" description: "Retrieve a payin, payout, or transfer quote by ID." openapi: "GET /quotes/{quote_id}" --- Expired quotes cannot be used to create payment resources. --- # Create payin Source: /api-reference/payins/create-payin Section: API Reference / Payins --- title: "Create payin" description: "Create a quote-backed payin." openapi: "POST /payins" --- The API returns a pending resource while provider processing continues asynchronously. --- # Get payin Source: /api-reference/payins/get-payin Section: API Reference / Payins --- title: "Get payin" description: "Retrieve a payin by ID." openapi: "GET /payins/{payin_id}" --- Poll this endpoint or process webhooks to reconcile final status. --- # Create payout Source: /api-reference/payouts/create-payout Section: API Reference / Payouts --- title: "Create payout" description: "Create a quote-backed payout." openapi: "POST /payouts" --- Payouts debit the merchant wallet and are processed asynchronously. --- # Get payout Source: /api-reference/payouts/get-payout Section: API Reference / Payouts --- title: "Get payout" description: "Retrieve a payout by ID." openapi: "GET /payouts/{payout_id}" --- Store payout IDs from create responses or webhook payloads. --- # Create transfer Source: /api-reference/transfers/create-transfer Section: API Reference / Transfers --- title: "Create transfer" description: "Create a quote-backed transfer." openapi: "POST /transfers" --- Bumxpress collects from the payer first, then disburses to the recipient. --- # Get transfer Source: /api-reference/transfers/get-transfer Section: API Reference / Transfers --- title: "Get transfer" description: "Retrieve transfer status and leg execution details." openapi: "GET /transfers/{transfer_id}" --- Use this endpoint to read payin and payout leg status, execution metadata, and timestamps. --- # Relaunch transfer payout Source: /api-reference/transfers/relaunch-transfer-payout Section: API Reference / Transfers --- title: "Relaunch transfer payout" description: "Retry a failed transfer disbursement leg." openapi: "POST /transfers/{transfer_id}/relaunch-payout" --- Retry a failed transfer disbursement leg without collecting from the payer again. --- # OpenAPI specification Source: /openapi.yaml ```yaml --- openapi: 3.0.3 info: title: Bumxpress Business Merchant API version: 1.0.0 description: | Merchant API for customers, KYC, quotes, payins, payouts, transfers, and webhooks. All merchant resources are scoped to the merchant attached to the API key. license: name: Proprietary url: https://business.bumxpress.com servers: - url: https://api.business.bumxpress.com description: Production security: - ApiKeyAuth: [] ApiSecretAuth: [] tags: - name: Customers description: Create and retrieve merchant-scoped customer records. - name: Customer KYC description: Submit and retrieve customer identity document status. - name: Quotes description: Create and retrieve pricing and routing quotes. - name: Payins description: Create and retrieve payment collection resources. - name: Payouts description: Create and retrieve disbursement resources. - name: Transfers description: Create, retrieve, and relaunch two-leg transfer resources. paths: "/customers": post: tags: - Customers summary: Create customer description: Create an individual, retail, or business customer. operationId: createCustomer parameters: - "$ref": "#/components/parameters/IdempotencyKey" requestBody: required: true content: application/json: schema: "$ref": "#/components/schemas/CreateCustomerRequest" examples: individual: value: external_ref: your-internal-id-123 customer_type: individual first_name: Awa last_name: Ngu id_number: ID123456 id_type: national_id email: awa@example.com phone: "+237670000000" country_code: CM nationality_code: CM date_of_birth: '1990-05-15' address_line1: 123 Main Street city: Douala occupation: Engineer source_of_funds: salary business: value: external_ref: biz-456 customer_type: business business_name: Acme SARL email: billing@acme.com phone: "+237670000001" country_code: CM nationality_code: CM address_line1: 45 Avenue Kennedy city: Douala responses: '201': description: Customer created. content: application/json: schema: "$ref": "#/components/schemas/Customer" '400': "$ref": "#/components/responses/BadRequest" '401': "$ref": "#/components/responses/Unauthorized" '409': "$ref": "#/components/responses/Conflict" "/customers/{customer_id}": get: tags: - Customers summary: Get customer operationId: getCustomer parameters: - "$ref": "#/components/parameters/CustomerId" responses: '200': description: Customer object. content: application/json: schema: "$ref": "#/components/schemas/Customer" '401': "$ref": "#/components/responses/Unauthorized" '404': "$ref": "#/components/responses/NotFound" "/customers/{customer_id}/kyc": post: tags: - Customer KYC summary: Submit KYC documents description: Submit identity documents for a customer. Document file URLs must be public HTTP or HTTPS URLs that Bumxpress can fetch. operationId: submitCustomerKyc parameters: - "$ref": "#/components/parameters/CustomerId" requestBody: required: true content: application/json: schema: "$ref": "#/components/schemas/SubmitKycRequest" example: documents: - document_type: national_id document_number: ID123456 issue_country_code: CM issue_date: '2020-01-15' expiry_date: '2030-01-15' front_file_url: https://cdn.example.com/kyc/front.jpg back_file_url: https://cdn.example.com/kyc/back.jpg selfie_file_url: https://cdn.example.com/kyc/selfie.jpg responses: '201': description: KYC documents accepted. content: application/json: schema: "$ref": "#/components/schemas/KycStatus" '400': "$ref": "#/components/responses/BadRequest" '401': "$ref": "#/components/responses/Unauthorized" '404': "$ref": "#/components/responses/NotFound" get: tags: - Customer KYC summary: Get customer KYC status operationId: getCustomerKyc parameters: - "$ref": "#/components/parameters/CustomerId" responses: '200': description: Customer KYC status and documents. content: application/json: schema: "$ref": "#/components/schemas/KycStatus" '401': "$ref": "#/components/responses/Unauthorized" '404': "$ref": "#/components/responses/NotFound" "/quotes/payin": post: tags: - Quotes summary: Create payin quote description: Create a quote to collect money from a customer into the merchant USD wallet. operationId: createPayinQuote parameters: - "$ref": "#/components/parameters/IdempotencyKey" requestBody: required: true content: application/json: schema: "$ref": "#/components/schemas/CreatePayinQuoteRequest" responses: '201': description: Payin quote created. content: application/json: schema: "$ref": "#/components/schemas/Quote" '400': "$ref": "#/components/responses/BadRequest" '401': "$ref": "#/components/responses/Unauthorized" '409': "$ref": "#/components/responses/Conflict" "/quotes/payout": post: tags: - Quotes summary: Create payout quote description: Create a quote to send money from the merchant USD wallet to a recipient in local currency. operationId: createPayoutQuote parameters: - "$ref": "#/components/parameters/IdempotencyKey" requestBody: required: true content: application/json: schema: "$ref": "#/components/schemas/CreatePayoutQuoteRequest" responses: '201': description: Payout quote created. content: application/json: schema: "$ref": "#/components/schemas/Quote" '400': "$ref": "#/components/responses/BadRequest" '401': "$ref": "#/components/responses/Unauthorized" '409': "$ref": "#/components/responses/Conflict" "/quotes/transfer": post: tags: - Quotes summary: Create transfer quote description: Create a quote for a two-leg flow that collects from a payer and disburses to a recipient. operationId: createTransferQuote parameters: - "$ref": "#/components/parameters/IdempotencyKey" requestBody: required: true content: application/json: schema: "$ref": "#/components/schemas/CreateTransferQuoteRequest" responses: '201': description: Transfer quote created. content: application/json: schema: "$ref": "#/components/schemas/Quote" '400': "$ref": "#/components/responses/BadRequest" '401': "$ref": "#/components/responses/Unauthorized" '409': "$ref": "#/components/responses/Conflict" "/quotes/{quote_id}": get: tags: - Quotes summary: Get quote operationId: getQuote parameters: - "$ref": "#/components/parameters/QuoteId" responses: '200': description: Quote object. content: application/json: schema: "$ref": "#/components/schemas/Quote" '401': "$ref": "#/components/responses/Unauthorized" '404': "$ref": "#/components/responses/NotFound" "/payins": post: tags: - Payins summary: Create payin description: Create a quote-backed payin. The API returns pending and processes the provider submission asynchronously. operationId: createPayin parameters: - "$ref": "#/components/parameters/IdempotencyKey" requestBody: required: true content: application/json: schema: "$ref": "#/components/schemas/CreatePayinRequest" responses: '201': description: Payin created. content: application/json: schema: "$ref": "#/components/schemas/Payin" '400': "$ref": "#/components/responses/BadRequest" '401': "$ref": "#/components/responses/Unauthorized" '409': "$ref": "#/components/responses/Conflict" "/payins/{payin_id}": get: tags: - Payins summary: Get payin operationId: getPayin parameters: - "$ref": "#/components/parameters/PayinId" responses: '200': description: Payin object. content: application/json: schema: "$ref": "#/components/schemas/Payin" '401': "$ref": "#/components/responses/Unauthorized" '404': "$ref": "#/components/responses/NotFound" "/payouts": post: tags: - Payouts summary: Create payout description: Create a quote-backed payout. Payout processing is asynchronous. operationId: createPayout parameters: - "$ref": "#/components/parameters/IdempotencyKey" requestBody: required: true content: application/json: schema: "$ref": "#/components/schemas/CreatePayoutRequest" responses: '201': description: Payout created. content: application/json: schema: "$ref": "#/components/schemas/Payout" '400': "$ref": "#/components/responses/BadRequest" '401': "$ref": "#/components/responses/Unauthorized" '409': "$ref": "#/components/responses/Conflict" "/payouts/{payout_id}": get: tags: - Payouts summary: Get payout operationId: getPayout parameters: - "$ref": "#/components/parameters/PayoutId" responses: '200': description: Payout object. content: application/json: schema: "$ref": "#/components/schemas/Payout" '401': "$ref": "#/components/responses/Unauthorized" '404': "$ref": "#/components/responses/NotFound" "/transfers": post: tags: - Transfers summary: Create transfer description: Create a quote-backed transfer that collects from a payer and disburses to a recipient. operationId: createTransfer parameters: - "$ref": "#/components/parameters/IdempotencyKey" requestBody: required: true content: application/json: schema: "$ref": "#/components/schemas/CreateTransferRequest" responses: '201': description: Transfer created. content: application/json: schema: "$ref": "#/components/schemas/Transfer" '400': "$ref": "#/components/responses/BadRequest" '401': "$ref": "#/components/responses/Unauthorized" '409': "$ref": "#/components/responses/Conflict" "/transfers/{transfer_id}": get: tags: - Transfers summary: Get transfer operationId: getTransfer parameters: - "$ref": "#/components/parameters/TransferId" responses: '200': description: Transfer object. content: application/json: schema: "$ref": "#/components/schemas/Transfer" '401': "$ref": "#/components/responses/Unauthorized" '404': "$ref": "#/components/responses/NotFound" "/transfers/{transfer_id}/relaunch-payout": post: tags: - Transfers summary: Relaunch transfer payout description: Retry a failed disbursement leg without re-collecting from the payer. operationId: relaunchTransferPayout parameters: - "$ref": "#/components/parameters/TransferId" - "$ref": "#/components/parameters/IdempotencyKey" requestBody: required: false content: application/json: schema: "$ref": "#/components/schemas/RelaunchPayoutRequest" responses: '202': description: Payout leg relaunched. content: application/json: schema: "$ref": "#/components/schemas/Transfer" '400': "$ref": "#/components/responses/BadRequest" '401': "$ref": "#/components/responses/Unauthorized" '404': "$ref": "#/components/responses/NotFound" '409': "$ref": "#/components/responses/Conflict" components: securitySchemes: ApiKeyAuth: type: apiKey in: header name: X-Api-Key description: Public API key from the merchant dashboard. ApiSecretAuth: type: apiKey in: header name: X-Api-Secret description: Secret shown once when the API key is created. parameters: IdempotencyKey: name: Idempotency-Key in: header required: true description: Unique key for this business intent. Reuse only when retrying the same request body. schema: type: string example: payin_2026_06_08_0001 CustomerId: name: customer_id in: path required: true schema: type: string format: uuid QuoteId: name: quote_id in: path required: true schema: type: string format: uuid PayinId: name: payin_id in: path required: true schema: type: string format: uuid PayoutId: name: payout_id in: path required: true schema: type: string format: uuid TransferId: name: transfer_id in: path required: true schema: type: string format: uuid responses: BadRequest: description: Invalid body, missing field, expired quote, quote mismatch, or insufficient balance. content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" Unauthorized: description: Missing, invalid, expired, or inactive API credentials. content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" NotFound: description: Resource not found for the authenticated merchant. content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" Conflict: description: Idempotency conflict or request with same key still processing. content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" schemas: ErrorResponse: type: object required: - error properties: error: type: object required: - code - message properties: code: type: string example: bad_request message: type: string example: quote_id is required CreateCustomerRequest: type: object properties: external_ref: type: string description: Merchant reference, unique per merchant. customer_type: type: string enum: - individual - retail - business default: individual first_name: type: string last_name: type: string business_name: type: string id_number: type: string id_type: type: string enum: - national_id - passport - driver_license email: type: string format: email phone: type: string example: "+237670000000" country_code: "$ref": "#/components/schemas/CountryCode" nationality_code: "$ref": "#/components/schemas/CountryCode" date_of_birth: type: string format: date address_line1: type: string city: type: string occupation: type: string source_of_funds: type: string Customer: allOf: - "$ref": "#/components/schemas/CreateCustomerRequest" - type: object required: - id - merchant_id - customer_type - kyc_status - status - created_at - updated_at properties: id: type: string format: uuid merchant_id: type: string format: uuid kyc_status: type: string enum: - not_started - pending - approved - rejected status: type: string example: active created_at: type: string format: date-time updated_at: type: string format: date-time _meta: "$ref": "#/components/schemas/IdempotencyMeta" SubmitKycRequest: type: object required: - documents properties: documents: type: array minItems: 1 items: "$ref": "#/components/schemas/KycDocumentInput" KycDocumentInput: type: object required: - document_type properties: document_type: type: string example: national_id document_number: type: string issue_country_code: "$ref": "#/components/schemas/CountryCode" issue_date: type: string format: date expiry_date: type: string format: date front_file_url: type: string format: uri back_file_url: type: string format: uri selfie_file_url: type: string format: uri KycStatus: type: object required: - customer_id - kyc_status - documents properties: customer_id: type: string format: uuid kyc_status: type: string enum: - not_started - pending - approved - rejected documents: type: array items: allOf: - "$ref": "#/components/schemas/KycDocumentInput" - type: object properties: id: type: string format: uuid status: type: string example: uploaded created_at: type: string format: date-time CreatePayinQuoteRequest: type: object required: - country_code - operator_code - rail_type - send_amount - send_currency properties: customer_id: type: string format: uuid country_code: "$ref": "#/components/schemas/CountryCode" operator_code: type: string example: CM_MTN_MOMO rail_type: "$ref": "#/components/schemas/RailType" send_amount: "$ref": "#/components/schemas/DecimalString" send_currency: "$ref": "#/components/schemas/CurrencyCode" example: customer_id: 22222222-2222-2222-2222-222222222222 country_code: CM operator_code: CM_MTN_MOMO rail_type: mobile_money send_amount: '10000' send_currency: XAF CreatePayoutQuoteRequest: allOf: - "$ref": "#/components/schemas/CreatePayinQuoteRequest" example: customer_id: 22222222-2222-2222-2222-222222222222 country_code: CM operator_code: CM_MTN_MOMO rail_type: mobile_money send_amount: '25.00' send_currency: USD CreateTransferQuoteRequest: type: object required: - corridor_code - payer_operator_code - recipient_operator_code - payout_currency properties: customer_id: type: string format: uuid corridor_code: type: string example: CM-CI-XAF-XOF payer_operator_code: type: string example: CM_MTN_MOMO recipient_operator_code: type: string example: CI_ORANGE_MOMO payin_amount: "$ref": "#/components/schemas/DecimalString" payin_currency: "$ref": "#/components/schemas/CurrencyCode" payout_amount: "$ref": "#/components/schemas/DecimalString" payout_currency: "$ref": "#/components/schemas/CurrencyCode" send_amount: "$ref": "#/components/schemas/DecimalString" send_currency: "$ref": "#/components/schemas/CurrencyCode" example: customer_id: 22222222-2222-2222-2222-222222222222 corridor_code: CM-CI-XAF-XOF payer_operator_code: CM_MTN_MOMO recipient_operator_code: CI_ORANGE_MOMO payin_amount: '100000' payin_currency: XAF payout_amount: '98500' payout_currency: XOF send_amount: '100000' send_currency: XAF Quote: type: object properties: id: type: string format: uuid customer_id: type: string format: uuid flow_type: type: string enum: - payin - payout - transfer status: type: string enum: - active - expired - consumed expires_at: type: string format: date-time send_amount: "$ref": "#/components/schemas/DecimalString" send_currency: "$ref": "#/components/schemas/CurrencyCode" receive_amount: "$ref": "#/components/schemas/DecimalString" receive_currency: "$ref": "#/components/schemas/CurrencyCode" country_code: "$ref": "#/components/schemas/CountryCode" operator_code: type: string rail_type: "$ref": "#/components/schemas/RailType" corridor_code: type: string corridor_type: type: string payer_operator_code: type: string recipient_operator_code: type: string total_fee: "$ref": "#/components/schemas/DecimalString" wallet_impact: type: object additionalProperties: true created_at: type: string format: date-time _meta: "$ref": "#/components/schemas/IdempotencyMeta" CreatePayinRequest: type: object required: - quote_id - customer_id - source properties: quote_id: type: string format: uuid customer_id: type: string format: uuid source: "$ref": "#/components/schemas/RailParty" example: quote_id: 33333333-3333-3333-3333-333333333333 customer_id: 22222222-2222-2222-2222-222222222222 source: country_code: CM rail_type: mobile_money phone: "+237670000000" operator_code: CM_MTN_MOMO CreatePayoutRequest: type: object required: - quote_id - customer_id - recipient properties: quote_id: type: string format: uuid customer_id: type: string format: uuid payment_reason_code: type: string example: OTHER payment_reason_text: type: string example: Merchant payout recipient: "$ref": "#/components/schemas/Recipient" example: quote_id: 33333333-3333-3333-3333-333333333333 customer_id: 22222222-2222-2222-2222-222222222222 payment_reason_code: OTHER payment_reason_text: Merchant payout recipient: recipient_type: individual first_name: Awa last_name: Ngu country_code: CM rail_type: mobile_money phone: "+237670000000" email: awa@example.com recipient_nationality_code: CM operator_code: CM_MTN_MOMO address_line1: 123 Main Street city: Douala CreateTransferRequest: type: object required: - quote_id - customer_id - payer - recipient properties: quote_id: type: string format: uuid customer_id: type: string format: uuid payment_reason_code: type: string example: OTHER sender_source_of_funds: type: string example: salary sender_occupation: type: string example: Engineer payer: "$ref": "#/components/schemas/RailParty" recipient: "$ref": "#/components/schemas/Recipient" example: quote_id: 33333333-3333-3333-3333-333333333333 customer_id: 22222222-2222-2222-2222-222222222222 payment_reason_code: OTHER sender_source_of_funds: salary sender_occupation: Engineer payer: country_code: CM rail_type: mobile_money phone: "+237670000000" operator_code: CM_MTN_MOMO recipient: recipient_type: individual first_name: Mariam last_name: Traore country_code: CI rail_type: mobile_money phone: "+2250700112233" operator_code: CI_ORANGE_MOMO email: mariam.traore@example.com recipient_nationality_code: CI address_line1: Rue du Commerce city: Abidjan RelaunchPayoutRequest: type: object properties: payout_amount: "$ref": "#/components/schemas/DecimalString" recipient: "$ref": "#/components/schemas/Recipient" example: payout_amount: '98500' recipient: recipient_type: individual first_name: Mariam last_name: Traore country_code: CI rail_type: mobile_money phone: "+2250700112233" operator_code: CI_ORANGE_MOMO email: mariam.traore@example.com recipient_nationality_code: CI address_line1: Rue du Commerce city: Abidjan Payin: allOf: - "$ref": "#/components/schemas/PaymentBase" - type: object properties: status: type: string enum: - created - pending - completed - failed source: "$ref": "#/components/schemas/RailParty" Payout: allOf: - "$ref": "#/components/schemas/PaymentBase" - type: object properties: status: type: string enum: - created - pending - completed - failed recipient: "$ref": "#/components/schemas/Recipient" Transfer: type: object properties: id: type: string format: uuid merchant_id: type: string format: uuid customer_id: type: string format: uuid quote_id: type: string format: uuid status: type: string enum: - pending - collecting - disbursing - completed - failed payin_status: type: string payout_status: type: string send_amount: "$ref": "#/components/schemas/DecimalString" send_currency: "$ref": "#/components/schemas/CurrencyCode" receive_amount: "$ref": "#/components/schemas/DecimalString" receive_currency: "$ref": "#/components/schemas/CurrencyCode" payin_amount: "$ref": "#/components/schemas/DecimalString" payin_currency: "$ref": "#/components/schemas/CurrencyCode" payout_amount: "$ref": "#/components/schemas/DecimalString" payout_currency: "$ref": "#/components/schemas/CurrencyCode" corridor_code: type: string corridor_type: type: string execution: type: object additionalProperties: true payer: "$ref": "#/components/schemas/RailParty" recipient: "$ref": "#/components/schemas/Recipient" pricing: type: object additionalProperties: true history: type: array items: "$ref": "#/components/schemas/StatusHistory" created_at: type: string format: date-time updated_at: type: string format: date-time PaymentBase: type: object properties: id: type: string format: uuid merchant_id: type: string format: uuid customer_id: type: string format: uuid quote_id: type: string format: uuid send_amount: "$ref": "#/components/schemas/DecimalString" send_currency: "$ref": "#/components/schemas/CurrencyCode" receive_amount: "$ref": "#/components/schemas/DecimalString" receive_currency: "$ref": "#/components/schemas/CurrencyCode" country_code: "$ref": "#/components/schemas/CountryCode" rail_type: "$ref": "#/components/schemas/RailType" operator_code: type: string provider_reference: type: string nullable: true wallet_impact: type: object additionalProperties: true pricing: type: object additionalProperties: true history: type: array items: "$ref": "#/components/schemas/StatusHistory" created_at: type: string format: date-time updated_at: type: string format: date-time RailParty: type: object required: - country_code - rail_type properties: country_code: "$ref": "#/components/schemas/CountryCode" rail_type: "$ref": "#/components/schemas/RailType" phone: type: string example: "+237670000000" operator_code: type: string example: CM_MTN_MOMO bank_name: type: string bank_code: type: string account_name: type: string account_number: type: string Recipient: allOf: - "$ref": "#/components/schemas/RailParty" - type: object required: - recipient_type properties: recipient_type: type: string enum: - individual - business first_name: type: string last_name: type: string business_name: type: string email: type: string format: email recipient_nationality_code: "$ref": "#/components/schemas/CountryCode" address_line1: type: string city: type: string StatusHistory: type: object properties: status: type: string reason: type: string nullable: true created_at: type: string format: date-time IdempotencyMeta: type: object properties: idempotency_key: type: string idempotency_replayed: type: boolean CountryCode: type: string minLength: 2 maxLength: 2 example: CM CurrencyCode: type: string minLength: 3 maxLength: 3 example: XAF DecimalString: type: string pattern: "^[0-9]+(\\.[0-9]+)?$" example: '10000' RailType: type: string enum: - mobile_money - bank_transfer ```