{
  "openapi": "3.0.3",
  "info": {
    "title": "Wajub API",
    "description": "Africa's payment orchestrator REST API.",
    "version": "2026-10-11",
    "contact": {
      "name": "Wajub",
      "url": "https://wajub.com",
      "email": "hello@wajub.com"
    },
    "termsOfService": "https://wajub.com/en/legal/tos"
  },
  "servers": [
    {
      "url": "https://api.wajub.com",
      "description": "API, test mode is controlled by your API key (pk_test.… / sk_test.…), not the URL."
    }
  ],
  "tags": [
    {
      "name": "Payments",
      "description": ""
    },
    {
      "name": "Refunds",
      "description": ""
    },
    {
      "name": "Transfers",
      "description": ""
    },
    {
      "name": "Customers",
      "description": "Create and manage reusable customer profiles. Linking a customer to a payment enables transaction history, better success-rate optimization, and reduces friction for returning payers."
    },
    {
      "name": "Beneficiaries",
      "description": "Pre-registered transfer recipients. Save frequently-used recipients as beneficiaries to simplify your payout API calls."
    },
    {
      "name": "Balance",
      "description": ""
    },
    {
      "name": "Events",
      "description": "Read and replay merchant events (powers `wajub events list/retrieve/resend`). Events are the source of truth for webhook deliveries; resending delivers the event again to every matching active endpoint.\n\nWith `X-Sync`, a platform reads the events of what its connection brought, never the merchant's other events, and a resend reaches the platform's own endpoints, never the merchant's."
    },
    {
      "name": "Webhook Endpoints",
      "description": "Manage webhook endpoint subscriptions. When a subscribed event fires, Wajub sends a signed HTTP POST to your endpoint URL."
    },
    {
      "name": "Channels",
      "description": ""
    },
    {
      "name": "Countries",
      "description": ""
    },
    {
      "name": "Currencies",
      "description": ""
    },
    {
      "name": "General",
      "description": ""
    },
    {
      "name": "Invoices",
      "description": "Create, send, and track one-off or recurring invoices. Live environment only."
    },
    {
      "name": "Payment Links",
      "description": "No-code payment links, shareable URLs that let customers pay without writing any integration code. Live environment only."
    },
    {
      "name": "Providers",
      "description": ""
    },
    {
      "name": "Subaccounts",
      "description": "Merchant subaccounts for marketplace and platform use cases (Sync product). Each subaccount can receive a percentage or fixed amount split from payments."
    }
  ],
  "components": {
    "securitySchemes": {
      "default": {
        "type": "apiKey",
        "name": "Authorization",
        "in": "header",
        "description": "A public key (pk./pk_test.) is accepted on /payments, /customers, /links, /invoices and the catalogue reads (/channels, /providers, /countries, /currencies); anything that moves money out, reads the balance or manages the account answers 406 to it. It is an identifier, never an authorization. Use a secret key (sk./sk_test.) for sensitive operations (transfers, refunds, balance), or a restricted key (rk./rk_test.) scoped to specific permissions. The _test. variant of any key selects the sandbox environment, there is no separate sandbox URL. Never expose your secret key in client-side code."
      }
    },
    "schemas": {
      "Payment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "trx_CSUGajfv9xh0XQ5wu2lx"
          },
          "reference": {
            "type": "string",
            "example": "order-4172"
          },
          "invoice": {
            "type": "string",
            "example": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
            "description": "The `id` of the invoice this payment settles, when it was made on an invoice's page. Absent otherwise."
          },
          "amount": {
            "type": "integer",
            "example": 25000
          },
          "amount_paid": {
            "type": "integer",
            "example": 25000
          },
          "currency": {
            "type": "string",
            "example": "XAF"
          },
          "status": {
            "type": "string",
            "example": "succeeded"
          },
          "description": {
            "type": "string",
            "example": "Order #4172"
          },
          "customer": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3"
              },
              "name": {
                "type": "string",
                "example": "Amina Diallo"
              },
              "email": {
                "type": "string",
                "example": "amina@example.com"
              },
              "phone": {
                "type": "string",
                "example": "+237670000000"
              }
            }
          },
          "payment_method": {
            "type": "object",
            "properties": {
              "channel": {
                "type": "string",
                "example": "cm.mtn"
              },
              "account": {
                "type": "string",
                "example": "+237670000000"
              }
            }
          },
          "channel": {
            "type": "string",
            "example": "cm.mtn"
          },
          "callback": {
            "type": "string",
            "example": "https://example.com/return"
          },
          "sandbox": {
            "type": "boolean",
            "example": false
          },
          "items": {
            "type": "array",
            "example": [
              {
                "name": "T-shirt",
                "quantity": 2
              }
            ],
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "example": "T-shirt"
                },
                "quantity": {
                  "type": "integer",
                  "example": 2
                }
              }
            }
          },
          "metadata": {
            "type": "object",
            "properties": {
              "order_id": {
                "type": "string",
                "example": "4172"
              }
            }
          },
          "tax": {
            "type": "object",
            "properties": {
              "amount": {
                "type": "number",
                "example": 4035.64
              },
              "taxable_amount": {
                "type": "number",
                "example": 20964.36
              },
              "rate": {
                "type": "number",
                "example": 19.25
              },
              "name": {
                "type": "string",
                "example": "TVA"
              },
              "country": {
                "type": "string",
                "example": "CM"
              },
              "inclusive": {
                "type": "boolean",
                "example": true
              }
            }
          },
          "receipt_url": {
            "type": "string",
            "example": "https://invoice.wajub.com/r/trx_CSUGajfv9xh0XQ5wu2lx?s=9f2c4e7a1b8d3f6c0e5a2d9b7c4f1e8a3d6b0c9e2f5a8d1b4e7c0a3f6d9b2e5c"
          },
          "credited_at": {
            "type": "string",
            "example": "2026-01-15T10:31:12+00:00"
          },
          "created_at": {
            "type": "string",
            "example": "2026-01-15T10:30:00+00:00"
          },
          "updated_at": {
            "type": "string",
            "example": "2026-01-15T10:31:12+00:00"
          },
          "settled": {
            "type": "boolean",
            "example": true
          },
          "split": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "splt_Jc5Ny7Qd1Hs8Mv3Ka6Wf"
              },
              "split_number": {
                "type": "integer",
                "example": 1
              },
              "total_splits": {
                "type": "integer",
                "example": 2
              },
              "split_currency": {
                "type": "string",
                "example": "XAF"
              },
              "amount": {
                "type": "integer",
                "example": 300000
              },
              "status": {
                "type": "string",
                "example": "succeeded"
              }
            },
            "description": "The instalment this call is about: `id`, `split_number`, `total_splits`, `split_currency`, `amount` and `status`."
          }
        }
      },
      "Refund": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw"
          },
          "transaction": {
            "type": "string",
            "example": "trx_CSUGajfv9xh0XQ5wu2lx"
          },
          "reference": {
            "type": "string",
            "example": "refund-ord-1042"
          },
          "amount": {
            "type": "number",
            "example": 5000
          },
          "currency": {
            "type": "string",
            "example": "XAF"
          },
          "fees_bearer": {
            "type": "string",
            "example": "merchant"
          },
          "fee_amount": {
            "type": "number",
            "example": 100
          },
          "payer_amount": {
            "type": "number",
            "example": 5000
          },
          "status": {
            "type": "string",
            "example": "succeeded"
          },
          "execution_mode": {
            "type": "string",
            "example": "automatic"
          },
          "reason": {
            "type": "string",
            "example": "requested_by_customer"
          },
          "metadata": {
            "type": "object",
            "properties": {}
          },
          "ledger_balance_currency": {
            "type": "string",
            "example": "XAF"
          },
          "ledger_balance_before": {
            "type": "number",
            "example": 85000
          },
          "ledger_balance_after": {
            "type": "number",
            "example": 80000
          },
          "sandbox": {
            "type": "boolean",
            "example": false
          },
          "created_at": {
            "type": "string",
            "example": "2026-09-18T09:30:12+00:00"
          },
          "updated_at": {
            "type": "string",
            "example": "2026-09-18T09:31:02+00:00"
          }
        }
      },
      "Transfer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "po_Gv2Ks9Lp4Xr7Mw1Qt8Zn"
          },
          "reference": {
            "type": "string",
            "example": "N7vW4mX1kQ8"
          },
          "amount": {
            "type": "integer",
            "example": 10000
          },
          "currency": {
            "type": "string",
            "example": "XAF"
          },
          "status": {
            "type": "string",
            "example": "succeeded"
          },
          "complete": {
            "type": "boolean",
            "example": true
          },
          "provider_reference": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "description": {
            "type": "string",
            "example": "Supplier payment #892"
          },
          "reason": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "properties": {
              "vendor_id": {
                "type": "string",
                "example": "v_892"
              }
            }
          },
          "ledger_balance_currency": {
            "type": "string",
            "example": "XAF"
          },
          "sandbox": {
            "type": "boolean",
            "example": false
          },
          "source": {
            "type": "string",
            "example": "api"
          },
          "succeeded_at": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "example": "2026-01-15T14:00:00+00:00"
          },
          "updated_at": {
            "type": "string",
            "example": "2026-01-15T14:00:00+00:00"
          },
          "provider": {
            "type": "object",
            "properties": {
              "slug": {
                "type": "string",
                "example": "mtn_momo"
              },
              "name": {
                "type": "string",
                "example": "MTN MoMo"
              }
            }
          },
          "beneficiary": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
              },
              "name": {
                "type": "string",
                "example": "Jean Dupont"
              },
              "phone": {
                "type": "string",
                "example": "+237670000000"
              },
              "email": {
                "type": "string",
                "example": null,
                "nullable": true
              },
              "deleted": {
                "type": "boolean",
                "example": false
              }
            }
          },
          "payment_method": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "pm_Hx3Lq8Vn2Rt6Ky9Wb4Zd"
              },
              "account_number": {
                "type": "string",
                "example": null,
                "nullable": true
              },
              "phone": {
                "type": "string",
                "example": "+237670000000"
              }
            }
          }
        }
      },
      "Customer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3"
          },
          "email": {
            "type": "string",
            "example": "amina@example.com"
          },
          "name": {
            "type": "string",
            "example": "Amina Diallo"
          },
          "status": {
            "type": "string",
            "example": "active"
          },
          "blocked": {
            "type": "boolean",
            "example": true
          },
          "block_reason": {
            "type": "string",
            "example": "Repeated chargebacks"
          }
        }
      },
      "Beneficiary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
          },
          "name": {
            "type": "string",
            "example": "Jean Dupont"
          },
          "email": {
            "type": "string",
            "example": "jean.dupont@example.com"
          },
          "phone": {
            "type": "string",
            "example": "+237670000000"
          },
          "country_code": {
            "type": "string",
            "example": "CM"
          },
          "note": {
            "type": "string",
            "example": "Pays every Friday"
          },
          "metadata": {
            "type": "object",
            "properties": {
              "seller_id": {
                "type": "string",
                "example": "42"
              }
            }
          },
          "sandbox": {
            "type": "boolean",
            "example": false
          },
          "is_active": {
            "type": "boolean",
            "example": true
          },
          "type": {
            "type": "string",
            "example": "standard"
          },
          "created_at": {
            "type": "string",
            "example": "2026-09-02T08:14:22+00:00"
          },
          "updated_at": {
            "type": "string",
            "example": "2026-09-02T08:14:22+00:00"
          },
          "verified": {
            "type": "boolean",
            "example": true
          },
          "verification": {
            "type": "string",
            "example": "verified"
          },
          "payment_method": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "pm_Kx7Wq2Rm9Tz4Lb8Nv3Hd"
              },
              "type": {
                "type": "string",
                "example": "mobile_money"
              },
              "name": {
                "type": "string",
                "example": "MTN Mobile Money CM"
              }
            }
          }
        }
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd"
          },
          "invoice_number": {
            "type": "string",
            "example": "INV-2026-0001",
            "nullable": true
          },
          "document_type": {
            "type": "string",
            "example": "invoice"
          },
          "status": {
            "type": "string",
            "example": "sent"
          },
          "customer": {
            "type": "string",
            "example": null,
            "nullable": true,
            "description": "The customer the invoice is addressed to, by its `cus_` id; `null` when it is addressed to a name and an e-mail only."
          },
          "customer_id": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "customer_name": {
            "type": "string",
            "example": "Amina Diallo"
          },
          "customer_email": {
            "type": "string",
            "example": "amina@example.com"
          },
          "customer_company_name": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "customer_phone": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "customer_address": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "invoice_date": {
            "type": "string",
            "example": "2026-09-16"
          },
          "due_date": {
            "type": "string",
            "example": "2026-09-30"
          },
          "currency": {
            "type": "string",
            "example": "XAF"
          },
          "language": {
            "type": "string",
            "example": "fr"
          },
          "subtotal": {
            "type": "integer",
            "example": 50000
          },
          "discount_amount": {
            "type": "integer",
            "example": 0
          },
          "tax_amount": {
            "type": "integer",
            "example": 0
          },
          "total": {
            "type": "integer",
            "example": 50000
          },
          "amount_paid": {
            "type": "integer",
            "example": 0
          },
          "amount_due": {
            "type": "integer",
            "example": 50000
          },
          "payment_type": {
            "type": "string",
            "example": "full"
          },
          "is_recurring": {
            "type": "boolean",
            "example": false
          },
          "recurring_interval": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "next_invoice_date": {
            "type": "string",
            "example": null,
            "nullable": true,
            "description": "When the next copy of a recurring invoice is due, `YYYY-MM-DD`. `null` once the series is over or stopped, and on an invoice that is not recurring."
          },
          "recurring_parent": {
            "type": "string",
            "example": null,
            "nullable": true,
            "description": "On a copy generated from a recurring invoice, the `id` of that invoice. `null` on an invoice you wrote."
          },
          "notes": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "terms": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "footer": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "accept": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "sent_at": {
            "type": "string",
            "example": "2026-09-16T10:15:37+00:00",
            "nullable": true
          },
          "paid_at": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "cancelled_at": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "items": {
            "type": "array",
            "example": [
              {
                "id": "9d3f6a2e-4b1c-4e8a-9f27-6c5d8b1a0e43",
                "name": "Website design",
                "description": null,
                "quantity": 1,
                "unit": null,
                "unit_price": 50000,
                "tax_rate": 0,
                "tax_amount": 0,
                "discount_type": null,
                "discount_value": 0,
                "discount_amount": 0,
                "subtotal": 50000,
                "total": 50000,
                "sort_order": 0
              }
            ],
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "example": "9d3f6a2e-4b1c-4e8a-9f27-6c5d8b1a0e43"
                },
                "name": {
                  "type": "string",
                  "example": "Website design"
                },
                "description": {
                  "type": "string",
                  "example": null,
                  "nullable": true
                },
                "quantity": {
                  "type": "integer",
                  "example": 1
                },
                "unit": {
                  "type": "string",
                  "example": null,
                  "nullable": true
                },
                "unit_price": {
                  "type": "integer",
                  "example": 50000
                },
                "tax_rate": {
                  "type": "integer",
                  "example": 0
                },
                "tax_amount": {
                  "type": "integer",
                  "example": 0
                },
                "discount_type": {
                  "type": "string",
                  "example": null,
                  "nullable": true
                },
                "discount_value": {
                  "type": "integer",
                  "example": 0
                },
                "discount_amount": {
                  "type": "integer",
                  "example": 0
                },
                "subtotal": {
                  "type": "integer",
                  "example": 50000
                },
                "total": {
                  "type": "integer",
                  "example": 50000
                },
                "sort_order": {
                  "type": "integer",
                  "example": 0
                }
              }
            }
          },
          "created_at": {
            "type": "string",
            "example": "2026-09-16T09:12:04+00:00"
          },
          "updated_at": {
            "type": "string",
            "example": "2026-09-16T10:15:37+00:00"
          }
        }
      },
      "Link": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "aB3dE5fG7"
          },
          "type": {
            "type": "string",
            "example": "product"
          },
          "product_type": {
            "type": "string",
            "example": "service"
          },
          "category_id": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "title": {
            "type": "string",
            "example": "Annual subscription"
          },
          "description": {
            "type": "string",
            "example": "One year of the members' area."
          },
          "external_reference": {
            "type": "string",
            "example": "CAT-2026-014"
          },
          "custom_url": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "url": {
            "type": "string",
            "example": "https://wajub.link/aB3dE5fG7"
          },
          "qr_url": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "price": {
            "type": "number",
            "example": 25000
          },
          "target_amount": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "min_amount": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "max_amount": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "currency": {
            "type": "string",
            "example": "XAF"
          },
          "cta_type": {
            "type": "string",
            "example": "pay"
          },
          "custom_cta_text": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "callback_url": {
            "type": "string",
            "example": "https://example.com/thanks"
          },
          "expiry_date": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "sales_limit": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "is_public": {
            "type": "boolean",
            "example": true
          },
          "show_progress": {
            "type": "boolean",
            "example": false
          },
          "show_contributors": {
            "type": "boolean",
            "example": false
          },
          "allow_overflow": {
            "type": "boolean",
            "example": false
          },
          "allow_custom_amount": {
            "type": "boolean",
            "example": false
          },
          "is_archived": {
            "type": "boolean",
            "example": false
          },
          "tags": {
            "type": "array",
            "example": [
              "membership"
            ],
            "items": {
              "type": "string"
            }
          },
          "accept": {
            "type": "object",
            "properties": {}
          },
          "suggested_amounts": {
            "type": "array",
            "example": []
          },
          "extra_fields": {
            "type": "object",
            "properties": {}
          },
          "product_variants": {
            "type": "array",
            "example": []
          },
          "event_start_date": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "event_end_date": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "event_location": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "event_address": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "event_city": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "event_country": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "event_capacity": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "event_timezone": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "fundraising_milestones": {
            "type": "array",
            "example": []
          },
          "campaign_deadline": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "recurring_enabled": {
            "type": "boolean",
            "example": false
          },
          "recurring_intervals": {
            "type": "array",
            "example": []
          },
          "allow_anonymous": {
            "type": "boolean",
            "example": false
          },
          "show_donor_wall": {
            "type": "boolean",
            "example": false
          },
          "impact_tiers": {
            "type": "array",
            "example": []
          },
          "single_use_link": {
            "type": "boolean",
            "example": false
          },
          "stock_quantity": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "allow_backorder": {
            "type": "boolean",
            "example": false
          },
          "shipping_required": {
            "type": "boolean",
            "example": false
          },
          "shipping_flat_rate": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "shipping_zones": {
            "type": "array",
            "example": []
          },
          "product_weight": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "product_weight_unit": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "service_duration": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "service_location_type": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "service_meeting_url": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "service_requirements": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "cancellation_policy": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "refund_policy": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "poster": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "gallery": {
            "type": "array",
            "example": []
          },
          "file_url": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "download_instructions": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "generate_qr_tickets": {
            "type": "boolean",
            "example": false
          },
          "attendee_info_fields": {
            "type": "array",
            "example": []
          },
          "thank_you_message": {
            "type": "string",
            "example": "Welcome aboard!"
          },
          "created_at": {
            "type": "string",
            "example": "2026-09-10T09:00:00+00:00"
          },
          "updated_at": {
            "type": "string",
            "example": "2026-09-10T09:00:00+00:00"
          }
        }
      },
      "Account": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "acc_Gt6yU3nE8rM1kS5vX9bQ"
          },
          "reference": {
            "type": "string",
            "example": "shop-amina"
          },
          "sandbox": {
            "type": "boolean",
            "example": false
          },
          "account_type": {
            "type": "string",
            "example": "direct"
          },
          "capabilities": {
            "type": "array",
            "example": [
              "read",
              "payments",
              "refunds"
            ],
            "items": {
              "type": "string"
            }
          },
          "profile": {
            "type": "object",
            "properties": {
              "business_name": {
                "type": "string",
                "example": "Boutique Amina"
              },
              "email": {
                "type": "string",
                "example": "contact@shop-amina.example"
              },
              "country": {
                "type": "string",
                "example": "CM"
              }
            }
          },
          "metadata": {
            "type": "object",
            "properties": {
              "vendor_id": {
                "type": "string",
                "example": "4172"
              }
            }
          },
          "callback": {
            "type": "string",
            "example": "https://example.com/connected"
          },
          "status": {
            "type": "string",
            "example": "active"
          },
          "payment_status": {
            "type": "string",
            "example": "active"
          },
          "commission_refund_policy": {
            "type": "string",
            "example": "prorata"
          },
          "slave": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "9b2f4c1e-6a3d-4e8f-b7c5-2d1e0f9a8b76"
              },
              "name": {
                "type": "string",
                "example": "Boutique Amina"
              },
              "email": {
                "type": "string",
                "example": "contact@shop-amina.example"
              }
            },
            "description": "The connected merchant."
          },
          "pricing": {
            "type": "object",
            "properties": {
              "percentage_fee": {
                "type": "number",
                "example": 2.5
              },
              "fixed_fee": {
                "type": "number",
                "example": 0
              },
              "min_fee": {
                "type": "number",
                "example": 0
              },
              "max_fee": {
                "type": "number",
                "example": 0
              },
              "currency": {
                "type": "string",
                "example": "XAF"
              }
            }
          },
          "expires_at": {
            "type": "string",
            "example": null,
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "example": "2026-08-20T10:30:00+00:00"
          },
          "updated_at": {
            "type": "string",
            "example": "2026-09-01T07:45:12+00:00"
          },
          "authorization_url": {
            "type": "string",
            "example": "https://sync.wajub.com/oauth/v2/authorize?access_token=…"
          }
        }
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "evt_Nq8rT3vK6mX2pW9cB5jL7hYs"
          },
          "event": {
            "type": "string",
            "example": "payment.succeeded"
          },
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "trx_CSUGajfv9xh0XQ5wu2lx"
              },
              "reference": {
                "type": "string",
                "example": "order-1042"
              },
              "status": {
                "type": "string",
                "example": "succeeded"
              }
            }
          },
          "livemode": {
            "type": "boolean",
            "example": true
          },
          "pending_webhooks": {
            "type": "integer",
            "example": 0
          },
          "api_version": {
            "type": "string",
            "example": "2026-10-11"
          },
          "request": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": null,
                "nullable": true
              },
              "idempotency_key": {
                "type": "string",
                "example": "idem_kZ3qP8mWvL2xR7tB5nY4hC6dF9jS1aG0"
              }
            }
          },
          "created": {
            "type": "string",
            "example": "2026-01-15T10:31:00+00:00"
          }
        }
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "9d4e7a2c-3b1f-4c8e-a6d5-2f8b7c1e0a94"
          },
          "url": {
            "type": "string",
            "example": "https://example.com/webhooks/wajub"
          },
          "description": {
            "type": "string",
            "example": "Order updates"
          },
          "events": {
            "type": "array",
            "example": [
              "payment.succeeded",
              "payment.failed",
              "refund.succeeded"
            ],
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "example": "enabled"
          },
          "active": {
            "type": "boolean",
            "example": true
          },
          "sandbox": {
            "type": "boolean",
            "example": false
          },
          "created_at": {
            "type": "string",
            "example": "2026-08-01T12:00:00+00:00"
          },
          "updated_at": {
            "type": "string",
            "example": "2026-08-01T12:00:00+00:00"
          },
          "secret": {
            "type": "string",
            "example": "whsec_…"
          }
        }
      },
      "Balance": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "example": 1325000
          },
          "available": {
            "type": "integer",
            "example": 1250000
          },
          "pending": {
            "type": "integer",
            "example": 75000
          },
          "reserved": {
            "type": "integer",
            "example": 0
          },
          "in.transit": {
            "type": "integer",
            "example": 0,
            "description": "Reserved, always `0`. Read it as `balance[\"in.transit\"]`."
          },
          "hold": {
            "type": "integer",
            "example": 0,
            "description": "Reserved, always `0`."
          },
          "disputed": {
            "type": "integer",
            "example": 0,
            "description": "Live only. Held against open disputes."
          },
          "credit": {
            "type": "integer",
            "example": 0
          },
          "currency": {
            "type": "string",
            "example": "XAF"
          },
          "environment": {
            "type": "string",
            "example": "live"
          }
        }
      },
      "Error": {
        "type": "object",
        "description": "The envelope of every refusal.",
        "properties": {
          "code": {
            "type": "integer",
            "description": "The HTTP status, repeated.",
            "example": 422
          },
          "status": {
            "type": "string",
            "description": "Its reason phrase.",
            "example": "Unprocessable Content"
          },
          "message": {
            "type": "string",
            "description": "What went wrong, in a sentence.",
            "example": "The amount field is required."
          },
          "error_code": {
            "type": "string",
            "description": "A stable code to branch on, when the refusal has one. See [Errors](/api/errors).",
            "example": "insufficient_funds"
          },
          "errors": {
            "type": "object",
            "description": "On a `422`, the messages by field; a refusal that concerns no single field is under `request`.",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "example": {
              "amount": [
                "The amount field is required."
              ]
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "default": []
    }
  ],
  "paths": {
    "/payments/options": {
      "get": {
        "summary": "List payment options.",
        "operationId": "listPaymentOptions",
        "description": "The channels a payer could use for a payment of this currency and amount, before you create it: the ones your account offers on the payment page, narrowed by `country` and by each channel's minimum and maximum. A preview: the payment itself, once created, is what the payer is offered.",
        "parameters": [
          {
            "in": "query",
            "name": "currency",
            "description": "ISO 4217 code of the payment.",
            "example": "XAF",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ISO 4217 code of the payment.",
              "example": "XAF"
            }
          },
          {
            "in": "query",
            "name": "amount",
            "description": "The amount, in the major unit.",
            "example": 25000,
            "required": true,
            "schema": {
              "type": "number",
              "description": "The amount, in the major unit.",
              "example": 25000
            }
          },
          {
            "in": "query",
            "name": "country",
            "description": "The payer's country (ISO 3166-1 alpha-2): channels of other countries are left out, cards excepted.",
            "example": "CM",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The payer's country (ISO 3166-1 alpha-2): channels of other countries are left out, cards excepted.",
              "example": "CM",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "locale",
            "description": "`fr` or `en`, the language of the names. Defaults to `en`.",
            "example": "fr",
            "required": false,
            "schema": {
              "type": "string",
              "description": "`fr` or `en`, the language of the names. Defaults to `en`.",
              "example": "fr",
              "enum": [
                "fr",
                "en"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "accept",
            "description": "The same restriction `POST /payments` takes (`countries`, `channels`, `types`, `currencies`).",
            "example": null,
            "required": false,
            "schema": {
              "type": "object",
              "description": "The same restriction `POST /payments` takes (`countries`, `channels`, `types`, `currencies`).",
              "example": null,
              "properties": {}
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Options",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Payment options retrieved",
                    "channels": [
                      {
                        "id": "cm.mobile",
                        "slug": "cm.mobile",
                        "name": "Mobile Money",
                        "name.fr": "Mobile Money",
                        "type": "mobile_money",
                        "logo": "https://cdn.wajub.com/channels/mtn.svg",
                        "countries": [
                          "CM"
                        ],
                        "operators": [
                          {
                            "slug": "cm.mtn",
                            "operator": "mtn",
                            "name": "MTN Mobile Money",
                            "logo": "https://cdn.wajub.com/channels/mtn.svg"
                          },
                          {
                            "slug": "cm.orange",
                            "operator": "orange",
                            "name": "Orange Money",
                            "logo": "https://cdn.wajub.com/channels/orange.svg"
                          }
                        ]
                      },
                      {
                        "id": "card",
                        "slug": "card",
                        "name": "Card",
                        "name.fr": "Carte",
                        "type": "card",
                        "logo": "https://cdn.wajub.com/channels/card.svg",
                        "countries": []
                      }
                    ]
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment options retrieved"
                    },
                    "channels": {
                      "type": "array",
                      "example": [
                        {
                          "id": "cm.mobile",
                          "slug": "cm.mobile",
                          "name": "Mobile Money",
                          "name.fr": "Mobile Money",
                          "type": "mobile_money",
                          "logo": "https://cdn.wajub.com/channels/mtn.svg",
                          "countries": [
                            "CM"
                          ],
                          "operators": [
                            {
                              "slug": "cm.mtn",
                              "operator": "mtn",
                              "name": "MTN Mobile Money",
                              "logo": "https://cdn.wajub.com/channels/mtn.svg"
                            },
                            {
                              "slug": "cm.orange",
                              "operator": "orange",
                              "name": "Orange Money",
                              "logo": "https://cdn.wajub.com/channels/orange.svg"
                            }
                          ]
                        },
                        {
                          "id": "card",
                          "slug": "card",
                          "name": "Card",
                          "name.fr": "Carte",
                          "type": "card",
                          "logo": "https://cdn.wajub.com/channels/card.svg",
                          "countries": []
                        }
                      ],
                      "description": "Each channel: `id`, `slug`, `name`, `name.fr`, `type`, `logo`, `countries`, and `operators` for an aggregate such as `cm.mobile`.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "cm.mobile"
                          },
                          "slug": {
                            "type": "string",
                            "example": "cm.mobile"
                          },
                          "name": {
                            "type": "string",
                            "example": "Mobile Money"
                          },
                          "name.fr": {
                            "type": "string",
                            "example": "Mobile Money"
                          },
                          "type": {
                            "type": "string",
                            "example": "mobile_money"
                          },
                          "logo": {
                            "type": "string",
                            "example": "https://cdn.wajub.com/channels/mtn.svg"
                          },
                          "countries": {
                            "type": "array",
                            "example": [
                              "CM"
                            ],
                            "items": {
                              "type": "string"
                            }
                          },
                          "operators": {
                            "type": "array",
                            "example": [
                              {
                                "slug": "cm.mtn",
                                "operator": "mtn",
                                "name": "MTN Mobile Money",
                                "logo": "https://cdn.wajub.com/channels/mtn.svg"
                              },
                              {
                                "slug": "cm.orange",
                                "operator": "orange",
                                "name": "Orange Money",
                                "logo": "https://cdn.wajub.com/channels/orange.svg"
                              }
                            ],
                            "items": {
                              "type": "object",
                              "properties": {
                                "slug": {
                                  "type": "string",
                                  "example": "cm.mtn"
                                },
                                "operator": {
                                  "type": "string",
                                  "example": "mtn"
                                },
                                "name": {
                                  "type": "string",
                                  "example": "MTN Mobile Money"
                                },
                                "logo": {
                                  "type": "string",
                                  "example": "https://cdn.wajub.com/channels/mtn.svg"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Missing amount",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "The amount field is required.",
                    "errors": {
                      "amount": [
                        "The amount field is required."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ]
      }
    },
    "/payments": {
      "get": {
        "summary": "List payments.",
        "operationId": "listPayments",
        "description": "Returns a paginated list of transactions for the authenticated account and environment. Supports both offset pagination (`per_page` + `page`) and cursor pagination (`cursor`) for large datasets. Requires the secret key.",
        "parameters": [
          {
            "in": "query",
            "name": "per_page",
            "description": "Max results per page (1–100). Defaults to 25.",
            "example": 10,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Max results per page (1–100). Defaults to 25.",
              "example": 10,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "page",
            "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
            "example": 2,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
              "example": 2
            }
          },
          {
            "in": "query",
            "name": "status",
            "description": "Filter by status. One of: `pending`, `processing`, `succeeded`, `failed`, `cancelled`, `expired`, `refunded`.",
            "example": "succeeded",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by status. One of: `pending`, `processing`, `succeeded`, `failed`, `cancelled`, `expired`, `refunded`.",
              "example": "succeeded",
              "enum": [
                "pending",
                "processing",
                "succeeded",
                "expired",
                "partial",
                "failed",
                "cancelled",
                "refunded",
                "partially_refunded"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "date_from",
            "description": "Filter from date (YYYY-MM-DD).",
            "example": "2026-01-01",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter from date (YYYY-MM-DD).",
              "example": "2026-01-01",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "date_to",
            "description": "Filter to date (YYYY-MM-DD).",
            "example": "2026-01-31",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter to date (YYYY-MM-DD).",
              "example": "2026-01-31",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "amount_min",
            "description": "Filter by minimum amount (major unit).",
            "example": 1000,
            "required": false,
            "schema": {
              "type": "number",
              "description": "Filter by minimum amount (major unit).",
              "example": 1000,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "amount_max",
            "description": "Filter by maximum amount.",
            "example": 100000,
            "required": false,
            "schema": {
              "type": "number",
              "description": "Filter by maximum amount.",
              "example": 100000,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "reference",
            "description": "The payments created with exactly this `reference`. A reference is yours and is not unique: every payment that carries it comes back.",
            "example": "order-4172",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The payments created with exactly this `reference`. A reference is yours and is not unique: every payment that carries it comes back.",
              "example": "order-4172",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
              "example": null,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "search",
            "description": "Search by reference, description or customer details.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "Search by reference, description or customer details.",
              "example": null,
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Payments retrieved",
                    "items": [
                      {
                        "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                        "reference": "order-4172",
                        "amount": 25000,
                        "amount_paid": 25000,
                        "currency": "XAF",
                        "status": "succeeded",
                        "channel": "cm.mtn",
                        "description": "Order #4172",
                        "sandbox": false,
                        "created_at": "2026-01-15T10:30:00+00:00"
                      }
                    ],
                    "meta": {
                      "current_page": 1,
                      "last_page": 3,
                      "per_page": 25,
                      "total": 68,
                      "next_cursor": "c_9fK2mQ7vB4nL6hR1xT8w",
                      "has_more": true
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payments retrieved"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Payment"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "last_page": {
                          "type": "integer",
                          "example": 3
                        },
                        "per_page": {
                          "type": "integer",
                          "example": 25
                        },
                        "total": {
                          "type": "integer",
                          "example": 68
                        },
                        "next_cursor": {
                          "type": "string",
                          "example": "c_9fK2mQ7vB4nL6hR1xT8w"
                        },
                        "has_more": {
                          "type": "boolean",
                          "example": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429,
                    "status": "Too Many Requests"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ]
      },
      "post": {
        "summary": "Create payment.",
        "operationId": "createPayment",
        "description": "Creates a pending transaction and returns a hosted payment URL (`authorization_url`). Redirect the customer to this URL to complete the payment on Wajub's hosted page. Always verify the final status server-side via `GET /payments/{id}` or by listening to the `payment.succeeded` webhook, never rely solely on the redirect URL. Marketplaces can attribute this payment to a connected subaccount via the `X-Sync` header.\n\nWith `deferred: true`, the payment is only prepared, for Wajub Components shown on a checkout before its order exists: no transaction, no `payment.created` webhook and no line in your payments until `POST /payments/{id}/activate`. The response has the same shape, with the `id` the payment keeps once activated.\n\nWith a publishable key, `customer` and the addresses hold what the request sent, never the customer your account already has with that email or phone.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "order-1042",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "201": {
            "description": "Payment initialized",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 201,
                    "status": "Created",
                    "message": "Payment initiated",
                    "authorization_url": "https://pay.wajub.com/test_7Yh2Mp4kQ9xL4vR8tB3nW6yC1dF5sJ0aG…",
                    "authorization_token": "test_7Yh2Mp4kQ9xL4vR8tB3nW6yC1dF5sJ0aG…",
                    "transaction": {
                      "id": "trx_test_CSUGajfv9xh0XQ5wu2lx",
                      "reference": "order-4172",
                      "amount": 25000,
                      "currency": "XAF",
                      "status": "pending",
                      "description": "Order #4172",
                      "sandbox": true,
                      "created_at": "2026-01-15T10:30:00+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 201
                    },
                    "status": {
                      "type": "string",
                      "example": "Created"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment initiated"
                    },
                    "authorization_url": {
                      "type": "string",
                      "example": "https://pay.wajub.com/test_7Yh2Mp4kQ9xL4vR8tB3nW6yC1dF5sJ0aG…"
                    },
                    "authorization_token": {
                      "type": "string",
                      "example": "test_7Yh2Mp4kQ9xL4vR8tB3nW6yC1dF5sJ0aG…"
                    },
                    "transaction": {
                      "$ref": "#/components/schemas/Payment"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "The given data was invalid.",
                    "errors": {
                      "amount": [
                        "The amount field is required."
                      ],
                      "currency": [
                        "The selected currency is invalid."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429,
                    "status": "Too Many Requests",
                    "message": "Too Many requests. Merchant limit : 120"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "deferred": {
                    "type": "boolean",
                    "description": "Prepare the payment without creating it, for Components shown before your order exists. The customer then comes with `POST /payments/{id}/activate`.",
                    "example": false
                  },
                  "amount": {
                    "type": "number",
                    "description": "Amount to collect in the major unit of the currency (e.g. 25000 = 25,000 XAF). Minimum: 0.01.",
                    "example": 25000
                  },
                  "currency": {
                    "type": "string",
                    "description": "ISO 4217 currency code (XAF, XOF, NGN, GHS, KES…).",
                    "example": "XAF"
                  },
                  "email": {
                    "type": "string",
                    "description": "The payer's email. One of `email`, `phone`, `customer_id` or `customer` is required, unless `deferred` is `true`.",
                    "example": "amina@example.com",
                    "nullable": true
                  },
                  "customer_id": {
                    "type": "string",
                    "description": "One of your customers, by its `cus_` id. One of `email`, `phone`, `customer_id` or `customer` is required, unless `deferred` is `true`.",
                    "example": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                    "nullable": true
                  },
                  "phone": {
                    "type": "string",
                    "description": "The payer's phone number, international format. One of `email`, `phone`, `customer_id` or `customer` is required, unless `deferred` is `true`.",
                    "example": "+237670000000",
                    "nullable": true
                  },
                  "name": {
                    "type": "string",
                    "description": "The payer's full name, shown on the payment page.",
                    "example": "Amina Diallo",
                    "nullable": true
                  },
                  "description": {
                    "type": "string",
                    "description": "A label shown to the customer on the payment page.",
                    "example": "Order #4172",
                    "nullable": true
                  },
                  "reference": {
                    "type": "string",
                    "description": "Your own reference for this payment, such as an order number (max 128 chars). Free and not unique: two payments may carry the same one. Find them with `GET /payments?reference=`; to make a retry safe, send an `Idempotency-Key` header.",
                    "example": "order-4172",
                    "nullable": true
                  },
                  "callback": {
                    "type": "string",
                    "description": "Where the customer is sent back once the payment ends, whatever the outcome, with `status` in the query string (`succeeded`, `failed`, `cancelled`, `expired`). Must be HTTPS; in sandbox, `http://localhost` and `http://127.0.0.1` are accepted too. Any other address answers `422`.",
                    "example": "https://example.com/return",
                    "nullable": true
                  },
                  "expires": {
                    "type": "object",
                    "description": "When the payment ends on its own if nobody pays it.",
                    "example": null,
                    "properties": {
                      "in": {
                        "type": "integer",
                        "description": "Session expiry in minutes (5–43200). Defaults to 1440 (24h).",
                        "example": 60,
                        "nullable": true
                      }
                    }
                  },
                  "customer": {
                    "type": "object",
                    "description": "Customer information. Not required itself: at least one of `email`, `phone`, `customer_id` or `customer` is, unless `deferred` is true.",
                    "example": null,
                    "properties": {
                      "email": {
                        "type": "string",
                        "description": "Customer email address.",
                        "example": "amina@example.com"
                      },
                      "phone": {
                        "type": "string",
                        "description": "Customer phone number (international format).",
                        "example": "+237670000000"
                      },
                      "name": {
                        "type": "string",
                        "description": "Customer full name displayed on the payment page.",
                        "example": "Amina Diallo"
                      }
                    },
                    "nullable": true
                  },
                  "theming": {
                    "type": "object",
                    "description": "Colours and logo of the payment page for this payment, over your account branding. Stored and returned; the page does not read it today.",
                    "example": null,
                    "properties": {},
                    "nullable": true
                  },
                  "address": {
                    "type": "object",
                    "description": "Accepted for older integrations and not used.",
                    "example": null,
                    "properties": {},
                    "nullable": true
                  },
                  "shipping": {
                    "type": "object",
                    "description": "Accepted for older integrations and not used.",
                    "example": null,
                    "properties": {},
                    "nullable": true
                  },
                  "items": {
                    "type": "array",
                    "description": "Lines shown on the payment page. Display only: they carry no price and never change `amount`.",
                    "example": null,
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "description": "The line's label, up to 255 characters.",
                          "example": "T-shirt",
                          "nullable": true
                        },
                        "description": {
                          "type": "string",
                          "description": "Detail shown under the label, up to 1 000 characters.",
                          "example": null,
                          "nullable": true
                        },
                        "quantity": {
                          "type": "number",
                          "description": "How many of this line, shown on the page.",
                          "example": 2,
                          "nullable": true
                        }
                      }
                    },
                    "nullable": true
                  },
                  "telemetry": {
                    "type": "object",
                    "description": "Free-form data about the integration that created the payment, such as your SDK and app versions. Kept with the payment, not returned.",
                    "example": null,
                    "properties": {},
                    "nullable": true
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Free-form key-value data attached to the transaction.",
                    "example": {
                      "order_id": "4172"
                    },
                    "properties": {},
                    "nullable": true
                  },
                  "bearer": {
                    "type": "string",
                    "description": "Who bears the platform fee: `merchant` (default) or `customer`.",
                    "example": "merchant",
                    "enum": [
                      "merchant",
                      "customer"
                    ],
                    "nullable": true
                  },
                  "accept": {
                    "type": "object",
                    "description": "What this payment may be paid with. Each list narrows the payment page and the charge; a channel outside them answers `422` `channel_not_accepted`.",
                    "example": null,
                    "properties": {
                      "countries": {
                        "type": "array",
                        "description": "Two-letter country codes: only the channels of these countries. Cards and crypto belong to no country and stay; name them under `types` or `channels` to exclude them.",
                        "example": [
                          "CM"
                        ],
                        "items": {
                          "type": "string"
                        }
                      },
                      "channels": {
                        "type": "array",
                        "description": "Only these channels: slugs such as `cm.mtn`, `cm.mobile` for every mobile operator of Cameroon, or `mobile` for every mobile operator.",
                        "example": [
                          "cm.mtn",
                          "cm.orange"
                        ],
                        "items": {
                          "type": "string"
                        }
                      },
                      "types": {
                        "type": "array",
                        "description": "Channel types accepted, such as `mobile_money` or `card`.",
                        "example": [
                          "mobile_money"
                        ],
                        "items": {
                          "type": "string"
                        }
                      },
                      "currencies": {
                        "type": "string",
                        "description": "`payment`: only channels that settle in the payment's currency. `any` or absent: no currency filter.",
                        "example": "payment",
                        "enum": [
                          "payment",
                          "any"
                        ],
                        "nullable": true
                      }
                    },
                    "nullable": true
                  }
                },
                "required": [
                  "amount",
                  "currency"
                ]
              }
            }
          }
        }
      }
    },
    "/payments/{id}/activate": {
      "post": {
        "summary": "Activate a prepared payment.",
        "operationId": "activateAPreparedPayment",
        "description": "Creates the payment prepared with `deferred: true`, once your order is placed. Call it from your server, with the secret key, while the component waits in `onBeforeSubmit`: the component charges only after this call succeeded. The payment keeps the prepared `id`, appears in your payments, and `payment.created` is sent now. `amount` and `currency` must still match the prepared payment: change them first with `PATCH /payments/{id}`. `reference` and `description` replace the ones given at preparation, when your order did not exist yet. Sending the same body again answers `200` and changes nothing. Another body on an activated payment answers `409`.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Activated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "activated": true
                  },
                  "properties": {
                    "activated": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Payment Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "Expired, cancelled, or activated with another body",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 409,
                    "status": "Conflict",
                    "message": "This payment session cannot be activated."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Total changed",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "The order total no longer matches this payment session.",
                    "errors": {
                      "amount": [
                        "The order total no longer matches this payment session."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "type": "number",
                    "description": "The order total, equal to the prepared payment's amount.",
                    "example": 12500
                  },
                  "currency": {
                    "type": "string",
                    "description": "ISO 4217 currency code, equal to the prepared payment's.",
                    "example": "XAF"
                  },
                  "customer": {
                    "type": "object",
                    "description": "The buyer, as your order recorded them. At least one of `email` or `phone`.",
                    "example": null,
                    "properties": {
                      "email": {
                        "type": "string",
                        "description": "The buyer's email address.",
                        "example": "amina@example.com",
                        "nullable": true
                      },
                      "phone": {
                        "type": "string",
                        "description": "The buyer's phone number (international format).",
                        "example": "+237670000000",
                        "nullable": true
                      },
                      "name": {
                        "type": "string",
                        "description": "The buyer's full name.",
                        "example": "Amina Diallo",
                        "nullable": true
                      }
                    }
                  },
                  "callback": {
                    "type": "string",
                    "description": "Redirect URL after payment.",
                    "example": "https://example.com/return",
                    "nullable": true
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Merged into the payment's metadata.",
                    "example": {
                      "order_id": "4172"
                    },
                    "properties": {},
                    "nullable": true
                  },
                  "reference": {
                    "type": "string",
                    "description": "Your own reference for this payment, now that the order exists (max 128 chars), as `POST /payments` takes it: free and not unique. Absent, the prepared one stays.",
                    "example": "order-4172",
                    "nullable": true
                  },
                  "description": {
                    "type": "string",
                    "description": "A label shown to the customer on the payment page (max 500 chars). Absent, the prepared one stays.",
                    "example": "Order #4172",
                    "nullable": true
                  }
                },
                "required": [
                  "amount",
                  "currency",
                  "customer"
                ]
              }
            }
          }
        }
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The prepared payment `id`.",
          "example": "trx_test_CSUGajfv9xh0XQ5wu2lx",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/payments/{id}": {
      "patch": {
        "summary": "Update a prepared payment.",
        "operationId": "updateAPreparedPayment",
        "description": "Changes the amount or currency of a payment prepared with `deferred: true`, while its checkout is still open: the buyer changed country, applied a discount, picked a delivery. One prepared payment serves the whole checkout, and the mounted Components keep their session. The new amount is checked as `POST /payments` checks it: the currency's limits, and the payment's `accept`, which must still leave a way to pay. `expires` gives the payment a new expiry, counted from now: the payment keeps it once activated. A payment that was not prepared answers `404`. A prepared payment that was activated, cancelled or has expired answers `409`. Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Payment updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Payment updated",
                    "transaction": {
                      "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                      "amount": 12500,
                      "currency": "XAF",
                      "status": "pending"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment updated"
                    },
                    "transaction": {
                      "$ref": "#/components/schemas/Payment"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not a prepared payment",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Payment Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "Activated, cancelled or expired",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 409,
                    "status": "Conflict",
                    "message": "This prepared payment can no longer change."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Validation failed",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Content",
                        "message": "The selected currency is invalid.",
                        "errors": {
                          "currency": [
                            "The selected currency is invalid."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Amount outside the currency's limits",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Entity",
                        "message": "Amount must be between 25 and 2000000 XAF.",
                        "errors": {
                          "amount": [
                            "The amount must be between 25 and 2000000 XAF."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Nothing left to pay with",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Entity",
                        "message": "No payment method is left once `accept` is applied to this payment.",
                        "errors": {
                          "accept": [
                            "No payment method is left once `accept` is applied to this payment."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "type": "number",
                    "description": "The new amount, in the major unit of the currency.",
                    "example": 12500
                  },
                  "currency": {
                    "type": "string",
                    "description": "ISO 4217 currency code.",
                    "example": "XAF"
                  },
                  "expires": {
                    "type": "object",
                    "description": "When the payment ends on its own if nobody pays it. Absent, the expiry does not change.",
                    "example": null,
                    "properties": {
                      "in": {
                        "type": "integer",
                        "description": "The new expiry in minutes from now (5–43200), as `POST /payments` takes it.",
                        "example": 120,
                        "nullable": true
                      }
                    },
                    "nullable": true
                  }
                },
                "required": [
                  "amount",
                  "currency"
                ]
              }
            }
          }
        }
      },
      "post": {
        "summary": "Charge a payment.",
        "operationId": "chargeAPayment",
        "description": "Sends a payment created with `POST /payments` to the payer's channel, from your server: the Mobile Money prompt on the payer's phone, or the charge on a bank or crypto channel. A payment collected on the hosted payment page never needs this call. Every field under `data` is also accepted at the root of the body. Card numbers are accepted in sandbox only, for test cards: live refuses raw card data.\n\nThe answer is `200` when the channel confirms at once, and `202` while it waits for the payer: the outcome then arrives by webhook. Send an `Idempotency-Key` unique to this charge: sending the same key again returns the first answer instead of charging twice.\n\nWhen the provider behind the channel needs the payer to do something first, the `202` names that step in `action` and carries what it needs: `action_url` to send the payer to for `redirect`, `otp_id` for the code to confirm for `confirm_otp`.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "charge-order-1042",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Waiting for the payer",
                      "type": "object",
                      "example": {
                        "code": 202,
                        "status": "Accepted",
                        "message": "Confirm the transaction on your phone.",
                        "transaction": {
                          "id": "trx_test_CSUGajfv9xh0XQ5wu2lx",
                          "status": "processing",
                          "amount": 5000,
                          "currency": "XAF"
                        }
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 202
                        },
                        "status": {
                          "type": "string",
                          "example": "Accepted"
                        },
                        "message": {
                          "type": "string",
                          "example": "Confirm the transaction on your phone."
                        },
                        "transaction": {
                          "$ref": "#/components/schemas/Payment"
                        }
                      }
                    },
                    {
                      "description": "The payer is sent to the provider",
                      "type": "object",
                      "example": {
                        "code": 202,
                        "status": "Accepted",
                        "message": "Open Wave to confirm your payment.",
                        "action": "redirect",
                        "transaction": {
                          "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                          "status": "processing",
                          "amount": 5000,
                          "currency": "XOF"
                        },
                        "action_url": "https://pay.wave.com/c/cos-0example00"
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 202
                        },
                        "status": {
                          "type": "string",
                          "example": "Accepted"
                        },
                        "message": {
                          "type": "string",
                          "example": "Open Wave to confirm your payment."
                        },
                        "action": {
                          "type": "string",
                          "example": "redirect",
                          "description": "The step the payer has to complete before the payment can go on: `redirect`, `confirm_otp`, `confirm_pin`, `confirm_phone`, `confirm_birthday`, `confirm_address`, `client_session`, `confirm` or `confirm_3ds`. Absent when there is none."
                        },
                        "transaction": {
                          "$ref": "#/components/schemas/Payment"
                        },
                        "action_url": {
                          "type": "string",
                          "example": "https://pay.wave.com/c/cos-0example00",
                          "description": "With `redirect`: the provider's page or app link to send the payer to."
                        }
                      }
                    },
                    {
                      "description": "The payer has a code to confirm",
                      "type": "object",
                      "example": {
                        "code": 202,
                        "status": "Accepted",
                        "message": "Enter the OTP sent to complete your payment.",
                        "action": "confirm_otp",
                        "transaction": {
                          "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                          "status": "processing",
                          "amount": 5000,
                          "currency": "GHS"
                        },
                        "otp_id": "otp_Xk4mQ8vT2nL7rB9wC3dF",
                        "otp_masked_contact": "+233 24 *** **89"
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 202
                        },
                        "status": {
                          "type": "string",
                          "example": "Accepted"
                        },
                        "message": {
                          "type": "string",
                          "example": "Enter the OTP sent to complete your payment."
                        },
                        "action": {
                          "type": "string",
                          "example": "confirm_otp",
                          "description": "The step the payer has to complete before the payment can go on: `redirect`, `confirm_otp`, `confirm_pin`, `confirm_phone`, `confirm_birthday`, `confirm_address`, `client_session`, `confirm` or `confirm_3ds`. Absent when there is none."
                        },
                        "transaction": {
                          "$ref": "#/components/schemas/Payment"
                        },
                        "otp_id": {
                          "type": "string",
                          "example": "otp_Xk4mQ8vT2nL7rB9wC3dF",
                          "description": "With `confirm_otp`: the identifier to send back with the code the payer received."
                        },
                        "otp_masked_contact": {
                          "type": "string",
                          "example": "+233 24 *** **89",
                          "description": "With `confirm_otp`: where the provider says it sent the code, when it says so."
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "402": {
            "description": "Declined, the payment is back to pending and can be charged again",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 402,
                    "status": "Payment Required",
                    "message": "Your card has insufficient funds.",
                    "error_code": "insufficient_funds",
                    "payer_message": "This payment could not be completed. Try again or use another payment method.",
                    "transaction": {
                      "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                      "status": "pending"
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payer_message": {
                          "type": "string",
                          "example": "This payment could not be completed. Try again or use another payment method.",
                          "description": "A sentence written for the payer, safe to show as it is. Present on a refusal when Wajub has one."
                        },
                        "transaction": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "example": "trx_CSUGajfv9xh0XQ5wu2lx"
                            },
                            "status": {
                              "type": "string",
                              "example": "pending"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Refused by a restriction or by Shield",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 403,
                    "status": "Forbidden",
                    "error_code": "shield_blocked",
                    "message": "Payment blocked: transaction risk score too high. Please contact support and reference BLK-7K2Q9XWD.",
                    "block_reference": "BLK-7K2Q9XWD"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "block_reference": {
                          "type": "string",
                          "example": "BLK-7K2Q9XWD"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Unknown payment",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Payment Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "A charge is already in progress",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 409,
                    "status": "Conflict",
                    "error_code": "payment_in_progress",
                    "message": "A charge is already in progress for this payment. Wait for its outcome before charging again."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Channel not accepted",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "The selected channel is invalid.",
                    "errors": {
                      "channel": [
                        "The selected channel is invalid."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "channel": {
                    "type": "string",
                    "description": "A channel slug from `GET /channels`, or `mobile` to let Wajub find the operator from the phone number.",
                    "example": "cm.mtn"
                  },
                  "data": {
                    "type": "object",
                    "description": "The payer's details for this channel. A sandbox card charge also takes `card.number` (a test card), `card.holder`, `exp` (`MM/YY` or `MM/YYYY`) and `cvc` (3 or 4 digits), keys with a dot in their name; live refuses raw card data.",
                    "example": null,
                    "properties": {
                      "phone": {
                        "type": "string",
                        "description": "Mobile Money number, in international format.",
                        "example": "+237670000000"
                      },
                      "account_number": {
                        "type": "string",
                        "description": "Account or wallet number, for channels that use one.",
                        "example": null
                      },
                      "iban": {
                        "type": "string",
                        "description": "For a bank channel.",
                        "example": null
                      },
                      "wallet_address": {
                        "type": "string",
                        "description": "For a crypto channel.",
                        "example": null
                      },
                      "save_payment_method": {
                        "type": "boolean",
                        "description": "Save this payment method on the customer for a later payment. Defaults to `false`.",
                        "example": false
                      },
                      "cvc": {
                        "type": "string",
                        "description": "Sandbox only: three or four digits.",
                        "example": "123"
                      },
                      "exp": {
                        "type": "string",
                        "description": "Sandbox only: the expiry, `MM/YY` or `MM/YYYY`, a year from this one to thirty years ahead.",
                        "example": "12/30"
                      },
                      "card": {
                        "type": "object",
                        "description": "Sandbox only: the test card, `number` and `holder`.",
                        "example": null,
                        "properties": {
                          "holder": {
                            "type": "string",
                            "description": "Sandbox only: the name on the card. `card_holder` is accepted too.",
                            "example": "Amina Diallo"
                          },
                          "number": {
                            "type": "string",
                            "description": "Sandbox only: a published test card. Its number decides the outcome.",
                            "example": "4242424242424242"
                          }
                        }
                      }
                    }
                  }
                },
                "required": [
                  "channel"
                ]
              }
            }
          }
        }
      },
      "get": {
        "summary": "Retrieve a payment.",
        "operationId": "retrieveAPayment",
        "description": "Returns a single payment by its `id`, the one `POST /payments` returned. To find payments by your own `reference`, which is not unique, list them with `GET /payments?reference=`. Always call this endpoint server-side to verify the final status before fulfilling an order. Read with a publishable key, the payment has no `customer` and no addresses, and its `payment_method` names the channel only, without the payer's number.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Payment retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Payment retrieved",
                    "transaction": {
                      "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                      "reference": "order-4172",
                      "invoice": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
                      "amount": 25000,
                      "amount_paid": 25000,
                      "currency": "XAF",
                      "status": "succeeded",
                      "description": "Order #4172",
                      "customer": {
                        "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                        "name": "Amina Diallo",
                        "email": "amina@example.com",
                        "phone": "+237670000000"
                      },
                      "payment_method": {
                        "channel": "cm.mtn",
                        "account": "+237670000000"
                      },
                      "channel": "cm.mtn",
                      "callback": "https://example.com/return",
                      "sandbox": false,
                      "items": [
                        {
                          "name": "T-shirt",
                          "quantity": 2
                        }
                      ],
                      "metadata": {
                        "order_id": "4172"
                      },
                      "tax": {
                        "amount": 4035.64,
                        "taxable_amount": 20964.36,
                        "rate": 19.25,
                        "name": "TVA",
                        "country": "CM",
                        "inclusive": true
                      },
                      "receipt_url": "https://invoice.wajub.com/r/trx_CSUGajfv9xh0XQ5wu2lx?s=9f2c4e7a1b8d3f6c0e5a2d9b7c4f1e8a3d6b0c9e2f5a8d1b4e7c0a3f6d9b2e5c",
                      "credited_at": "2026-01-15T10:31:12+00:00",
                      "created_at": "2026-01-15T10:30:00+00:00",
                      "updated_at": "2026-01-15T10:31:12+00:00",
                      "settled": true
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment retrieved"
                    },
                    "transaction": {
                      "$ref": "#/components/schemas/Payment"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Payment Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429,
                    "status": "Too Many Requests"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ]
      },
      "delete": {
        "summary": "Cancel payment.",
        "operationId": "cancelPayment",
        "description": "Cancels a `pending`, `processing` or `partial` payment, and sends `payment.cancelled`. Once cancelled, the payment cannot be restarted. A payment prepared with `deferred: true` and not activated only has its session ended: there is no transaction to cancel, and no webhook is sent. It then reads as `cancelled`. Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Payment cancelled",
                    "transaction": {
                      "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                      "status": "cancelled"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment cancelled"
                    },
                    "transaction": {
                      "$ref": "#/components/schemas/Payment"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Cannot cancel",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "message": "This payment cannot be cancelled (already completed or expired)."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Payment Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "Instalments already paid: close the payment instead",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 409,
                    "status": "Conflict",
                    "message": "Instalments of this payment were already paid: close it with POST /payments/{id}/close, keeping or refunding what was collected.",
                    "error_code": "payment_partly_paid"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The prepared payment `id`.",
          "example": "trx_test_CSUGajfv9xh0XQ5wu2lx",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/payments/{id}/splits": {
      "post": {
        "summary": "Charge the next instalment.",
        "operationId": "chargeTheNextInstalment",
        "description": "Splits a payment into 2 to 4 instalments, then charges the next one on each call, in sandbox and, on Mobile Money channels, in live. The merchant has to turn instalments on in Settings › Regional first. Takes the same `channel` and `data` as `POST /payments/{id}`.\n\nThe first call sets the plan. Each later call charges the next instalment: send it without `split_count` and `split_amounts`, or with the same plan; another plan answers `422`. The payment is `processing` while an instalment waits for the payer, `partial` between two, and `succeeded` with the last one. Each instalment is credited to your balance as it clears, with its share of the fee. A declined instalment answers `402` and is charged again by the next call; the instalments already paid stay paid. A call made while an instalment is still with the payer charges nothing and answers `202` with that instalment. To stop before the last one, close the payment (`POST /payments/{id}/close`).",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "order-1042-part-1",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Instalment confirmed at once, the payment partial",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Confirm the transaction on your phone.",
                    "transaction": {
                      "id": "trx_Rk4Wm8Zq2Lp6Xv9Tb3Nh",
                      "amount": 600000,
                      "amount_paid": 300000,
                      "currency": "XAF",
                      "status": "partial",
                      "split": {
                        "id": "splt_Jc5Ny7Qd1Hs8Mv3Ka6Wf",
                        "split_number": 1,
                        "total_splits": 2,
                        "split_currency": "XAF",
                        "amount": 300000,
                        "status": "succeeded"
                      }
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Confirm the transaction on your phone."
                    },
                    "transaction": {
                      "$ref": "#/components/schemas/Payment"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "First instalment sent to the payer",
                      "type": "object",
                      "example": {
                        "code": 202,
                        "status": "Accepted",
                        "message": "Confirm the transaction on your phone.",
                        "transaction": {
                          "id": "trx_test_Rk4Wm8Zq2Lp6Xv9Tb3Nh",
                          "amount": 600000,
                          "amount_paid": 0,
                          "currency": "XAF",
                          "status": "processing",
                          "split": {
                            "id": "splt_test_Jc5Ny7Qd1Hs8Mv3Ka6Wf",
                            "split_number": 1,
                            "total_splits": 2,
                            "split_currency": "XAF",
                            "amount": 300000,
                            "status": "processing"
                          }
                        }
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 202
                        },
                        "status": {
                          "type": "string",
                          "example": "Accepted"
                        },
                        "message": {
                          "type": "string",
                          "example": "Confirm the transaction on your phone."
                        },
                        "transaction": {
                          "$ref": "#/components/schemas/Payment"
                        }
                      }
                    },
                    {
                      "description": "An instalment is still with the payer, nothing more was charged",
                      "type": "object",
                      "example": {
                        "code": 202,
                        "status": "Accepted",
                        "message": "Instalment 2 of 2 is waiting for the payer. Nothing more was charged.",
                        "transaction": {
                          "id": "trx_Rk4Wm8Zq2Lp6Xv9Tb3Nh",
                          "status": "processing",
                          "split": {
                            "id": "splt_Pf2Gk9Wd4Rs1Lx7Mb3Nz",
                            "split_number": 2,
                            "total_splits": 2,
                            "split_currency": "XAF",
                            "amount": 300000,
                            "status": "processing"
                          }
                        }
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 202
                        },
                        "status": {
                          "type": "string",
                          "example": "Accepted"
                        },
                        "message": {
                          "type": "string",
                          "example": "Instalment 2 of 2 is waiting for the payer. Nothing more was charged."
                        },
                        "transaction": {
                          "$ref": "#/components/schemas/Payment"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "402": {
            "description": "Instalment declined, the payment back to partial",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 402,
                    "status": "Payment Required",
                    "message": "Insufficient balance.",
                    "error_code": "insufficient_funds",
                    "transaction": {
                      "id": "trx_Rk4Wm8Zq2Lp6Xv9Tb3Nh",
                      "status": "partial",
                      "split": {
                        "id": "splt_Pf2Gk9Wd4Rs1Lx7Mb3Nz",
                        "split_number": 2,
                        "total_splits": 2,
                        "split_currency": "XAF",
                        "amount": 300000,
                        "status": "failed"
                      }
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "transaction": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "example": "trx_Rk4Wm8Zq2Lp6Xv9Tb3Nh"
                            },
                            "status": {
                              "type": "string",
                              "example": "partial"
                            },
                            "split": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "example": "splt_Pf2Gk9Wd4Rs1Lx7Mb3Nz"
                                },
                                "split_number": {
                                  "type": "integer",
                                  "example": 2
                                },
                                "total_splits": {
                                  "type": "integer",
                                  "example": 2
                                },
                                "split_currency": {
                                  "type": "string",
                                  "example": "XAF"
                                },
                                "amount": {
                                  "type": "integer",
                                  "example": 300000
                                },
                                "status": {
                                  "type": "string",
                                  "example": "failed"
                                }
                              },
                              "description": "The instalment this call is about: `id`, `split_number`, `total_splits`, `split_currency`, `amount` and `status`."
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Unknown payment",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Payment Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Instalments not turned on",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Content",
                        "message": "Manual split is disabled for this merchant.",
                        "errors": {
                          "split_count": [
                            "Manual split is disabled for this merchant."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "split_count and split_amounts disagree",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Content",
                        "message": "split_count must match the number of amounts provided in split_amounts.",
                        "errors": {
                          "split_amounts": [
                            "split_count must match the number of amounts provided in split_amounts."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Another plan than the one already set",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Content",
                        "message": "This payment already has a plan of 2 instalments. Send the call without split_count and split_amounts, or with the same plan.",
                        "errors": {
                          "split_count": [
                            "This payment already has a plan of 2 instalments. Send the call without split_count and split_amounts, or with the same plan."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Not a Mobile Money channel, in live",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Content",
                        "message": "In live, instalments are charged on Mobile Money channels only.",
                        "errors": {
                          "split_count": [
                            "In live, instalments are charged on Mobile Money channels only."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "channel": {
                    "type": "string",
                    "description": "Same as `POST /payments/{id}`. In live, a Mobile Money channel.",
                    "example": "cm.mtn"
                  },
                  "data": {
                    "type": "object",
                    "description": "The payer's details for this channel.",
                    "example": null,
                    "properties": {
                      "phone": {
                        "type": "string",
                        "description": "Mobile Money number, in international format.",
                        "example": "+237670000000"
                      }
                    }
                  },
                  "split_count": {
                    "type": "integer",
                    "description": "Split into this many equal instalments: 2, 3 or 4, in whole units, the last one taking the rest. Sets the plan on the first call.",
                    "example": 2
                  },
                  "split_amounts": {
                    "type": "array",
                    "description": "Or give each instalment's amount, 2 to 4 of them, adding up to what the payer pays: `amount`, or `amount_total` when the payer bears the fee.",
                    "example": null,
                    "items": {
                      "type": "number"
                    }
                  },
                  "split_currency": {
                    "type": "string",
                    "description": "Currency of `split_amounts`, ISO 4217.",
                    "example": null
                  }
                },
                "required": [
                  "channel"
                ]
              }
            }
          }
        }
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "Payment `id`.",
          "example": "trx_test_CSUGajfv9xh0XQ5wu2lx",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/payments/{id}/confirm": {
      "post": {
        "summary": "Confirm a step of a charge.",
        "operationId": "confirmAStepOfACharge",
        "description": "Finishes, from your server, a charge that answered `202` with a step only the payer can complete: send back the identifier the charge returned for that step with what the payer gave. `otp_id` with `code` for `confirm_otp`, `pin_id` with `pin`, `phone_id` with `phone`, `birthday_id` with `birthday`, `address_id` with `address`, `city`, `state` and `zip_code`, or `client_session_id` (the charge's `client_session.id`) once the payer is back from the provider's own window. One step per call. The hosted payment page and the Components confirm on their side and never need this call.\n\nThe answer is the charge's: `200` once the payment is paid, `202` with the next step when the provider asks for another one, `402` when it refuses what was sent. A code, PIN, phone, birthday or address gets three tries per step: `attempts_remaining` says how many are left, and with none left the payment has to be charged again. Send an `Idempotency-Key`: the same key returns the first answer instead of sending the payer's code twice.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "confirm-order-1042",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Confirmed, the payment is paid",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Payment confirmed.",
                    "transaction": {
                      "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                      "status": "succeeded",
                      "amount": 5000,
                      "currency": "NGN"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment confirmed."
                    },
                    "transaction": {
                      "$ref": "#/components/schemas/Payment"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The provider asks for another step",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 202,
                    "status": "Accepted",
                    "message": "Enter the OTP sent to complete your payment.",
                    "action": "confirm_otp",
                    "transaction": {
                      "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                      "status": "processing",
                      "amount": 5000,
                      "currency": "NGN"
                    },
                    "otp_id": "otp_Xk4mQ8vT2nL7rB9wC3dF",
                    "otp_masked_contact": "+234 80 *** **89"
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 202
                    },
                    "status": {
                      "type": "string",
                      "example": "Accepted"
                    },
                    "message": {
                      "type": "string",
                      "example": "Enter the OTP sent to complete your payment."
                    },
                    "action": {
                      "type": "string",
                      "example": "confirm_otp"
                    },
                    "transaction": {
                      "$ref": "#/components/schemas/Payment"
                    },
                    "otp_id": {
                      "type": "string",
                      "example": "otp_Xk4mQ8vT2nL7rB9wC3dF"
                    },
                    "otp_masked_contact": {
                      "type": "string",
                      "example": "+234 80 *** **89"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment Required",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Refused, tries left",
                      "example": {
                        "code": 402,
                        "status": "Payment Required",
                        "message": "The provider refused this confirmation.",
                        "error_code": "invalid_otp",
                        "attempts_remaining": 2,
                        "payer_message": "This verification could not be completed. Check the information and try again.",
                        "transaction": {
                          "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                          "status": "processing"
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "attempts_remaining": {
                              "type": "integer",
                              "example": 2,
                              "description": "With a refused code, PIN, phone, birthday or address: the tries left on this step."
                            },
                            "payer_message": {
                              "type": "string",
                              "example": "This verification could not be completed. Check the information and try again."
                            },
                            "transaction": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "example": "trx_CSUGajfv9xh0XQ5wu2lx"
                                },
                                "status": {
                                  "type": "string",
                                  "example": "processing"
                                }
                              }
                            }
                          }
                        }
                      ]
                    },
                    {
                      "description": "No try left",
                      "example": {
                        "code": 402,
                        "status": "Payment Required",
                        "message": "This step had its three tries. Charge the payment again.",
                        "error_code": "max_attempts_exceeded",
                        "attempts_remaining": 0,
                        "payer_message": "This verification could not be completed. Check the information and try again.",
                        "transaction": {
                          "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                          "status": "processing"
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "attempts_remaining": {
                              "type": "integer",
                              "example": 0,
                              "description": "With a refused code, PIN, phone, birthday or address: the tries left on this step."
                            },
                            "payer_message": {
                              "type": "string",
                              "example": "This verification could not be completed. Check the information and try again."
                            },
                            "transaction": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "example": "trx_CSUGajfv9xh0XQ5wu2lx"
                                },
                                "status": {
                                  "type": "string",
                                  "example": "processing"
                                }
                              }
                            }
                          }
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Unknown payment",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Payment Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "No step of this payment has that identifier",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Entity",
                        "message": "No step of this payment is waiting on this identifier.",
                        "error_code": "otp_expired"
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "No step, or several, named",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Content",
                        "message": "Send the identifier the charge answered with: one of otp_id, pin_id, phone_id, birthday_id, address_id or client_session_id.",
                        "errors": {
                          "step": [
                            "Send the identifier the charge answered with: one of otp_id, pin_id, phone_id, birthday_id, address_id or client_session_id."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "otp_id": {
                    "type": "string",
                    "description": "With `confirm_otp`: the `otp_id` of the charge's answer.",
                    "example": "otp_Xk4mQ8vT2nL7rB9wC3dF",
                    "nullable": true
                  },
                  "code": {
                    "type": "string",
                    "description": "With `otp_id`: the code the payer received.",
                    "example": "123456",
                    "nullable": true
                  },
                  "pin_id": {
                    "type": "string",
                    "description": "With `confirm_pin`: the `pin_id` of the charge's answer.",
                    "example": null,
                    "nullable": true
                  },
                  "pin": {
                    "type": "string",
                    "description": "With `pin_id`: the card's PIN, as the payer typed it.",
                    "example": null,
                    "nullable": true
                  },
                  "phone_id": {
                    "type": "string",
                    "description": "With `confirm_phone`: the `phone_id` of the charge's answer.",
                    "example": null,
                    "nullable": true
                  },
                  "phone": {
                    "type": "string",
                    "description": "With `phone_id`: the payer's phone number.",
                    "example": null,
                    "nullable": true
                  },
                  "birthday_id": {
                    "type": "string",
                    "description": "With `confirm_birthday`: the `birthday_id` of the charge's answer.",
                    "example": null,
                    "nullable": true
                  },
                  "birthday": {
                    "type": "string",
                    "description": "With `birthday_id`: the payer's date of birth, `YYYY-MM-DD`.",
                    "example": null,
                    "nullable": true
                  },
                  "address_id": {
                    "type": "string",
                    "description": "With `confirm_address`: the `address_id` of the charge's answer.",
                    "example": null,
                    "nullable": true
                  },
                  "address": {
                    "type": "string",
                    "description": "With `address_id`: the billing street address.",
                    "example": null,
                    "nullable": true
                  },
                  "city": {
                    "type": "string",
                    "description": "With `address_id`: the billing city.",
                    "example": null,
                    "nullable": true
                  },
                  "state": {
                    "type": "string",
                    "description": "With `address_id`: the billing state or region.",
                    "example": null,
                    "nullable": true
                  },
                  "zip_code": {
                    "type": "string",
                    "description": "With `address_id`: the billing postal code.",
                    "example": null,
                    "nullable": true
                  },
                  "client_session_id": {
                    "type": "string",
                    "description": "With `client_session`: the `client_session.id` of the charge's answer, once the payer has finished in the provider's window.",
                    "example": null,
                    "nullable": true
                  },
                  "psp_transaction_id": {
                    "type": "string",
                    "description": "With `client_session_id`, for a provider whose window hands back its own payment id.",
                    "example": null,
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "Payment `id`.",
          "example": "trx_CSUGajfv9xh0XQ5wu2lx",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/payments/{id}/close": {
      "post": {
        "summary": "Close a partial payment",
        "operationId": "closeAPartialPayment",
        "description": "Ends the instalment plan of a `partial` payment before its last instalment. With `outcome: keep` the payment becomes `succeeded` for what the paid instalments collected (`amount_paid`), which is already on your balance; the unpaid instalments are dropped. With `outcome: refund` it is closed the same way and a refund of everything collected is opened at once; Wajub sends it to the numbers the instalments came from. Nothing closes a partial payment on its own. Requires the secret key. A restricted key needs `payment.write`, and `refund.write` as well with `outcome: refund`. Through `X-Sync`, the connection needs the `payments` capability, and `refunds` as well with `outcome: refund`, as `POST /refunds` takes it.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "close-order-1042",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Kept",
                      "type": "object",
                      "example": {
                        "code": 200,
                        "status": "OK",
                        "message": "Payment closed",
                        "transaction": {
                          "id": "trx_8Hc2kLm4Qp9Rs3Tv",
                          "amount": 10000,
                          "amount_paid": 5000,
                          "currency": "XAF",
                          "status": "succeeded"
                        }
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 200
                        },
                        "status": {
                          "type": "string",
                          "example": "OK"
                        },
                        "message": {
                          "type": "string",
                          "example": "Payment closed"
                        },
                        "transaction": {
                          "$ref": "#/components/schemas/Payment"
                        }
                      }
                    },
                    {
                      "description": "Refunded",
                      "type": "object",
                      "example": {
                        "code": 200,
                        "status": "OK",
                        "message": "Payment closed",
                        "transaction": {
                          "id": "trx_8Hc2kLm4Qp9Rs3Tv",
                          "amount": 10000,
                          "amount_paid": 5000,
                          "currency": "XAF",
                          "status": "succeeded"
                        },
                        "refund": {
                          "id": "rfd_3Kd9Lm2Np7Qr4Ts",
                          "amount": 5000,
                          "status": "pending"
                        }
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 200
                        },
                        "status": {
                          "type": "string",
                          "example": "OK"
                        },
                        "message": {
                          "type": "string",
                          "example": "Payment closed"
                        },
                        "transaction": {
                          "$ref": "#/components/schemas/Payment"
                        },
                        "refund": {
                          "$ref": "#/components/schemas/Refund"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Restricted key without refund.write, with outcome refund",
                      "example": {
                        "code": 403,
                        "status": "Forbidden",
                        "message": "This API key does not have permission to write refund"
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Connection without the refunds capability, with outcome refund",
                      "example": {
                        "code": 403,
                        "status": "Forbidden",
                        "message": "This Sync account does not have the 'refunds' permission."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Not a partial instalment payment",
                      "example": {
                        "code": 409,
                        "status": "Conflict",
                        "message": "Only a payment paid in part in instalments can be closed.",
                        "error_code": "payment_not_partial"
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "An instalment in flight",
                      "example": {
                        "code": 409,
                        "status": "Conflict",
                        "message": "An instalment is being charged: wait for its outcome, then close the payment.",
                        "error_code": "payment_in_progress"
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Outcome missing",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "The outcome field is required.",
                    "errors": {
                      "outcome": [
                        "The outcome field is required."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "outcome": {
                    "type": "string",
                    "description": "`keep` the instalments collected, or `refund` them.",
                    "example": "keep",
                    "enum": [
                      "keep",
                      "refund"
                    ]
                  },
                  "reason": {
                    "type": "string",
                    "description": "With `outcome: refund`, why the payment is refunded: one of the refund reasons. Defaults to `requested_by_customer`.",
                    "example": "requested_by_customer",
                    "nullable": true
                  },
                  "fees_bearer": {
                    "type": "string",
                    "description": "With `outcome: refund`, who bears the fee share of the refund: `merchant` (default) or `customer`.",
                    "example": "merchant",
                    "enum": [
                      "merchant",
                      "customer"
                    ],
                    "nullable": true
                  }
                },
                "required": [
                  "outcome"
                ]
              }
            }
          }
        }
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The payment's `id`.",
          "example": "trx_8Hc2kLm4Qp9Rs3Tv",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/payments/{id}/refunds": {
      "get": {
        "summary": "List refunds for a payment.",
        "operationId": "listRefundsForAPayment",
        "description": "Requires the secret key, as `GET /refunds` does. A restricted key needs `payment.read`, and `refund.read` as well. Through `X-Sync`, the connection needs the `payments` capability, and `refunds` as well, as `GET /refunds` takes it.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Refunds of the payment",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Refunds for payment retrieved",
                    "items": [
                      {
                        "id": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw",
                        "transaction": "trx_CSUGajfv9xh0XQ5wu2lx",
                        "reference": "refund-ord-1042",
                        "amount": 5000,
                        "currency": "XAF",
                        "fees_bearer": "merchant",
                        "fee_amount": 100,
                        "payer_amount": 5000,
                        "status": "succeeded",
                        "execution_mode": "automatic",
                        "reason": "requested_by_customer",
                        "metadata": {},
                        "ledger_balance_currency": "XAF",
                        "ledger_balance_before": 85000,
                        "ledger_balance_after": 80000,
                        "sandbox": false,
                        "created_at": "2026-09-18T09:30:12+00:00",
                        "updated_at": "2026-09-18T09:31:02+00:00"
                      }
                    ]
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Refunds for payment retrieved"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Refund"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Restricted key without refund.read",
                      "example": {
                        "code": 403,
                        "status": "Forbidden",
                        "message": "This API key does not have permission to read refund"
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Connection without the refunds capability",
                      "example": {
                        "code": 403,
                        "status": "Forbidden",
                        "message": "This Sync account does not have the 'refunds' permission."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payments"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The payment `id`.",
          "example": "trx_CSUGajfv9xh0XQ5wu2lx",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/refunds": {
      "get": {
        "summary": "List refunds.",
        "operationId": "listRefunds",
        "description": "",
        "parameters": [
          {
            "in": "query",
            "name": "per_page",
            "description": "Max results per page (1–100).",
            "example": 10,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Max results per page (1–100).",
              "example": 10,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "page",
            "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
            "example": 2,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
              "example": 2
            }
          },
          {
            "in": "query",
            "name": "status",
            "description": "Filter by status. One of: `pending`, `processing`, `succeeded`, `failed`, `cancelled`. Before API version 2026-10-12, `failed` also returns the cancelled refunds, which that version reads as `failed`.",
            "example": "failed",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by status. One of: `pending`, `processing`, `succeeded`, `failed`, `cancelled`. Before API version 2026-10-12, `failed` also returns the cancelled refunds, which that version reads as `failed`.",
              "example": "failed",
              "enum": [
                "pending",
                "processing",
                "succeeded",
                "failed",
                "cancelled"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
              "example": null,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "date_from",
            "description": "Refunds created on or after this date, `YYYY-MM-DD`.",
            "example": "2026-09-01",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Refunds created on or after this date, `YYYY-MM-DD`.",
              "example": "2026-09-01",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "date_to",
            "description": "Refunds created on or before this date, on or after `date_from`.",
            "example": "2026-09-30",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Refunds created on or before this date, on or after `date_from`.",
              "example": "2026-09-30",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "search",
            "description": "Search over the refund `id` and your reference.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "Search over the refund `id` and your reference.",
              "example": null,
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Refunds retrieved",
                    "items": [
                      {
                        "id": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw",
                        "transaction": "trx_CSUGajfv9xh0XQ5wu2lx",
                        "reference": "refund-ord-1042",
                        "amount": 5000,
                        "currency": "XAF",
                        "fees_bearer": "merchant",
                        "fee_amount": 100,
                        "payer_amount": 5000,
                        "status": "succeeded",
                        "execution_mode": "automatic",
                        "reason": "requested_by_customer",
                        "metadata": {},
                        "ledger_balance_currency": "XAF",
                        "ledger_balance_before": 85000,
                        "ledger_balance_after": 80000,
                        "sandbox": false,
                        "created_at": "2026-09-18T09:30:12+00:00",
                        "updated_at": "2026-09-18T09:31:02+00:00"
                      }
                    ],
                    "meta": {
                      "current_page": 1,
                      "last_page": 1,
                      "per_page": 25,
                      "total": 1,
                      "next_cursor": null,
                      "has_more": false
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Refunds retrieved"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Refund"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "last_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "per_page": {
                          "type": "integer",
                          "example": 25
                        },
                        "total": {
                          "type": "integer",
                          "example": 1
                        },
                        "next_cursor": {
                          "type": "string",
                          "example": null,
                          "nullable": true
                        },
                        "has_more": {
                          "type": "boolean",
                          "example": false
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Refunds"
        ]
      },
      "post": {
        "summary": "Create a refund.",
        "operationId": "createARefund",
        "description": "Initiates a full or partial refund for a `succeeded` payment. Refunds are asynchronous, listen to the `refund.succeeded` or `refund.failed` webhooks for the final status. Supports idempotency via the `Idempotency-Key` header. Marketplaces can issue this refund from a connected subaccount via the `X-Sync` header.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "refund-order-1042",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "201": {
            "description": "Refund created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 201,
                    "status": "Created",
                    "message": "Refund created successfully",
                    "refund": {
                      "id": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw",
                      "transaction": "trx_CSUGajfv9xh0XQ5wu2lx",
                      "amount": 5000,
                      "currency": "XAF",
                      "fees_bearer": "merchant",
                      "fee_amount": 100,
                      "payer_amount": 5000,
                      "status": "pending",
                      "reason": "requested_by_customer",
                      "created_at": "2026-01-15T12:00:00+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 201
                    },
                    "status": {
                      "type": "string",
                      "example": "Created"
                    },
                    "message": {
                      "type": "string",
                      "example": "Refund created successfully"
                    },
                    "refund": {
                      "$ref": "#/components/schemas/Refund"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Private key required",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "errors": {
                      "reason": [
                        "The reason field is required."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429,
                    "status": "Too Many Requests"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Refunds"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "payment": {
                    "type": "string",
                    "description": "The payment `id` (e.g. `trx_CSUGajfv9xh0XQ5wu2lx`).",
                    "example": "trx_CSUGajfv9xh0XQ5wu2lx"
                  },
                  "amount": {
                    "type": "number",
                    "description": "Amount to refund in the major currency unit. Omit for a full refund.",
                    "example": 5000,
                    "nullable": true
                  },
                  "currency": {
                    "type": "string",
                    "description": "The payment's own currency, as an ISO 4217 code. A refund is always made in the currency of its payment, so this can be omitted; any other currency answers `422`.",
                    "example": "XAF",
                    "nullable": true
                  },
                  "fees_bearer": {
                    "type": "string",
                    "description": "Who bears the payment's Wajub fee for the refunded share: `merchant` (the payer gets back everything they paid, the fee too if they paid it on top) or `customer` (the fee share is deducted, or not returned). Defaults to your refund settings, else to whoever paid the fee at payment time.",
                    "example": "merchant",
                    "enum": [
                      "merchant",
                      "customer"
                    ],
                    "nullable": true
                  },
                  "reason": {
                    "type": "string",
                    "description": "Why the payment is refunded. One of `duplicate`, `fraudulent`, `requested_by_customer`, `service_not_delivered`, `product_not_received`, `wrong_amount`, `network_error`, `transaction_error`, `customer_complaint`, `merchant_error`, `reconciliation`. Any other value answers `422`.",
                    "example": "requested_by_customer",
                    "enum": [
                      "duplicate",
                      "fraudulent",
                      "requested_by_customer",
                      "service_not_delivered",
                      "product_not_received",
                      "wrong_amount",
                      "network_error",
                      "transaction_error",
                      "customer_complaint",
                      "merchant_error",
                      "reconciliation"
                    ]
                  },
                  "reference": {
                    "type": "string",
                    "description": "Your own reference for this refund, up to 255 characters.",
                    "example": "order-1042-refund",
                    "nullable": true
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Your own key-value data. Some keys are reserved by Wajub.",
                    "example": null,
                    "properties": {},
                    "nullable": true
                  }
                },
                "required": [
                  "payment",
                  "reason"
                ]
              }
            }
          }
        }
      }
    },
    "/refunds/{id}": {
      "get": {
        "summary": "Retrieve a refund.",
        "operationId": "retrieveARefund",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Refund retrieved",
                    "refund": {
                      "id": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw",
                      "transaction": "trx_CSUGajfv9xh0XQ5wu2lx",
                      "reference": "refund-ord-1042",
                      "amount": 5000,
                      "currency": "XAF",
                      "fees_bearer": "merchant",
                      "fee_amount": 100,
                      "payer_amount": 5000,
                      "status": "succeeded",
                      "execution_mode": "automatic",
                      "reason": "requested_by_customer",
                      "metadata": {},
                      "ledger_balance_currency": "XAF",
                      "ledger_balance_before": 85000,
                      "ledger_balance_after": 80000,
                      "sandbox": false,
                      "created_at": "2026-09-18T09:30:12+00:00",
                      "updated_at": "2026-09-18T09:31:02+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Refund retrieved"
                    },
                    "refund": {
                      "$ref": "#/components/schemas/Refund"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Refunds"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "Refund identifier.",
          "example": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/transfers": {
      "get": {
        "summary": "List transfers.",
        "operationId": "listTransfers",
        "description": "Returns a paginated list of outgoing transfer payouts.",
        "parameters": [
          {
            "in": "query",
            "name": "per_page",
            "description": "Max results per page (1–100). Defaults to 25.",
            "example": 10,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Max results per page (1–100). Defaults to 25.",
              "example": 10,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "page",
            "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
            "example": 2,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
              "example": 2
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
              "example": null,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "status",
            "description": "Filter by status. One of: `pending`, `processing`, `succeeded`, `failed`, `cancelled`. Before API version 2026-10-12, `failed` also returns the cancelled transfers, which that version reads as `failed`.",
            "example": "succeeded",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by status. One of: `pending`, `processing`, `succeeded`, `failed`, `cancelled`. Before API version 2026-10-12, `failed` also returns the cancelled transfers, which that version reads as `failed`.",
              "example": "succeeded",
              "enum": [
                "pending",
                "processing",
                "succeeded",
                "failed",
                "cancelled"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "search",
            "description": "Search by reference or description.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "Search by reference or description.",
              "example": null,
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Transfers retrieved",
                    "items": [
                      {
                        "id": "po_Gv2Ks9Lp4Xr7Mw1Qt8Zn",
                        "reference": "N7vW4mX1kQ8",
                        "amount": 10000,
                        "currency": "XAF",
                        "status": "succeeded",
                        "complete": true
                      }
                    ],
                    "meta": {
                      "current_page": 1,
                      "last_page": 2,
                      "per_page": 25,
                      "total": 18,
                      "next_cursor": "c_9fK2mQ7vB4nL6hR1xT8w",
                      "has_more": true
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Transfers retrieved"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Transfer"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "last_page": {
                          "type": "integer",
                          "example": 2
                        },
                        "per_page": {
                          "type": "integer",
                          "example": 25
                        },
                        "total": {
                          "type": "integer",
                          "example": 18
                        },
                        "next_cursor": {
                          "type": "string",
                          "example": "c_9fK2mQ7vB4nL6hR1xT8w"
                        },
                        "has_more": {
                          "type": "boolean",
                          "example": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429,
                    "status": "Too Many Requests"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Transfers"
        ]
      },
      "post": {
        "summary": "Create a transfer.",
        "operationId": "createATransfer",
        "description": "Initiates a payout to a Mobile Money wallet, a phone-addressed wallet (Djamo) or another Wajub account. A bank payout goes only through a payout account added in the Dashboard, which this call cannot pay. Requires a secret key and sufficient available balance. Transfers are asynchronous, listen to `transfer.succeeded` or `transfer.failed` webhooks for the final status. Marketplaces can pay out on behalf of a connected subaccount via the `X-Sync` header.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "payout-invoice-4172",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "201": {
            "description": "Transfer initiated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 201,
                    "status": "Created",
                    "message": "Transfer initiated",
                    "transfer": {
                      "id": "po_Gv2Ks9Lp4Xr7Mw1Qt8Zn",
                      "reference": "payout-892",
                      "provider_reference": null,
                      "amount": 10000,
                      "currency": "XAF",
                      "description": "Supplier payment #892",
                      "reason": null,
                      "metadata": {
                        "vendor_id": "v_892"
                      },
                      "ledger_balance_currency": "XAF",
                      "sandbox": false,
                      "status": "processing",
                      "complete": false,
                      "source": "api",
                      "succeeded_at": null,
                      "created_at": "2026-01-15T14:00:00+00:00",
                      "updated_at": "2026-01-15T14:00:00+00:00",
                      "provider": {
                        "slug": "mtn_momo",
                        "name": "MTN MoMo"
                      },
                      "beneficiary": {
                        "id": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                        "name": "Jean Dupont",
                        "phone": "+237670000000",
                        "email": null,
                        "deleted": false
                      },
                      "payment_method": {
                        "id": "pm_Hx3Lq8Vn2Rt6Ky9Wb4Zd",
                        "account_number": null,
                        "phone": "+237670000000"
                      }
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 201
                    },
                    "status": {
                      "type": "string",
                      "example": "Created"
                    },
                    "message": {
                      "type": "string",
                      "example": "Transfer initiated"
                    },
                    "transfer": {
                      "$ref": "#/components/schemas/Transfer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Private key required",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "errors": {
                      "amount": [
                        "The amount field is required."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Rate limited",
                      "example": {
                        "code": 429,
                        "status": "Too Many Requests"
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Another live payout of the account is being processed",
                      "example": {
                        "code": 429,
                        "status": "Too Many Requests",
                        "error_code": "payout_queue_busy",
                        "message": "Another payout of this account is being processed. Retry in a few seconds."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Transfers"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "beneficiary": {
                    "description": "The recipient. Either the `id` of a saved beneficiary, sent as a string, or the recipient's details inline, as the object described below. An inline recipient is saved as a beneficiary by the call. There is no `bank_code` field.",
                    "oneOf": [
                      {
                        "type": "string",
                        "description": "The `id` of a saved beneficiary.",
                        "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "Inline form: the payee's full name.",
                            "example": "Jean Dupont"
                          },
                          "channel": {
                            "type": "string",
                            "description": "Inline form: the payout channel (e.g. `cm.mtn`, `ke.mpesa`, `ci.djamo`).",
                            "example": "cm.mtn"
                          },
                          "phone": {
                            "type": "string",
                            "description": "Inline form: Mobile Money / wallet phone number. One of `phone` and `account_number` is required.",
                            "example": "+237670000000",
                            "nullable": true
                          },
                          "account_number": {
                            "type": "string",
                            "description": "Inline form: the wallet number, or the number of the Wajub account to pay. One of `phone` and `account_number` is required.",
                            "example": null,
                            "nullable": true
                          },
                          "email": {
                            "type": "string",
                            "description": "Inline form: the payee's e-mail address.",
                            "example": null,
                            "nullable": true
                          },
                          "country_code": {
                            "type": "string",
                            "description": "Inline form: 2-letter country code.",
                            "example": null,
                            "nullable": true
                          },
                          "note": {
                            "type": "string",
                            "description": "Inline form: a note of your own, up to 500 characters.",
                            "example": null,
                            "nullable": true
                          }
                        },
                        "required": [
                          "name",
                          "channel"
                        ],
                        "description": "The recipient inline, saved as a beneficiary by the call."
                      }
                    ],
                    "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
                  },
                  "amount": {
                    "type": "number",
                    "description": "Amount to send in the major currency unit.",
                    "example": 10000
                  },
                  "currency": {
                    "type": "string",
                    "description": "ISO 4217 code. Required from API version 2026-10-12. Before it, a payout without `currency` is sent in XAF, whatever your account's currency: always send it.",
                    "example": "XAF",
                    "nullable": true
                  },
                  "description": {
                    "type": "string",
                    "description": "Descriptive label for the transfer.",
                    "example": "Supplier payment #892",
                    "nullable": true
                  },
                  "reason": {
                    "type": "string",
                    "description": "Why you pay, up to 255 characters, kept with the transfer.",
                    "example": "Supplier invoice 892",
                    "nullable": true
                  },
                  "reference": {
                    "type": "string",
                    "description": "Your own reference, up to 255 characters. Stored and returned as is, never checked for uniqueness: it does not protect against a repeated request, only the `Idempotency-Key` header does.",
                    "example": "payout-892",
                    "nullable": true
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Free-form key-value data.",
                    "example": {
                      "vendor_id": "v_892"
                    },
                    "properties": {},
                    "nullable": true
                  }
                },
                "required": [
                  "beneficiary",
                  "amount"
                ]
              }
            }
          }
        }
      }
    },
    "/transfers/batch": {
      "post": {
        "summary": "Create a batch of transfers.",
        "operationId": "createABatchOfTransfers",
        "description": "The `Idempotency-Key` header is required and unique to this batch: re-sending the same batch with the same key only sends the lines that did not go through.\n\nA batch counts against your account's payout limits. When a limit is reached, a new batch is refused whole with `422`. A retry of a batch that already sent some lines is never refused whole: the lines that went out come back as they are, and only a line still to send can be refused.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Required, and unique to this batch: re-sending the same batch with the same key only sends the lines that did not go through. Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "payout-run-2026-09-16",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "One line sent, one refused",
                      "type": "object",
                      "example": {
                        "code": 200,
                        "status": "OK",
                        "message": "Batch partially accepted",
                        "batch": {
                          "reference": "payout-run-2026-09-16",
                          "total": 2,
                          "accepted": 1,
                          "rejected": 1
                        },
                        "results": [
                          {
                            "reference": "seller-42",
                            "status": "accepted",
                            "recovered": 0,
                            "transfer": {
                              "id": "po_Gv2Ks9Lp4Xr7Mw1Qt8Zn",
                              "reference": "seller-42",
                              "amount": 12500,
                              "currency": "XAF",
                              "description": "September sales",
                              "sandbox": false,
                              "status": "processing",
                              "complete": false,
                              "source": "api",
                              "created_at": "2026-09-16T18:00:02+00:00",
                              "updated_at": "2026-09-16T18:00:02+00:00"
                            }
                          },
                          {
                            "reference": "seller-57",
                            "status": "rejected",
                            "message": "This beneficiary payment method has not been verified yet and cannot receive live payouts."
                          }
                        ]
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 200
                        },
                        "status": {
                          "type": "string",
                          "example": "OK"
                        },
                        "message": {
                          "type": "string",
                          "example": "Batch partially accepted"
                        },
                        "batch": {
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "example": "payout-run-2026-09-16"
                            },
                            "total": {
                              "type": "integer",
                              "example": 2
                            },
                            "accepted": {
                              "type": "integer",
                              "example": 1
                            },
                            "rejected": {
                              "type": "integer",
                              "example": 1
                            }
                          }
                        },
                        "results": {
                          "type": "array",
                          "example": [
                            {
                              "reference": "seller-42",
                              "status": "accepted",
                              "recovered": 0,
                              "transfer": {
                                "id": "po_Gv2Ks9Lp4Xr7Mw1Qt8Zn",
                                "reference": "seller-42",
                                "amount": 12500,
                                "currency": "XAF",
                                "description": "September sales",
                                "sandbox": false,
                                "status": "processing",
                                "complete": false,
                                "source": "api",
                                "created_at": "2026-09-16T18:00:02+00:00",
                                "updated_at": "2026-09-16T18:00:02+00:00"
                              }
                            },
                            {
                              "reference": "seller-57",
                              "status": "rejected",
                              "message": "This beneficiary payment method has not been verified yet and cannot receive live payouts."
                            }
                          ],
                          "items": {
                            "type": "object",
                            "properties": {
                              "reference": {
                                "type": "string",
                                "example": "seller-42"
                              },
                              "status": {
                                "type": "string",
                                "example": "accepted"
                              },
                              "recovered": {
                                "type": "integer",
                                "example": 0
                              },
                              "transfer": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "example": "po_Gv2Ks9Lp4Xr7Mw1Qt8Zn"
                                  },
                                  "reference": {
                                    "type": "string",
                                    "example": "seller-42"
                                  },
                                  "amount": {
                                    "type": "integer",
                                    "example": 12500
                                  },
                                  "currency": {
                                    "type": "string",
                                    "example": "XAF"
                                  },
                                  "description": {
                                    "type": "string",
                                    "example": "September sales"
                                  },
                                  "sandbox": {
                                    "type": "boolean",
                                    "example": false
                                  },
                                  "status": {
                                    "type": "string",
                                    "example": "processing"
                                  },
                                  "complete": {
                                    "type": "boolean",
                                    "example": false
                                  },
                                  "source": {
                                    "type": "string",
                                    "example": "api"
                                  },
                                  "created_at": {
                                    "type": "string",
                                    "example": "2026-09-16T18:00:02+00:00"
                                  },
                                  "updated_at": {
                                    "type": "string",
                                    "example": "2026-09-16T18:00:02+00:00"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    {
                      "description": "A seller's debt absorbed the whole line",
                      "type": "object",
                      "example": {
                        "code": 200,
                        "status": "OK",
                        "message": "Batch accepted",
                        "batch": {
                          "reference": "payout-run-2026-09-16",
                          "total": 1,
                          "accepted": 1,
                          "rejected": 0
                        },
                        "results": [
                          {
                            "reference": "seller-42",
                            "status": "recovered",
                            "recovered": 12500,
                            "transfer": null
                          }
                        ]
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 200
                        },
                        "status": {
                          "type": "string",
                          "example": "OK"
                        },
                        "message": {
                          "type": "string",
                          "example": "Batch accepted"
                        },
                        "batch": {
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "example": "payout-run-2026-09-16"
                            },
                            "total": {
                              "type": "integer",
                              "example": 1
                            },
                            "accepted": {
                              "type": "integer",
                              "example": 1
                            },
                            "rejected": {
                              "type": "integer",
                              "example": 0
                            }
                          }
                        },
                        "results": {
                          "type": "array",
                          "example": [
                            {
                              "reference": "seller-42",
                              "status": "recovered",
                              "recovered": 12500,
                              "transfer": null
                            }
                          ],
                          "items": {
                            "type": "object",
                            "properties": {
                              "reference": {
                                "type": "string",
                                "example": "seller-42"
                              },
                              "status": {
                                "type": "string",
                                "example": "recovered"
                              },
                              "recovered": {
                                "type": "integer",
                                "example": 12500
                              },
                              "transfer": {
                                "type": "string",
                                "example": null,
                                "nullable": true
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "No Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "error_code": "idempotency_key_required",
                    "message": "A batch needs an Idempotency-Key header, so that retrying it cannot pay anyone twice."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Bulk payouts restricted on this account",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 403,
                    "status": "Forbidden",
                    "error_code": "merchant_restricted",
                    "message": "Bulk payouts are currently restricted for this account. Contact support."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "No payout left this hour",
                      "type": "object",
                      "example": {
                        "message": "Too many payouts in the last hour. Please wait before sending another.",
                        "errors": {
                          "amount": [
                            "Too many payouts in the last hour. Please wait before sending another."
                          ]
                        }
                      },
                      "properties": {
                        "message": {
                          "type": "string",
                          "example": "Too many payouts in the last hour. Please wait before sending another."
                        },
                        "errors": {
                          "type": "object",
                          "properties": {
                            "amount": {
                              "type": "array",
                              "example": [
                                "Too many payouts in the last hour. Please wait before sending another."
                              ],
                              "items": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    {
                      "description": "Two lines share a reference",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Content",
                        "message": "Each line needs its own reference: two lines sharing one would share an idempotency key, and only one of them would ever be paid. (and 1 more error)",
                        "errors": {
                          "transfers.0.reference": [
                            "Each line needs its own reference: two lines sharing one would share an idempotency key, and only one of them would ever be paid."
                          ],
                          "transfers.1.reference": [
                            "Each line needs its own reference: two lines sharing one would share an idempotency key, and only one of them would ever be paid."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Another live payout of the account is being processed",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429,
                    "status": "Too Many Requests",
                    "error_code": "payout_queue_busy",
                    "message": "Another payout of this account is being processed. Retry the batch in a few seconds."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Transfers"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "transfers": {
                    "type": "array",
                    "description": "Up to 500 payouts.",
                    "example": null,
                    "items": {
                      "type": "object",
                      "properties": {
                        "beneficiary": {
                          "type": "string",
                          "description": "The beneficiary `id` (`ben_…`). A phone number or an e-mail is refused with `beneficiary_not_found`.",
                          "example": "ben_01JXXX"
                        },
                        "amount": {
                          "type": "number",
                          "description": "Within the currency's minimum and maximum, as on `POST /transfers`; a line outside them is refused with `amount_out_of_range`.",
                          "example": 12500
                        },
                        "currency": {
                          "type": "string",
                          "description": "Required from API version 2026-10-12; before, defaults to XAF.",
                          "example": "XAF",
                          "nullable": true
                        },
                        "reference": {
                          "type": "string",
                          "description": "Your own identifier for this payout, a seller or an order. Unique within the batch; it is what ties a transfer back to your records.",
                          "example": "seller-42"
                        },
                        "description": {
                          "type": "string",
                          "description": "A label for this payout, up to 255 characters.",
                          "example": "September sales",
                          "nullable": true
                        }
                      },
                      "required": [
                        "beneficiary",
                        "amount",
                        "reference"
                      ]
                    }
                  }
                },
                "required": [
                  "transfers"
                ]
              }
            }
          }
        }
      }
    },
    "/transfers/{id}": {
      "get": {
        "summary": "Retrieve a transfer.",
        "operationId": "retrieveATransfer",
        "description": "Returns a single transfer payout by its identifier.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Transfer retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Transfer retrieved",
                    "transfer": {
                      "id": "po_Gv2Ks9Lp4Xr7Mw1Qt8Zn",
                      "reference": "N7vW4mX1kQ8",
                      "amount": 10000,
                      "currency": "XAF",
                      "status": "succeeded",
                      "complete": true
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Transfer retrieved"
                    },
                    "transfer": {
                      "$ref": "#/components/schemas/Transfer"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Transfer Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Transfers"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The transfer `id` (`po_…`). A transfer is not read by its `reference`, which is not unique.",
          "example": "po_Gv2Ks9Lp4Xr7Mw1Qt8Zn",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/customers": {
      "get": {
        "summary": "List customers.",
        "operationId": "listCustomers",
        "description": "",
        "parameters": [
          {
            "in": "query",
            "name": "per_page",
            "description": "Max results per page (1–100). Defaults to 25.",
            "example": 10,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Max results per page (1–100). Defaults to 25.",
              "example": 10,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "page",
            "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
            "example": 2,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
              "example": 2
            }
          },
          {
            "in": "query",
            "name": "status",
            "description": "Filter by status (`active`, `inactive`, `blocked`).",
            "example": "active",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by status (`active`, `inactive`, `blocked`).",
              "example": "active",
              "enum": [
                "active",
                "inactive",
                "blocked"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "type",
            "description": "Filter by type (`individual`, `business`).",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by type (`individual`, `business`).",
              "example": null,
              "enum": [
                "individual",
                "business"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "country",
            "description": "Customers whose shipping or billing address is in this country, by 2-letter code.",
            "example": "CM",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Customers whose shipping or billing address is in this country, by 2-letter code.",
              "example": "CM",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
              "example": null,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "customer_group",
            "description": "Only the customers of this group.",
            "example": "wholesale",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only the customers of this group.",
              "example": "wholesale",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "search",
            "description": "Search over the name, business name, email, phone and `id`.",
            "example": "amina",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Search over the name, business name, email, phone and `id`.",
              "example": "amina",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Customers list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Customers retrieved",
                    "items": [
                      {
                        "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                        "email": "amina@example.com",
                        "name": "Amina Diallo"
                      }
                    ],
                    "meta": {
                      "current_page": 1,
                      "last_page": 16,
                      "per_page": 25,
                      "total": 156,
                      "next_cursor": "c_9fK2mQ7vB4nL6hR1xT8w",
                      "has_more": true
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Customers retrieved"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Customer"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "last_page": {
                          "type": "integer",
                          "example": 16
                        },
                        "per_page": {
                          "type": "integer",
                          "example": 25
                        },
                        "total": {
                          "type": "integer",
                          "example": 156
                        },
                        "next_cursor": {
                          "type": "string",
                          "example": "c_9fK2mQ7vB4nL6hR1xT8w"
                        },
                        "has_more": {
                          "type": "boolean",
                          "example": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Customers"
        ]
      },
      "post": {
        "summary": "Create a customer.",
        "operationId": "createACustomer",
        "description": "Creates a reusable customer profile. At least one of `email` or `phone` is required. Marketplaces can create this customer under a connected subaccount via the `X-Sync` header.\n\nWith a publishable key, a customer your account already has with that email or phone comes back as its `id` and the fields the request sent, never what your account holds.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "customer-amina-diallo",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Same email or phone as an existing customer: that customer, unchanged",
                      "type": "object",
                      "example": {
                        "code": 200,
                        "status": "OK",
                        "message": "Customer already exists for this merchant",
                        "customer": {
                          "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                          "email": "amina@example.com",
                          "name": "Amina Diallo",
                          "status": "active"
                        }
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 200
                        },
                        "status": {
                          "type": "string",
                          "example": "OK"
                        },
                        "message": {
                          "type": "string",
                          "example": "Customer already exists for this merchant"
                        },
                        "customer": {
                          "$ref": "#/components/schemas/Customer"
                        }
                      }
                    },
                    {
                      "description": "With a publishable key: the id and what the request sent",
                      "type": "object",
                      "example": {
                        "code": 200,
                        "status": "OK",
                        "message": "Customer already exists for this merchant",
                        "customer": {
                          "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                          "email": "amina@example.com"
                        }
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 200
                        },
                        "status": {
                          "type": "string",
                          "example": "OK"
                        },
                        "message": {
                          "type": "string",
                          "example": "Customer already exists for this merchant"
                        },
                        "customer": {
                          "$ref": "#/components/schemas/Customer"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Customer created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 201,
                    "status": "Created",
                    "message": "Customer created",
                    "customer": {
                      "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                      "email": "amina@example.com",
                      "name": "Amina Diallo",
                      "status": "active"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 201
                    },
                    "status": {
                      "type": "string",
                      "example": "Created"
                    },
                    "message": {
                      "type": "string",
                      "example": "Customer created"
                    },
                    "customer": {
                      "$ref": "#/components/schemas/Customer"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "With X-Sync, the email or phone of a customer outside the connection",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 409,
                    "status": "Conflict",
                    "message": "This email or phone belongs to a customer of this account outside this connection."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Neither email nor phone",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "errors": {
                      "email": [
                        "The email field is required when phone is not present."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Customers"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "description": "Profile type: `individual` (default) or `business`.",
                    "example": "individual",
                    "enum": [
                      "individual",
                      "business"
                    ],
                    "nullable": true
                  },
                  "email": {
                    "type": "string",
                    "description": "Email address. Required if `phone` is not provided.",
                    "example": "amina@example.com",
                    "nullable": true
                  },
                  "phone": {
                    "type": "string",
                    "description": "Phone number. Required if `email` is not provided.",
                    "example": "+237670000000",
                    "nullable": true
                  },
                  "phone_country": {
                    "type": "string",
                    "description": "Two-letter country code the phone number is read in when it is written without its international prefix.",
                    "example": "CM",
                    "nullable": true
                  },
                  "name": {
                    "type": "string",
                    "description": "Full name. `first_name` and `last_name` are refused: send the full name here.",
                    "example": "Amina Diallo",
                    "nullable": true
                  },
                  "company_name": {
                    "type": "string",
                    "description": "Accepted for older integrations: copied into `business_name` when that one is not sent.",
                    "example": null,
                    "nullable": true
                  },
                  "first_name": {
                    "type": "string",
                    "description": "Refused: send the full name in `name`.",
                    "example": null
                  },
                  "last_name": {
                    "type": "string",
                    "description": "Refused: send the full name in `name`.",
                    "example": null
                  },
                  "date_of_birth": {
                    "type": "string",
                    "description": "Individuals only: the date of birth, `YYYY-MM-DD`, before today.",
                    "example": "1990-04-12",
                    "nullable": true
                  },
                  "gender": {
                    "type": "string",
                    "description": "Individuals only.",
                    "example": "female",
                    "enum": [
                      "male",
                      "female",
                      "other"
                    ],
                    "nullable": true
                  },
                  "business_name": {
                    "type": "string",
                    "description": "Businesses only: the registered name. Required when `type` is `business`.",
                    "example": "Diallo Consulting SARL",
                    "nullable": true
                  },
                  "business_type": {
                    "type": "string",
                    "description": "Businesses only: the legal form or line of business, as you record it.",
                    "example": "SARL",
                    "nullable": true
                  },
                  "business_registration_number": {
                    "type": "string",
                    "description": "Businesses only: the trade register number.",
                    "example": "RC/DLA/2021/B/1234",
                    "nullable": true
                  },
                  "tax_id": {
                    "type": "string",
                    "description": "Businesses only: a tax number kept on the profile. The tax ids Tax checks are added with `POST /customers/{id}/tax_ids`.",
                    "example": "M012345678901X",
                    "nullable": true
                  },
                  "legal_representative_name": {
                    "type": "string",
                    "description": "Businesses only: who signs for the business.",
                    "example": "Amina Diallo",
                    "nullable": true
                  },
                  "legal_representative_title": {
                    "type": "string",
                    "description": "Businesses only: their title.",
                    "example": "Managing Director",
                    "nullable": true
                  },
                  "description": {
                    "type": "string",
                    "description": "Your description of the customer, up to 1 000 characters.",
                    "example": "Wholesale buyer, Douala",
                    "nullable": true
                  },
                  "notes": {
                    "type": "string",
                    "description": "Your internal notes.",
                    "example": "Prefers to pay by Mobile Money",
                    "nullable": true
                  },
                  "currency": {
                    "type": "string",
                    "description": "Preferred currency, ISO 4217.",
                    "example": "XAF",
                    "nullable": true
                  },
                  "address": {
                    "type": "object",
                    "description": "The primary shipping address.",
                    "example": null,
                    "properties": {
                      "country": {
                        "type": "string",
                        "description": "Two-letter country code.",
                        "example": "CM",
                        "nullable": true
                      },
                      "city": {
                        "type": "string",
                        "description": "City.",
                        "example": "Douala",
                        "nullable": true
                      },
                      "address_line1": {
                        "type": "string",
                        "description": "Street and number.",
                        "example": "12 Rue Joffre",
                        "nullable": true
                      },
                      "state": {
                        "type": "string",
                        "description": "State or region.",
                        "example": "Littoral",
                        "nullable": true
                      },
                      "postal_code": {
                        "type": "string",
                        "description": "Postal code, where the country has them.",
                        "example": null,
                        "nullable": true
                      },
                      "address_line2": {
                        "type": "string",
                        "description": "Building, floor or landmark.",
                        "example": "Immeuble Le Bonheur, 3e étage",
                        "nullable": true
                      }
                    },
                    "nullable": true
                  },
                  "billing": {
                    "type": "object",
                    "description": "The primary billing address, with the same fields as `address`.",
                    "example": null,
                    "properties": {
                      "country": {
                        "type": "string",
                        "description": "Two-letter country code.",
                        "example": "CM",
                        "nullable": true
                      },
                      "city": {
                        "type": "string",
                        "description": "City.",
                        "example": "Douala",
                        "nullable": true
                      },
                      "address_line1": {
                        "type": "string",
                        "description": "Street and number.",
                        "example": "12 Rue Joffre",
                        "nullable": true
                      },
                      "state": {
                        "type": "string",
                        "description": "State or region.",
                        "example": "Littoral",
                        "nullable": true
                      },
                      "postal_code": {
                        "type": "string",
                        "description": "Postal code, where the country has them.",
                        "example": null,
                        "nullable": true
                      },
                      "address_line2": {
                        "type": "string",
                        "description": "Building, floor or landmark.",
                        "example": null,
                        "nullable": true
                      }
                    },
                    "nullable": true
                  },
                  "preferred_language": {
                    "type": "string",
                    "description": "The customer's language, `fr` or `en`: invoices sent to them are written in it.",
                    "example": "fr",
                    "nullable": true
                  },
                  "preferred_currencies": {
                    "type": "array",
                    "description": "ISO 4217 codes.",
                    "example": [
                      "XAF",
                      "EUR"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "preferred_locales": {
                    "type": "array",
                    "description": "Locales such as `fr` or `en`.",
                    "example": [
                      "fr"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "customer_group": {
                    "type": "string",
                    "description": "A group name of your own, to filter the list with `customer_group`.",
                    "example": "wholesale",
                    "nullable": true
                  },
                  "tags": {
                    "type": "array",
                    "description": "Your labels, up to 50 characters each.",
                    "example": [
                      "vip",
                      "douala"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Free-form key-value data.",
                    "example": null,
                    "properties": {},
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      }
    },
    "/customers/{id}": {
      "get": {
        "summary": "Retrieve a customer.",
        "operationId": "retrieveACustomer",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Customer retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Customer retrieved",
                    "customer": {
                      "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                      "email": "amina@example.com",
                      "name": "Amina Diallo",
                      "status": "active"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Customer retrieved"
                    },
                    "customer": {
                      "$ref": "#/components/schemas/Customer"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Customers"
        ]
      },
      "put": {
        "summary": "Update a customer.",
        "operationId": "updateACustomer",
        "description": "Send only the fields you change. `name` changes only when you send it: `first_name` and `last_name` are refused, and `business_name` no longer rewrites the name of an individual.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Customer updated",
                    "customer": {
                      "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Customer updated"
                    },
                    "customer": {
                      "$ref": "#/components/schemas/Customer"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Email or phone of another customer of the account",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "message": "A customer with this email already exists.",
                    "errors": {
                      "email": [
                        "A customer with this email already exists."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Customers"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "Email address.",
                    "example": "amina@example.com",
                    "nullable": true
                  },
                  "phone": {
                    "type": "string",
                    "description": "Phone number, international format.",
                    "example": "+237670000000",
                    "nullable": true
                  },
                  "phone_country": {
                    "type": "string",
                    "description": "Two-letter country code the phone number is read in when it is written without its international prefix.",
                    "example": "CM",
                    "nullable": true
                  },
                  "name": {
                    "type": "string",
                    "description": "Full name, or the business name of a business. Changes only when you send it.",
                    "example": "Amina Diallo",
                    "nullable": true
                  },
                  "company_name": {
                    "type": "string",
                    "description": "Accepted for older integrations: copied into `business_name` when that one is not sent.",
                    "example": null,
                    "nullable": true
                  },
                  "first_name": {
                    "type": "string",
                    "description": "Refused: send the full name in `name`.",
                    "example": null
                  },
                  "last_name": {
                    "type": "string",
                    "description": "Refused: send the full name in `name`.",
                    "example": null
                  },
                  "date_of_birth": {
                    "type": "string",
                    "description": "Individuals only: the date of birth, `YYYY-MM-DD`, before today.",
                    "example": "1990-04-12",
                    "nullable": true
                  },
                  "gender": {
                    "type": "string",
                    "description": "Individuals only.",
                    "example": "female",
                    "enum": [
                      "male",
                      "female",
                      "other"
                    ],
                    "nullable": true
                  },
                  "business_name": {
                    "type": "string",
                    "description": "Businesses only: the registered name.",
                    "example": "Diallo Consulting SARL",
                    "nullable": true
                  },
                  "business_type": {
                    "type": "string",
                    "description": "Businesses only: the legal form or line of business, as you record it.",
                    "example": "SARL",
                    "nullable": true
                  },
                  "business_registration_number": {
                    "type": "string",
                    "description": "Businesses only: the trade register number.",
                    "example": "RC/DLA/2021/B/1234",
                    "nullable": true
                  },
                  "tax_id": {
                    "type": "string",
                    "description": "Businesses only: a tax number kept on the profile. The tax ids Tax checks are added with `POST /customers/{id}/tax_ids`.",
                    "example": "M012345678901X",
                    "nullable": true
                  },
                  "legal_representative_name": {
                    "type": "string",
                    "description": "Businesses only: who signs for the business.",
                    "example": "Amina Diallo",
                    "nullable": true
                  },
                  "legal_representative_title": {
                    "type": "string",
                    "description": "Businesses only: their title.",
                    "example": "Managing Director",
                    "nullable": true
                  },
                  "description": {
                    "type": "string",
                    "description": "Your description of the customer, up to 1 000 characters.",
                    "example": "Wholesale buyer, Douala",
                    "nullable": true
                  },
                  "notes": {
                    "type": "string",
                    "description": "Your internal notes.",
                    "example": "Prefers to pay by Mobile Money",
                    "nullable": true
                  },
                  "currency": {
                    "type": "string",
                    "description": "Preferred currency, ISO 4217.",
                    "example": "XAF",
                    "nullable": true
                  },
                  "address": {
                    "type": "object",
                    "description": "The primary shipping address.",
                    "example": null,
                    "properties": {
                      "country": {
                        "type": "string",
                        "description": "Two-letter country code.",
                        "example": "CM",
                        "nullable": true
                      },
                      "city": {
                        "type": "string",
                        "description": "City.",
                        "example": "Douala",
                        "nullable": true
                      },
                      "address_line1": {
                        "type": "string",
                        "description": "Street and number.",
                        "example": "12 Rue Joffre",
                        "nullable": true
                      },
                      "state": {
                        "type": "string",
                        "description": "State or region.",
                        "example": "Littoral",
                        "nullable": true
                      },
                      "postal_code": {
                        "type": "string",
                        "description": "Postal code, where the country has them.",
                        "example": null,
                        "nullable": true
                      },
                      "address_line2": {
                        "type": "string",
                        "description": "Building, floor or landmark.",
                        "example": "Immeuble Le Bonheur, 3e étage",
                        "nullable": true
                      }
                    },
                    "nullable": true
                  },
                  "billing": {
                    "type": "object",
                    "description": "The primary billing address, with the same fields as `address`.",
                    "example": null,
                    "properties": {
                      "country": {
                        "type": "string",
                        "description": "Two-letter country code.",
                        "example": "CM",
                        "nullable": true
                      },
                      "city": {
                        "type": "string",
                        "description": "City.",
                        "example": "Douala",
                        "nullable": true
                      },
                      "address_line1": {
                        "type": "string",
                        "description": "Street and number.",
                        "example": "12 Rue Joffre",
                        "nullable": true
                      },
                      "state": {
                        "type": "string",
                        "description": "State or region.",
                        "example": "Littoral",
                        "nullable": true
                      },
                      "postal_code": {
                        "type": "string",
                        "description": "Postal code, where the country has them.",
                        "example": null,
                        "nullable": true
                      },
                      "address_line2": {
                        "type": "string",
                        "description": "Building, floor or landmark.",
                        "example": null,
                        "nullable": true
                      }
                    },
                    "nullable": true
                  },
                  "preferred_language": {
                    "type": "string",
                    "description": "The customer's language, `fr` or `en`: invoices sent to them are written in it.",
                    "example": "fr",
                    "nullable": true
                  },
                  "preferred_currencies": {
                    "type": "array",
                    "description": "ISO 4217 codes.",
                    "example": [
                      "XAF",
                      "EUR"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "preferred_locales": {
                    "type": "array",
                    "description": "Locales such as `fr` or `en`.",
                    "example": [
                      "fr"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "customer_group": {
                    "type": "string",
                    "description": "A group name of your own, to filter the list with `customer_group`.",
                    "example": "wholesale",
                    "nullable": true
                  },
                  "tags": {
                    "type": "array",
                    "description": "Your labels, up to 50 characters each.",
                    "example": [
                      "vip",
                      "douala"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Free-form key-value data.",
                    "example": {
                      "crm_id": "C-1042"
                    },
                    "properties": {},
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a customer.",
        "operationId": "deleteACustomer",
        "description": "Anonymises the customer's personal data and deletes the record, in one step: if any part fails, nothing is changed and the call answers 500. A full copy is archived for 120 days, then permanently deleted. The `customer.deleted` event carries the anonymised record, and the customer's details are removed from the events already recorded, from what their deliveries stored, and from search. Their past payments keep the wallet or account number they were paid with. Repeating the call answers the same, and finishes an erasure an earlier call left incomplete. Refused with `X-Sync`: erasing a customer is the merchant's decision.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Customer deleted and anonymized"
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Customer deleted and anonymized"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "With X-Sync",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 403,
                    "status": "Forbidden",
                    "message": "A platform cannot delete a merchant's customer. Erasing a customer is the merchant's decision."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Customers"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "Customer `id`.",
          "example": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/customers/{id}/block": {
      "post": {
        "summary": "Block a customer.",
        "operationId": "blockACustomer",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Customer blocked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Customer blocked",
                    "customer": {
                      "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                      "status": "blocked",
                      "blocked": true,
                      "block_reason": "Repeated chargebacks"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Customer blocked"
                    },
                    "customer": {
                      "$ref": "#/components/schemas/Customer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Already blocked",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "message": "Customer is already blocked"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Customer Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Customers"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "description": "Why the customer is blocked, up to 500 characters, returned as `block_reason`.",
                    "example": "Repeated chargebacks",
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The customer `id`.",
          "example": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/customers/{id}/unblock": {
      "post": {
        "summary": "Unblock a customer.",
        "operationId": "unblockACustomer",
        "description": "The customer goes back to `active`.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Customer unblocked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Customer unblocked",
                    "customer": {
                      "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                      "status": "active",
                      "blocked": false
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Customer unblocked"
                    },
                    "customer": {
                      "$ref": "#/components/schemas/Customer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Not blocked",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "message": "Customer is not blocked"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Customer Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Customers"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The customer `id`.",
          "example": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/customers/{id}/activate": {
      "post": {
        "summary": "Activate a customer.",
        "operationId": "activateACustomer",
        "description": "Sets the customer to `active`, and lifts a block if there is one.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Customer activated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Customer activated",
                    "customer": {
                      "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                      "status": "active"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Customer activated"
                    },
                    "customer": {
                      "$ref": "#/components/schemas/Customer"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Customer Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Customers"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The customer `id`.",
          "example": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/customers/{id}/deactivate": {
      "post": {
        "summary": "Deactivate a customer.",
        "operationId": "deactivateACustomer",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Customer deactivated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Customer deactivated",
                    "customer": {
                      "id": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
                      "status": "inactive"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Customer deactivated"
                    },
                    "customer": {
                      "$ref": "#/components/schemas/Customer"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Customer Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Customers"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The customer `id`.",
          "example": "cus_Qe7Tb2Wn5Lr9Xc4Mv8Hk1Zs3",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/beneficiaries": {
      "get": {
        "summary": "List beneficiaries.",
        "operationId": "listBeneficiaries",
        "description": "",
        "parameters": [
          {
            "in": "query",
            "name": "per_page",
            "description": "Max per page (1–100).",
            "example": 10,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Max per page (1–100).",
              "example": 10,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "page",
            "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
            "example": 2,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
              "example": 2
            }
          },
          {
            "in": "query",
            "name": "is_active",
            "description": "Filter by active status.",
            "example": true,
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Filter by active status.",
              "example": true,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "type",
            "description": "Filter by beneficiary type: `standard`, `privileged`, or `all`. Defaults to `standard`, `privileged` beneficiaries (added from the Konsole dashboard) are only included when explicitly requested.",
            "example": "standard",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Filter by beneficiary type: `standard`, `privileged`, or `all`. Defaults to `standard`, `privileged` beneficiaries (added from the Konsole dashboard) are only included when explicitly requested.",
              "example": "standard",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
              "example": null,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "search",
            "description": "Search over the name, phone and email.",
            "example": "Dupont",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Search over the name, phone and email.",
              "example": "Dupont",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Beneficiaries retrieved",
                    "items": [
                      {
                        "id": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                        "name": "Jean Dupont",
                        "email": "jean.dupont@example.com",
                        "phone": "+237670000000",
                        "country_code": "CM",
                        "note": "Pays every Friday",
                        "metadata": {
                          "seller_id": "42"
                        },
                        "sandbox": false,
                        "is_active": true,
                        "type": "standard",
                        "created_at": "2026-09-02T08:14:22+00:00",
                        "updated_at": "2026-09-02T08:14:22+00:00",
                        "verified": true,
                        "verification": "verified",
                        "payment_method": {
                          "id": "pm_Kx7Wq2Rm9Tz4Lb8Nv3Hd",
                          "type": "mobile_money",
                          "name": "MTN Mobile Money CM"
                        }
                      }
                    ],
                    "meta": {
                      "current_page": 1,
                      "last_page": 1,
                      "per_page": 25,
                      "total": 1,
                      "next_cursor": null,
                      "has_more": false
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Beneficiaries retrieved"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Beneficiary"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "last_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "per_page": {
                          "type": "integer",
                          "example": 25
                        },
                        "total": {
                          "type": "integer",
                          "example": 1
                        },
                        "next_cursor": {
                          "type": "string",
                          "example": null,
                          "nullable": true
                        },
                        "has_more": {
                          "type": "boolean",
                          "example": false
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Beneficiaries"
        ]
      },
      "post": {
        "summary": "Create a beneficiary.",
        "operationId": "createABeneficiary",
        "description": "Save a recipient for reuse in transfers. Supports Mobile Money numbers, phone-addressed wallets (Djamo: `ci.djamo`, `sn.djamo`, the recipient's Djamo phone number) and bank accounts.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "beneficiary-seller-42",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 201,
                    "status": "Created",
                    "message": "Beneficiary created successfully",
                    "beneficiary": {
                      "id": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                      "name": "Jean Dupont",
                      "phone": "+237670000000"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 201
                    },
                    "status": {
                      "type": "string",
                      "example": "Created"
                    },
                    "message": {
                      "type": "string",
                      "example": "Beneficiary created successfully"
                    },
                    "beneficiary": {
                      "$ref": "#/components/schemas/Beneficiary"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "errors": {}
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Beneficiaries"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "channel": {
                    "type": "string",
                    "description": "Transfer channel (e.g. `cm.mtn`, `ke.mpesa`, `ci.djamo`). It tells Mobile Money, wallet and bank recipients apart: there is no `type` field.",
                    "example": "cm.mtn"
                  },
                  "name": {
                    "type": "string",
                    "description": "Recipient full name.",
                    "example": "Jean Dupont"
                  },
                  "account_number": {
                    "type": "string",
                    "description": "Bank account number, for a bank channel. One of `phone` and `account_number` is required.",
                    "example": null,
                    "nullable": true
                  },
                  "phone": {
                    "type": "string",
                    "description": "Mobile Money / Djamo phone number. One of `phone` and `account_number` is required.",
                    "example": "+237670000000",
                    "nullable": true
                  },
                  "email": {
                    "type": "string",
                    "description": "The recipient's email address.",
                    "example": "jean.dupont@example.com",
                    "nullable": true
                  },
                  "country_code": {
                    "type": "string",
                    "description": "The recipient's two-letter country code.",
                    "example": "CM",
                    "nullable": true
                  },
                  "note": {
                    "type": "string",
                    "description": "A note of your own, up to 1 000 characters.",
                    "example": "Pays every Friday",
                    "nullable": true
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Free-form key-value data.",
                    "example": {
                      "seller_id": "42"
                    },
                    "properties": {},
                    "nullable": true
                  },
                  "iban": {
                    "type": "string",
                    "description": "Recorded on the beneficiary for your own reference. A bank payout goes through a payout account added in the Dashboard, which this API cannot pay.",
                    "example": null,
                    "nullable": true
                  },
                  "swift": {
                    "type": "string",
                    "description": "Recorded with `iban`, 8 or 11 characters.",
                    "example": null,
                    "nullable": true
                  }
                },
                "required": [
                  "channel",
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/beneficiaries/{id}": {
      "get": {
        "summary": "Retrieve a beneficiary.",
        "operationId": "retrieveABeneficiary",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Beneficiary retrieved",
                    "beneficiary": {
                      "id": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                      "name": "Jean Dupont",
                      "email": "jean.dupont@example.com",
                      "phone": "+237670000000",
                      "country_code": "CM",
                      "note": "Pays every Friday",
                      "metadata": {
                        "seller_id": "42"
                      },
                      "sandbox": false,
                      "is_active": true,
                      "type": "standard",
                      "created_at": "2026-09-02T08:14:22+00:00",
                      "updated_at": "2026-09-02T08:14:22+00:00",
                      "verified": true,
                      "verification": "verified",
                      "payment_method": {
                        "id": "pm_Kx7Wq2Rm9Tz4Lb8Nv3Hd",
                        "type": "mobile_money",
                        "name": "MTN Mobile Money CM"
                      }
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Beneficiary retrieved"
                    },
                    "beneficiary": {
                      "$ref": "#/components/schemas/Beneficiary"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Beneficiaries"
        ]
      },
      "put": {
        "summary": "Update a beneficiary.",
        "operationId": "updateABeneficiary",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "beneficiary": {
                      "id": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "beneficiary": {
                      "$ref": "#/components/schemas/Beneficiary"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Beneficiaries"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Updated name.",
                    "example": "Jean-Pierre Dupont"
                  },
                  "email": {
                    "type": "string",
                    "description": "The recipient's email address.",
                    "example": "jean.dupont@example.com",
                    "nullable": true
                  },
                  "phone": {
                    "type": "string",
                    "description": "Mobile Money or wallet number, international format.",
                    "example": "+237670000001",
                    "nullable": true
                  },
                  "country_code": {
                    "type": "string",
                    "description": "The recipient's two-letter country code.",
                    "example": "CM",
                    "nullable": true
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Free-form key-value data.",
                    "example": {
                      "seller_id": "42"
                    },
                    "properties": {},
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a beneficiary.",
        "operationId": "deleteABeneficiary",
        "description": "Deletes the beneficiary: it no longer appears in transfer suggestions, and past transfers still show it.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "message": "Beneficiary deleted"
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "message": {
                      "type": "string",
                      "example": "Beneficiary deleted"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Beneficiaries"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "Beneficiary identifier.",
          "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/beneficiaries/{id}/statement": {
      "get": {
        "summary": "A beneficiary's statement.",
        "operationId": "aBeneficiarysStatement",
        "description": "",
        "parameters": [
          {
            "in": "query",
            "name": "from",
            "description": "The first day covered. Defaults to 30 days ago.",
            "example": "2026-09-01",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The first day covered. Defaults to 30 days ago.",
              "example": "2026-09-01",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "to",
            "description": "The last day covered, inclusive. Defaults to today.",
            "example": "2026-09-30",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The last day covered, inclusive. Defaults to today.",
              "example": "2026-09-30",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Statement",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Statement retrieved",
                    "statement": {
                      "beneficiary": {
                        "id": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                        "name": "Jean Dupont",
                        "deleted": false
                      },
                      "period": {
                        "from": "2026-09-01",
                        "to": "2026-09-30"
                      },
                      "totals": [
                        {
                          "currency": "XAF",
                          "paid": 37500,
                          "in_progress": 12500,
                          "failed": 0,
                          "count": 4
                        }
                      ],
                      "lines": [
                        {
                          "id": "po_01JXXX",
                          "reference": "seller-42",
                          "batch_reference": "payout-run-2026-09-16",
                          "amount": 12500,
                          "currency": "XAF",
                          "status": "succeeded",
                          "description": "September sales",
                          "created_at": "2026-09-16T08:00:04+00:00",
                          "succeeded_at": "2026-09-16T08:00:41+00:00"
                        }
                      ]
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Statement retrieved"
                    },
                    "statement": {
                      "type": "object",
                      "properties": {
                        "beneficiary": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
                            },
                            "name": {
                              "type": "string",
                              "example": "Jean Dupont"
                            },
                            "deleted": {
                              "type": "boolean",
                              "example": false
                            }
                          }
                        },
                        "period": {
                          "type": "object",
                          "properties": {
                            "from": {
                              "type": "string",
                              "example": "2026-09-01"
                            },
                            "to": {
                              "type": "string",
                              "example": "2026-09-30"
                            }
                          }
                        },
                        "totals": {
                          "type": "array",
                          "example": [
                            {
                              "currency": "XAF",
                              "paid": 37500,
                              "in_progress": 12500,
                              "failed": 0,
                              "count": 4
                            }
                          ],
                          "items": {
                            "type": "object",
                            "properties": {
                              "currency": {
                                "type": "string",
                                "example": "XAF"
                              },
                              "paid": {
                                "type": "number",
                                "example": 37500
                              },
                              "in_progress": {
                                "type": "number",
                                "example": 12500
                              },
                              "failed": {
                                "type": "number",
                                "example": 0
                              },
                              "count": {
                                "type": "integer",
                                "example": 4
                              }
                            }
                          }
                        },
                        "lines": {
                          "type": "array",
                          "example": [
                            {
                              "id": "po_01JXXX",
                              "reference": "seller-42",
                              "batch_reference": "payout-run-2026-09-16",
                              "amount": 12500,
                              "currency": "XAF",
                              "status": "succeeded",
                              "description": "September sales",
                              "created_at": "2026-09-16T08:00:04+00:00",
                              "succeeded_at": "2026-09-16T08:00:41+00:00"
                            }
                          ],
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "example": "po_01JXXX"
                              },
                              "reference": {
                                "type": "string",
                                "example": "seller-42"
                              },
                              "batch_reference": {
                                "type": "string",
                                "example": "payout-run-2026-09-16"
                              },
                              "amount": {
                                "type": "number",
                                "example": 12500
                              },
                              "currency": {
                                "type": "string",
                                "example": "XAF"
                              },
                              "status": {
                                "type": "string",
                                "example": "succeeded"
                              },
                              "description": {
                                "type": "string",
                                "example": "September sales"
                              },
                              "created_at": {
                                "type": "string",
                                "example": "2026-09-16T08:00:04+00:00"
                              },
                              "succeeded_at": {
                                "type": "string",
                                "example": "2026-09-16T08:00:41+00:00"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Beneficiaries"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The beneficiary `id`.",
          "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/beneficiaries/{id}/receivables": {
      "get": {
        "summary": "List a beneficiary's debts.",
        "operationId": "listABeneficiarysDebts",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Receivables",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Receivables retrieved",
                    "receivables": [
                      {
                        "id": "rcv_Yt6Dn2Wq9Lc4Hs7Mb1Kx",
                        "beneficiary": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                        "reference": "order-9981-refund",
                        "refund": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw",
                        "description": "Refund on order 9981",
                        "currency": "XAF",
                        "amount": 12500,
                        "recovered": 0,
                        "outstanding": 12500,
                        "status": "open",
                        "settled_at": null,
                        "created_at": "2026-09-16T11:20:45+00:00"
                      }
                    ]
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Receivables retrieved"
                    },
                    "receivables": {
                      "type": "array",
                      "example": [
                        {
                          "id": "rcv_Yt6Dn2Wq9Lc4Hs7Mb1Kx",
                          "beneficiary": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                          "reference": "order-9981-refund",
                          "refund": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw",
                          "description": "Refund on order 9981",
                          "currency": "XAF",
                          "amount": 12500,
                          "recovered": 0,
                          "outstanding": 12500,
                          "status": "open",
                          "settled_at": null,
                          "created_at": "2026-09-16T11:20:45+00:00"
                        }
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "rcv_Yt6Dn2Wq9Lc4Hs7Mb1Kx"
                          },
                          "beneficiary": {
                            "type": "string",
                            "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
                          },
                          "reference": {
                            "type": "string",
                            "example": "order-9981-refund"
                          },
                          "refund": {
                            "type": "string",
                            "example": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw"
                          },
                          "description": {
                            "type": "string",
                            "example": "Refund on order 9981"
                          },
                          "currency": {
                            "type": "string",
                            "example": "XAF"
                          },
                          "amount": {
                            "type": "integer",
                            "example": 12500
                          },
                          "recovered": {
                            "type": "integer",
                            "example": 0
                          },
                          "outstanding": {
                            "type": "integer",
                            "example": 12500
                          },
                          "status": {
                            "type": "string",
                            "example": "open"
                          },
                          "settled_at": {
                            "type": "string",
                            "example": null,
                            "nullable": true
                          },
                          "created_at": {
                            "type": "string",
                            "example": "2026-09-16T11:20:45+00:00"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Beneficiaries"
        ]
      },
      "post": {
        "summary": "Declare a debt.",
        "operationId": "declareADebt",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Same reference sent again",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Receivable already recorded",
                    "receivable": {
                      "id": "rcv_Yt6Dn2Wq9Lc4Hs7Mb1Kx",
                      "reference": "order-9981-refund",
                      "amount": 12500,
                      "outstanding": 12500,
                      "status": "open"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Receivable already recorded"
                    },
                    "receivable": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "example": "rcv_Yt6Dn2Wq9Lc4Hs7Mb1Kx"
                        },
                        "reference": {
                          "type": "string",
                          "example": "order-9981-refund"
                        },
                        "amount": {
                          "type": "integer",
                          "example": 12500
                        },
                        "outstanding": {
                          "type": "integer",
                          "example": 12500
                        },
                        "status": {
                          "type": "string",
                          "example": "open"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Debt recorded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 201,
                    "status": "Created",
                    "message": "Receivable recorded",
                    "receivable": {
                      "id": "rcv_Yt6Dn2Wq9Lc4Hs7Mb1Kx",
                      "beneficiary": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                      "reference": "order-9981-refund",
                      "refund": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw",
                      "description": "Refund on order 9981",
                      "currency": "XAF",
                      "amount": 12500,
                      "recovered": 0,
                      "outstanding": 12500,
                      "status": "open",
                      "settled_at": null,
                      "created_at": "2026-09-16T11:20:45+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 201
                    },
                    "status": {
                      "type": "string",
                      "example": "Created"
                    },
                    "message": {
                      "type": "string",
                      "example": "Receivable recorded"
                    },
                    "receivable": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "example": "rcv_Yt6Dn2Wq9Lc4Hs7Mb1Kx"
                        },
                        "beneficiary": {
                          "type": "string",
                          "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
                        },
                        "reference": {
                          "type": "string",
                          "example": "order-9981-refund"
                        },
                        "refund": {
                          "type": "string",
                          "example": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw"
                        },
                        "description": {
                          "type": "string",
                          "example": "Refund on order 9981"
                        },
                        "currency": {
                          "type": "string",
                          "example": "XAF"
                        },
                        "amount": {
                          "type": "integer",
                          "example": 12500
                        },
                        "recovered": {
                          "type": "integer",
                          "example": 0
                        },
                        "outstanding": {
                          "type": "integer",
                          "example": 12500
                        },
                        "status": {
                          "type": "string",
                          "example": "open"
                        },
                        "settled_at": {
                          "type": "string",
                          "example": null,
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "example": "2026-09-16T11:20:45+00:00"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown beneficiary",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Beneficiary Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Reference already used for another debt",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "This reference already names a different debt. Use a new reference for a new debt.",
                    "errors": {
                      "reference": [
                        "This reference already names a different debt. Use a new reference for a new debt."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Beneficiaries"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "type": "number",
                    "description": "What the seller owes back, in the major unit of `currency`.",
                    "example": 12500
                  },
                  "currency": {
                    "type": "string",
                    "description": "Defaults to XAF.",
                    "example": "XAF",
                    "nullable": true
                  },
                  "reference": {
                    "type": "string",
                    "description": "Your own identifier for this debt, usually the refunded order.",
                    "example": "order-9981-refund"
                  },
                  "refund": {
                    "type": "string",
                    "description": "The refund it comes from, if it went through Wajub.",
                    "example": "re_01JXXX",
                    "nullable": true
                  },
                  "description": {
                    "type": "string",
                    "description": "A label for the debt, up to 255 characters.",
                    "example": "Refund on order 9981",
                    "nullable": true
                  }
                },
                "required": [
                  "amount",
                  "reference"
                ]
              }
            }
          }
        }
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The beneficiary `id`.",
          "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/beneficiaries/{id}/receivables/{receivable}/settle": {
      "post": {
        "summary": "Mark a debt as recovered outside Wajub.",
        "operationId": "markADebtAsRecoveredOutsideWajub",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Settled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Receivable settled",
                    "receivable": {
                      "id": "rcv_Yt6Dn2Wq9Lc4Hs7Mb1Kx",
                      "beneficiary": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                      "reference": "order-9981-refund",
                      "refund": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw",
                      "description": "Refund on order 9981",
                      "currency": "XAF",
                      "amount": 12500,
                      "recovered": 0,
                      "outstanding": 12500,
                      "status": "settled",
                      "settled_at": "2026-09-20T15:02:10+00:00",
                      "created_at": "2026-09-16T11:20:45+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Receivable settled"
                    },
                    "receivable": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "example": "rcv_Yt6Dn2Wq9Lc4Hs7Mb1Kx"
                        },
                        "beneficiary": {
                          "type": "string",
                          "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
                        },
                        "reference": {
                          "type": "string",
                          "example": "order-9981-refund"
                        },
                        "refund": {
                          "type": "string",
                          "example": "rfd_Pm3Vc8Lx2Nq7Rb5Tk9Hw"
                        },
                        "description": {
                          "type": "string",
                          "example": "Refund on order 9981"
                        },
                        "currency": {
                          "type": "string",
                          "example": "XAF"
                        },
                        "amount": {
                          "type": "integer",
                          "example": 12500
                        },
                        "recovered": {
                          "type": "integer",
                          "example": 0
                        },
                        "outstanding": {
                          "type": "integer",
                          "example": 12500
                        },
                        "status": {
                          "type": "string",
                          "example": "settled"
                        },
                        "settled_at": {
                          "type": "string",
                          "example": "2026-09-20T15:02:10+00:00"
                        },
                        "created_at": {
                          "type": "string",
                          "example": "2026-09-16T11:20:45+00:00"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown beneficiary or debt",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Beneficiary Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Beneficiaries"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The beneficiary `id`.",
          "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "in": "path",
          "name": "receivable",
          "description": "The receivable `id`.",
          "example": "rcv_Yt6Dn2Wq9Lc4Hs7Mb1Kx",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/beneficiaries/{id}/verify": {
      "post": {
        "summary": "Verify a beneficiary.",
        "operationId": "verifyABeneficiary",
        "description": "Asks the operator whose name the beneficiary's wallet is registered under, and compares it with the name you declared.\n\nOn most accounts the answer is information. A payable beneficiary stays payable whatever it is, the call answers `200`, and `registered_name` carries the name the operator holds. `verification` is `verified` when the names match, `name_mismatch` when they do not, and `lookup_unavailable` when the operator could not be asked: it offers no lookup on this channel, it did not answer, it does not know the number, or the key is a sandbox key, since sandbox has no operator. A beneficiary with no payout destination to check answers `422` with `not_found`. A beneficiary left unverified (a seller the operator could not confirm while the account was on Relay) becomes payable when the names match, under the operator's name.\n\nOn an account whose beneficiaries must be verified before they are paid, a Sync Relay platform, the same check decides. A beneficiary already verified is returned as it is, anything other than `verified` answers `422` and leaves the beneficiary unpayable, and `registered_name` is not returned. In sandbox such an account's beneficiaries are created verified, and the call answers `verified` without asking anyone.\n\nThe call has its own ceiling on every plan: 10 checks a minute and 200 a day per account in live, 10 a minute in sandbox. Past it the answer is `429`.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "The names match",
                      "type": "object",
                      "example": {
                        "code": 200,
                        "status": "OK",
                        "message": "The name registered with the operator matches this beneficiary.",
                        "verification": "verified",
                        "registered_name": "Ada Mbarga"
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 200
                        },
                        "status": {
                          "type": "string",
                          "example": "OK"
                        },
                        "message": {
                          "type": "string",
                          "example": "The name registered with the operator matches this beneficiary."
                        },
                        "verification": {
                          "type": "string",
                          "example": "verified",
                          "description": "`verified` when the operator's name matches the declared one, `name_mismatch` when it does not, `lookup_unavailable` when the operator could not be asked. A `422` carries anything other than `verified` on an account whose beneficiaries must be verified, or `not_found` when the beneficiary has no payout destination to check. Enum: verified, name_mismatch, lookup_unavailable, not_found."
                        },
                        "registered_name": {
                          "type": "string",
                          "example": "Ada Mbarga",
                          "description": "The name the operator holds for the number. Absent when the operator could not be asked, and on an account whose beneficiaries must be verified before they are paid."
                        }
                      }
                    },
                    {
                      "description": "Another name, for information",
                      "type": "object",
                      "example": {
                        "code": 200,
                        "status": "OK",
                        "message": "The operator holds this number under another name. The beneficiary can still be paid.",
                        "verification": "name_mismatch",
                        "registered_name": "Paul Nkolo",
                        "beneficiary": {
                          "id": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                          "name": "Ada Mbarga",
                          "verified": true,
                          "verification": "name_mismatch"
                        }
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 200
                        },
                        "status": {
                          "type": "string",
                          "example": "OK"
                        },
                        "message": {
                          "type": "string",
                          "example": "The operator holds this number under another name. The beneficiary can still be paid."
                        },
                        "verification": {
                          "type": "string",
                          "example": "name_mismatch",
                          "description": "`verified` when the operator's name matches the declared one, `name_mismatch` when it does not, `lookup_unavailable` when the operator could not be asked. A `422` carries anything other than `verified` on an account whose beneficiaries must be verified, or `not_found` when the beneficiary has no payout destination to check. Enum: verified, name_mismatch, lookup_unavailable, not_found."
                        },
                        "registered_name": {
                          "type": "string",
                          "example": "Paul Nkolo",
                          "description": "The name the operator holds for the number. Absent when the operator could not be asked, and on an account whose beneficiaries must be verified before they are paid."
                        },
                        "beneficiary": {
                          "$ref": "#/components/schemas/Beneficiary"
                        }
                      }
                    },
                    {
                      "description": "The operator could not be asked",
                      "type": "object",
                      "example": {
                        "code": 200,
                        "status": "OK",
                        "message": "The operator could not be asked about this number. The beneficiary can still be paid.",
                        "verification": "lookup_unavailable"
                      },
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": 200
                        },
                        "status": {
                          "type": "string",
                          "example": "OK"
                        },
                        "message": {
                          "type": "string",
                          "example": "The operator could not be asked about this number. The beneficiary can still be paid."
                        },
                        "verification": {
                          "type": "string",
                          "example": "lookup_unavailable",
                          "description": "`verified` when the operator's name matches the declared one, `name_mismatch` when it does not, `lookup_unavailable` when the operator could not be asked. A `422` carries anything other than `verified` on an account whose beneficiaries must be verified, or `not_found` when the beneficiary has no payout destination to check. Enum: verified, name_mismatch, lookup_unavailable, not_found."
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Verification required, names differ",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Content",
                        "message": "The name registered with the operator does not match this beneficiary.",
                        "errors": {
                          "request": [
                            "The name registered with the operator does not match this beneficiary."
                          ]
                        },
                        "verification": "name_mismatch",
                        "beneficiary": {
                          "id": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                          "name": "Ada Mbarga",
                          "verified": false,
                          "verification": "name_mismatch"
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "verification": {
                              "type": "string",
                              "example": "name_mismatch",
                              "description": "`verified` when the operator's name matches the declared one, `name_mismatch` when it does not, `lookup_unavailable` when the operator could not be asked. A `422` carries anything other than `verified` on an account whose beneficiaries must be verified, or `not_found` when the beneficiary has no payout destination to check. Enum: verified, name_mismatch, lookup_unavailable, not_found."
                            },
                            "beneficiary": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
                                },
                                "name": {
                                  "type": "string",
                                  "example": "Ada Mbarga"
                                },
                                "verified": {
                                  "type": "boolean",
                                  "example": false
                                },
                                "verification": {
                                  "type": "string",
                                  "example": "name_mismatch"
                                }
                              }
                            }
                          }
                        }
                      ]
                    },
                    {
                      "description": "No payout destination to check",
                      "example": {
                        "code": 422,
                        "status": "Unprocessable Content",
                        "message": "This beneficiary has no payout destination to verify.",
                        "errors": {
                          "request": [
                            "This beneficiary has no payout destination to verify."
                          ]
                        },
                        "verification": "not_found",
                        "beneficiary": {
                          "id": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
                          "name": "Ada Mbarga"
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "verification": {
                              "type": "string",
                              "example": "not_found",
                              "description": "`verified` when the operator's name matches the declared one, `name_mismatch` when it does not, `lookup_unavailable` when the operator could not be asked. A `422` carries anything other than `verified` on an account whose beneficiaries must be verified, or `not_found` when the beneficiary has no payout destination to check. Enum: verified, name_mismatch, lookup_unavailable, not_found."
                            },
                            "beneficiary": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv"
                                },
                                "name": {
                                  "type": "string",
                                  "example": "Ada Mbarga"
                                }
                              }
                            }
                          }
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Ceiling of the name check reached",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429,
                    "status": "Too Many Requests",
                    "message": "Too Many requests. Merchant limit : IP",
                    "retry_after": 60
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "retry_after": {
                          "type": "integer",
                          "example": 60
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Beneficiaries"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "Beneficiary identifier.",
          "example": "ben_Fw8Qa3Zr6Ty1Np5Jd2Lv",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/balance": {
      "get": {
        "summary": "Retrieve balance.",
        "operationId": "retrieveBalance",
        "description": "Returns the available, pending and reserved balance held by our licensed payment partner. Requires a **secret key**. The figures can be up to 3 minutes old: read the balance before each transfer batch.",
        "parameters": [
          {
            "in": "query",
            "name": "currency",
            "description": "ISO 4217 code to convert the balance to. Defaults to your account currency.",
            "example": "XAF",
            "required": false,
            "schema": {
              "type": "string",
              "description": "ISO 4217 code to convert the balance to. Defaults to your account currency.",
              "example": "XAF",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Balance retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Balance retrieved",
                    "balance": {
                      "total": 1325000,
                      "available": 1250000,
                      "pending": 75000,
                      "reserved": 0,
                      "in.transit": 0,
                      "hold": 0,
                      "disputed": 0,
                      "credit": 0,
                      "currency": "XAF",
                      "environment": "live"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Balance retrieved"
                    },
                    "balance": {
                      "$ref": "#/components/schemas/Balance"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Private key required",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429,
                    "status": "Too Many Requests"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Balance"
        ]
      }
    },
    "/events": {
      "get": {
        "summary": "List events.",
        "operationId": "listEvents",
        "description": "Returns a paginated list of the events your webhook endpoints can receive. Use this to replay events, audit activity, or debug failed deliveries. With `X-Sync`, only the events of the payments, refunds, transfers, disputes, links, invoices and beneficiaries that connection brought.",
        "parameters": [
          {
            "in": "query",
            "name": "per_page",
            "description": "Max results per page (1–100). Defaults to 25.",
            "example": 10,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Max results per page (1–100). Defaults to 25.",
              "example": 10,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "page",
            "description": "Page number.",
            "example": 1,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Page number.",
              "example": 1,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "type",
            "description": "Only events of this type: one an endpoint receives, as the webhook events catalogue lists them. Anything else is a 422.",
            "example": "payment.succeeded",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only events of this type: one an endpoint receives, as the webhook events catalogue lists them. Anything else is a 422.",
              "example": "payment.succeeded",
              "enum": [
                "account.change_accepted",
                "account.change_declined",
                "account.change_requested",
                "account.commission_receivable_collected",
                "account.commission_receivable_recorded",
                "account.connected",
                "account.created",
                "account.deauthorized",
                "account.onboarding_account_selected",
                "account.onboarding_email_verified",
                "account.onboarding_kyc_submitted",
                "account.onboarding_started",
                "account.payment_activated",
                "account.payment_suspended",
                "account.updated",
                "balance.updated",
                "beneficiary.created",
                "beneficiary.deleted",
                "beneficiary.receivable_recorded",
                "beneficiary.receivable_recovered",
                "beneficiary.updated",
                "compliance.changes_requested",
                "compliance.inquiry.created",
                "compliance.inquiry.resolved",
                "compliance.rejected",
                "compliance.submitted",
                "compliance.verified",
                "customer.created",
                "customer.deleted",
                "customer.updated",
                "dispute.closed",
                "dispute.created",
                "dispute.deadline_approaching",
                "dispute.deleted",
                "dispute.lost",
                "dispute.updated",
                "dispute.won",
                "fee.charged",
                "fee.received",
                "invoice.cancelled",
                "invoice.created",
                "invoice.deleted",
                "invoice.paid",
                "invoice.payment_succeeded",
                "invoice.sent",
                "invoice.updated",
                "link.created",
                "link.deleted",
                "link.updated",
                "payment.attempt_failed",
                "payment.cancelled",
                "payment.created",
                "payment.expired",
                "payment.failed",
                "payment.processing",
                "payment.split.failed",
                "payment.split.processing",
                "payment.split.succeeded",
                "payment.succeeded",
                "provider.activated",
                "provider.channel_activated",
                "provider.channel_deactivated",
                "provider.deactivated",
                "refund.cancelled",
                "refund.created",
                "refund.failed",
                "refund.processing",
                "refund.succeeded",
                "refund.updated",
                "transfer.cancelled",
                "transfer.created",
                "transfer.failed",
                "transfer.processing",
                "transfer.succeeded",
                "webhook_endpoint.created",
                "webhook_endpoint.deleted",
                "webhook_endpoint.updated"
              ],
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Events list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Events retrieved",
                    "events": [
                      {
                        "id": "evt_Nq8rT3vK6mX2pW9cB5jL7hYs",
                        "event": "payment.succeeded",
                        "data": {
                          "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                          "reference": "order-1042",
                          "status": "succeeded"
                        },
                        "livemode": true,
                        "pending_webhooks": 0,
                        "api_version": "2026-10-11",
                        "request": {
                          "id": null,
                          "idempotency_key": "idem_kZ3qP8mWvL2xR7tB5nY4hC6dF9jS1aG0"
                        },
                        "created": "2026-01-15T10:31:00+00:00"
                      }
                    ],
                    "meta": {
                      "current_page": 1,
                      "last_page": 9,
                      "per_page": 25,
                      "total": 328
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Events retrieved"
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Event"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "last_page": {
                          "type": "integer",
                          "example": 9
                        },
                        "per_page": {
                          "type": "integer",
                          "example": 25
                        },
                        "total": {
                          "type": "integer",
                          "example": 328
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Events"
        ]
      }
    },
    "/events/{id}": {
      "get": {
        "summary": "Retrieve an event.",
        "operationId": "retrieveAnEvent",
        "description": "Returns a single event by its identifier.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Event retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Event retrieved",
                    "event": {
                      "id": "evt_Nq8rT3vK6mX2pW9cB5jL7hYs",
                      "event": "payment.succeeded",
                      "data": {
                        "id": "trx_CSUGajfv9xh0XQ5wu2lx",
                        "reference": "order-1042",
                        "status": "succeeded"
                      },
                      "livemode": true,
                      "pending_webhooks": 0,
                      "api_version": "2026-10-11",
                      "request": {
                        "id": null,
                        "idempotency_key": "idem_kZ3qP8mWvL2xR7tB5nY4hC6dF9jS1aG0"
                      },
                      "created": "2026-01-15T10:31:00+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Event retrieved"
                    },
                    "event": {
                      "$ref": "#/components/schemas/Event"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Events"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The event `id`.",
          "example": "evt_Nq8rT3vK6mX2pW9cB5jL7hYs",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/events/{id}/resend": {
      "post": {
        "summary": "Resend an event.",
        "operationId": "resendAnEvent",
        "description": "Sends the event again to every active endpoint subscribed to it that has not accepted it yet, each getting its next attempt. An endpoint that already accepted it is not sent it again: when they all have, the call still answers `202` and sends nothing. Useful for replaying failed or missed deliveries.\n\nWith `X-Sync`, the event goes to your own endpoints, as your copy of it (the one carrying `data.account`), never to the connected merchant's.",
        "parameters": [],
        "responses": {
          "202": {
            "description": "Queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 202,
                    "status": "Accepted",
                    "message": "Event re-delivery queued."
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 202
                    },
                    "status": {
                      "type": "string",
                      "example": "Accepted"
                    },
                    "message": {
                      "type": "string",
                      "example": "Event re-delivery queued."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Events"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The event `id`.",
          "example": "evt_Nq8rT3vK6mX2pW9cB5jL7hYs",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/webhooks": {
      "get": {
        "summary": "List webhook endpoints.",
        "operationId": "listWebhookEndpoints",
        "description": "",
        "parameters": [
          {
            "in": "query",
            "name": "per_page",
            "description": "Max results per page.",
            "example": 10,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Max results per page.",
              "example": 10,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "page",
            "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
            "example": 2,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
              "example": 2
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
              "example": null,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "search",
            "description": "Search over the URL and description.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "Search over the URL and description.",
              "example": null,
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Webhook endpoints retrieved",
                    "items": [
                      {
                        "id": "9d4e7a2c-3b1f-4c8e-a6d5-2f8b7c1e0a94",
                        "url": "https://example.com/webhooks/wajub",
                        "description": "Order updates",
                        "events": [
                          "payment.succeeded",
                          "payment.failed",
                          "refund.succeeded"
                        ],
                        "status": "enabled",
                        "active": true,
                        "sandbox": false,
                        "created_at": "2026-08-01T12:00:00+00:00",
                        "updated_at": "2026-08-01T12:00:00+00:00"
                      }
                    ],
                    "meta": {
                      "current_page": 1,
                      "last_page": 1,
                      "per_page": 25,
                      "total": 1,
                      "next_cursor": null,
                      "has_more": false
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Webhook endpoints retrieved"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpoint"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "last_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "per_page": {
                          "type": "integer",
                          "example": 25
                        },
                        "total": {
                          "type": "integer",
                          "example": 1
                        },
                        "next_cursor": {
                          "type": "string",
                          "example": null,
                          "nullable": true
                        },
                        "has_more": {
                          "type": "boolean",
                          "example": false
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Webhook Endpoints"
        ]
      },
      "post": {
        "summary": "Create a webhook endpoint.",
        "operationId": "createAWebhookEndpoint",
        "description": "Subscribe to one or more event types. Wajub sends a signed `POST` request to your URL each time a matching event fires.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "endpoint-orders-prod",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 201,
                    "endpoint": {
                      "id": "9d4e7a2c-3b1f-4c8e-a6d5-2f8b7c1e0a94",
                      "url": "https://example.com/webhooks/wajub",
                      "secret": "whsec_…",
                      "events": [
                        "payment.succeeded"
                      ]
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 201
                    },
                    "endpoint": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Invalid URL",
                      "example": {
                        "code": 422,
                        "errors": {
                          "url": [
                            "The url must be a valid URL."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "URL already registered",
                      "example": {
                        "code": 422,
                        "errors": {
                          "url": [
                            "A webhook endpoint with this URL already exists."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Private address",
                      "example": {
                        "code": 422,
                        "errors": {
                          "url": [
                            "The url must not point to a private or internal IP address."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Webhook Endpoints"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Your endpoint URL, up to 2048 characters. It must use https:// with a live key; a sandbox key also accepts http://. The URL must resolve to a public internet address: a private or internal address is refused, and so is a URL already registered in this environment. For a local test, use `wajub listen`.",
                    "example": "https://example.com/webhooks/wajub"
                  },
                  "events": {
                    "type": "array",
                    "description": "Event types to subscribe to, at least one; `*` for every type. Names are not checked: copy them from the event catalog.",
                    "example": [
                      "payment.succeeded",
                      "transfer.succeeded"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional description, up to 500 characters.",
                    "example": "Production endpoint",
                    "nullable": true
                  }
                },
                "required": [
                  "url",
                  "events"
                ]
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}": {
      "get": {
        "summary": "Retrieve a webhook endpoint.",
        "operationId": "retrieveAWebhookEndpoint",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Webhook endpoint retrieved",
                    "endpoint": {
                      "id": "9d4e7a2c-3b1f-4c8e-a6d5-2f8b7c1e0a94",
                      "url": "https://example.com/webhooks/wajub",
                      "description": "Order updates",
                      "events": [
                        "payment.succeeded",
                        "payment.failed",
                        "refund.succeeded"
                      ],
                      "status": "enabled",
                      "active": true,
                      "sandbox": false,
                      "created_at": "2026-08-01T12:00:00+00:00",
                      "updated_at": "2026-08-01T12:00:00+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Webhook endpoint retrieved"
                    },
                    "endpoint": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Webhook Endpoints"
        ]
      },
      "put": {
        "summary": "Update a webhook endpoint.",
        "operationId": "updateAWebhookEndpoint",
        "description": "Send only what changes.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "endpoint": {
                      "id": "9d4e7a2c-3b1f-4c8e-a6d5-2f8b7c1e0a94"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "endpoint": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Empty event list",
                      "example": {
                        "code": 422,
                        "errors": {
                          "events": [
                            "The events field must have at least 1 items."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "URL already registered",
                      "example": {
                        "code": 422,
                        "errors": {
                          "url": [
                            "A webhook endpoint with this URL already exists."
                          ]
                        }
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Webhook Endpoints"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Updated URL, under the same rules as on creation: https:// in live, no private or internal address, not a URL another endpoint of this environment already has.",
                    "example": "https://example.com/webhooks/v2",
                    "nullable": true
                  },
                  "events": {
                    "type": "array",
                    "description": "Replaces the whole list of event types. At least one: an empty list is refused.",
                    "example": null,
                    "items": {
                      "type": "string"
                    }
                  },
                  "description": {
                    "type": "string",
                    "description": "Updated description.",
                    "example": null,
                    "nullable": true
                  },
                  "active": {
                    "type": "boolean",
                    "description": "`false` disables the endpoint: nothing more is delivered to it, and the retries already queued for it are abandoned. `true` enables it again.",
                    "example": false,
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a webhook endpoint.",
        "operationId": "deleteAWebhookEndpoint",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "message": "Webhook endpoint deleted."
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "message": {
                      "type": "string",
                      "example": "Webhook endpoint deleted."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Webhook Endpoints"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "Endpoint identifier.",
          "example": "9d4e7a2c-3b1f-4c8e-a6d5-2f8b7c1e0a94",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/webhooks/{id}/rotate-secret": {
      "post": {
        "summary": "Rotate webhook secret.",
        "operationId": "rotateWebhookSecret",
        "description": "Generates a new signing secret (`whsec_…`) for this endpoint. Update your signature verification immediately, the old secret is invalidated.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "endpoint": {
                      "id": "9d4e7a2c-3b1f-4c8e-a6d5-2f8b7c1e0a94",
                      "secret": "whsec_newvalue"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "endpoint": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Webhook Endpoints"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "Endpoint identifier.",
          "example": "9d4e7a2c-3b1f-4c8e-a6d5-2f8b7c1e0a94",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/channels": {
      "get": {
        "summary": "List channels.",
        "operationId": "listChannels",
        "description": "Every payment channel Wajub supports, the same list for every key. What your own account can take is `GET /providers`.",
        "parameters": [
          {
            "in": "query",
            "name": "country",
            "description": "Only the channels of this country, by its ISO 3166-1 alpha-2 code, in any case. A code Wajub does not know is a 422.",
            "example": "CM",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only the channels of this country, by its ISO 3166-1 alpha-2 code, in any case. A code Wajub does not know is a 422.",
              "example": "CM",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "locale",
            "description": "`en` (default) or `fr`, for `name` and `desc`.",
            "example": "fr",
            "required": false,
            "schema": {
              "type": "string",
              "description": "`en` (default) or `fr`, for `name` and `desc`.",
              "example": "fr"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Channels list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Channels retrieved",
                    "items": [
                      {
                        "id": "chn.T5wJ2hV9kM3r",
                        "uid": "chn.T5wJ2hV9kM3r",
                        "slug": "cm.mtn",
                        "name": "MTN Mobile Money CM",
                        "desc": "",
                        "type": "mobile_money",
                        "countries": [
                          "CM"
                        ],
                        "currency": "XAF",
                        "logo": "https://assets.wajub.com/img/channels/momo.svg",
                        "active": true,
                        "live": true,
                        "min_amount": null,
                        "max_amount": null,
                        "charge": true,
                        "collect": true,
                        "payout": true
                      }
                    ]
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Channels retrieved"
                    },
                    "items": {
                      "type": "array",
                      "example": [
                        {
                          "id": "chn.T5wJ2hV9kM3r",
                          "uid": "chn.T5wJ2hV9kM3r",
                          "slug": "cm.mtn",
                          "name": "MTN Mobile Money CM",
                          "desc": "",
                          "type": "mobile_money",
                          "countries": [
                            "CM"
                          ],
                          "currency": "XAF",
                          "logo": "https://assets.wajub.com/img/channels/momo.svg",
                          "active": true,
                          "live": true,
                          "min_amount": null,
                          "max_amount": null,
                          "charge": true,
                          "collect": true,
                          "payout": true
                        }
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "chn.T5wJ2hV9kM3r"
                          },
                          "uid": {
                            "type": "string",
                            "example": "chn.T5wJ2hV9kM3r"
                          },
                          "slug": {
                            "type": "string",
                            "example": "cm.mtn"
                          },
                          "name": {
                            "type": "string",
                            "example": "MTN Mobile Money CM"
                          },
                          "desc": {
                            "type": "string",
                            "example": ""
                          },
                          "type": {
                            "type": "string",
                            "example": "mobile_money"
                          },
                          "countries": {
                            "type": "array",
                            "example": [
                              "CM"
                            ],
                            "items": {
                              "type": "string"
                            }
                          },
                          "currency": {
                            "type": "string",
                            "example": "XAF",
                            "description": "Reads XAF for every channel, not the channel's own currency. Removed from API version 2026-10-12."
                          },
                          "logo": {
                            "type": "string",
                            "example": "https://assets.wajub.com/img/channels/momo.svg"
                          },
                          "active": {
                            "type": "boolean",
                            "example": true
                          },
                          "live": {
                            "type": "boolean",
                            "example": true,
                            "description": "Whether a provider a merchant can connect carries the channel, so that it can be charged outside sandbox."
                          },
                          "min_amount": {
                            "type": "string",
                            "example": null,
                            "description": "The smallest payment on this channel, in its major unit, when the catalogue sets one."
                          },
                          "max_amount": {
                            "type": "string",
                            "example": null,
                            "description": "The largest payment on this channel, in its major unit, when the catalogue sets one."
                          },
                          "charge": {
                            "type": "boolean",
                            "example": true,
                            "description": "Whether `POST /payments/{id}` can charge the channel."
                          },
                          "collect": {
                            "type": "boolean",
                            "example": true
                          },
                          "payout": {
                            "type": "boolean",
                            "example": true
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Channels"
        ]
      }
    },
    "/countries": {
      "get": {
        "summary": "List countries.",
        "operationId": "listCountries",
        "description": "",
        "parameters": [
          {
            "in": "query",
            "name": "locale",
            "description": "`en` (default) or `fr`, for `name`.",
            "example": "fr",
            "required": false,
            "schema": {
              "type": "string",
              "description": "`en` (default) or `fr`, for `name`.",
              "example": "fr"
            }
          },
          {
            "in": "query",
            "name": "region",
            "description": "Only the countries of this region, in any case. Anything else is a 422.",
            "example": "Africa",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only the countries of this region, in any case. Anything else is a 422.",
              "example": "Africa",
              "enum": [
                "Africa",
                "Americas",
                "Antarctic",
                "Asia",
                "Europe",
                "Oceania"
              ],
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Countries list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Countries retrieved",
                    "items": [
                      {
                        "code": "CM",
                        "alpha3": "CMR",
                        "name": "Cameroon",
                        "phone_code": "+237",
                        "currency_code": "XAF",
                        "flag": "🇨🇲",
                        "region": "Africa"
                      }
                    ]
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Countries retrieved"
                    },
                    "items": {
                      "type": "array",
                      "example": [
                        {
                          "code": "CM",
                          "alpha3": "CMR",
                          "name": "Cameroon",
                          "phone_code": "+237",
                          "currency_code": "XAF",
                          "flag": "🇨🇲",
                          "region": "Africa"
                        }
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string",
                            "example": "CM"
                          },
                          "alpha3": {
                            "type": "string",
                            "example": "CMR"
                          },
                          "name": {
                            "type": "string",
                            "example": "Cameroon"
                          },
                          "phone_code": {
                            "type": "string",
                            "example": "+237"
                          },
                          "currency_code": {
                            "type": "string",
                            "example": "XAF"
                          },
                          "flag": {
                            "type": "string",
                            "example": "🇨🇲"
                          },
                          "region": {
                            "type": "string",
                            "example": "Africa"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Countries"
        ]
      }
    },
    "/currencies": {
      "get": {
        "summary": "List currencies.",
        "operationId": "listCurrencies",
        "description": "",
        "parameters": [
          {
            "in": "query",
            "name": "type",
            "description": "Which currencies to list, in any case. Defaults to `fiat`. Anything else is a 422.",
            "example": "fiat",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Which currencies to list, in any case. Defaults to `fiat`. Anything else is a 422.",
              "example": "fiat",
              "enum": [
                "fiat",
                "crypto",
                "all"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Currencies list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Currencies retrieved",
                    "items": [
                      {
                        "code": "XAF",
                        "name": "CFA Franc BEAC",
                        "symbol": "FCFA",
                        "precision": 0,
                        "is_crypto": false
                      }
                    ]
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Currencies retrieved"
                    },
                    "items": {
                      "type": "array",
                      "example": [
                        {
                          "code": "XAF",
                          "name": "CFA Franc BEAC",
                          "symbol": "FCFA",
                          "precision": 0,
                          "is_crypto": false
                        }
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string",
                            "example": "XAF"
                          },
                          "name": {
                            "type": "string",
                            "example": "CFA Franc BEAC"
                          },
                          "symbol": {
                            "type": "string",
                            "example": "FCFA"
                          },
                          "precision": {
                            "type": "integer",
                            "example": 0
                          },
                          "is_crypto": {
                            "type": "boolean",
                            "example": false
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Currencies"
        ]
      }
    },
    "/invoices": {
      "get": {
        "summary": "List invoices (live only, document_type = invoice).",
        "operationId": "listInvoicesliveOnlyDocumentTypeInvoice",
        "description": "Requires the secret key.",
        "parameters": [
          {
            "in": "query",
            "name": "customer_id",
            "description": "One of your customers, by its `cus_` id.",
            "example": "cus_7Kq2mX9vL4tRb3nP8sZcWd1e",
            "required": false,
            "schema": {
              "type": "string",
              "description": "One of your customers, by its `cus_` id.",
              "example": "cus_7Kq2mX9vL4tRb3nP8sZcWd1e"
            }
          },
          {
            "in": "query",
            "name": "amount_min",
            "description": "Lower bound on `total`, in the major unit, as `total` reads. Each invoice is compared in its own currency.",
            "example": 10000,
            "required": false,
            "schema": {
              "type": "number",
              "description": "Lower bound on `total`, in the major unit, as `total` reads. Each invoice is compared in its own currency.",
              "example": 10000,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "amount_max",
            "description": "Upper bound on `total`, in the major unit.",
            "example": 500000,
            "required": false,
            "schema": {
              "type": "number",
              "description": "Upper bound on `total`, in the major unit.",
              "example": 500000,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
              "example": null
            }
          },
          {
            "in": "query",
            "name": "per_page",
            "description": "Results per page, 1 to 100. Defaults to 25.",
            "example": 10,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Results per page, 1 to 100. Defaults to 25.",
              "example": 10,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "page",
            "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
            "example": 2,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
              "example": 2
            }
          },
          {
            "in": "query",
            "name": "search",
            "description": "Search over the name and email written on the invoice.",
            "example": "amina",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Search over the name and email written on the invoice.",
              "example": "amina"
            }
          },
          {
            "in": "query",
            "name": "status",
            "description": "Only invoices in this status.",
            "example": "sent",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only invoices in this status.",
              "example": "sent",
              "enum": [
                "draft",
                "sent",
                "viewed",
                "partial",
                "paid",
                "overdue",
                "cancelled",
                "refunded"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "sort_by",
            "description": "The field to order by. Defaults to `created_at`. Any order other than `created_at` `desc` is paged by number: `cursor` is ignored and `meta` has neither `next_cursor` nor `has_more`.",
            "example": "due_date",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The field to order by. Defaults to `created_at`. Any order other than `created_at` `desc` is paged by number: `cursor` is ignored and `meta` has neither `next_cursor` nor `has_more`.",
              "example": "due_date",
              "enum": [
                "created_at",
                "invoice_date",
                "due_date",
                "total",
                "amount_paid",
                "status"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "sort_dir",
            "description": "The direction of the order. Defaults to `desc`.",
            "example": "asc",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The direction of the order. Defaults to `desc`.",
              "example": "asc",
              "enum": [
                "asc",
                "desc"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "payment_status",
            "description": "Only invoices paid this far, read from `amount_paid` against `total`.",
            "example": "unpaid",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only invoices paid this far, read from `amount_paid` against `total`.",
              "example": "unpaid",
              "enum": [
                "unpaid",
                "partially_paid",
                "fully_paid"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "date_from",
            "description": "Lower bound on `invoice_date`, a date.",
            "example": "2026-09-01",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Lower bound on `invoice_date`, a date.",
              "example": "2026-09-01",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "date_to",
            "description": "Upper bound on `invoice_date`, a date on or after `date_from`.",
            "example": "2026-09-30",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Upper bound on `invoice_date`, a date on or after `date_from`.",
              "example": "2026-09-30",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "due_date_from",
            "description": "Lower bound on `due_date`, a date.",
            "example": "2026-10-01",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Lower bound on `due_date`, a date.",
              "example": "2026-10-01",
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "due_date_to",
            "description": "Upper bound on `due_date`, a date on or after `due_date_from`.",
            "example": "2026-10-31",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Upper bound on `due_date`, a date on or after `due_date_from`.",
              "example": "2026-10-31",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoices",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Invoices retrieved",
                    "items": [
                      {
                        "id": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
                        "invoice_number": "INV-2026-0001",
                        "document_type": "invoice",
                        "status": "sent",
                        "customer": null,
                        "customer_id": null,
                        "customer_name": "Amina Diallo",
                        "customer_email": "amina@example.com",
                        "customer_company_name": null,
                        "customer_phone": null,
                        "customer_address": null,
                        "invoice_date": "2026-09-16",
                        "due_date": "2026-09-30",
                        "currency": "XAF",
                        "language": "fr",
                        "subtotal": 50000,
                        "discount_amount": 0,
                        "tax_amount": 0,
                        "total": 50000,
                        "amount_paid": 0,
                        "amount_due": 50000,
                        "payment_type": "full",
                        "is_recurring": false,
                        "recurring_interval": null,
                        "next_invoice_date": null,
                        "recurring_parent": null,
                        "notes": null,
                        "terms": null,
                        "footer": null,
                        "accept": null,
                        "sent_at": "2026-09-16T10:15:37+00:00",
                        "paid_at": null,
                        "cancelled_at": null,
                        "items": [
                          {
                            "id": "9d3f6a2e-4b1c-4e8a-9f27-6c5d8b1a0e43",
                            "name": "Website design",
                            "description": null,
                            "quantity": 1,
                            "unit": null,
                            "unit_price": 50000,
                            "tax_rate": 0,
                            "tax_amount": 0,
                            "discount_type": null,
                            "discount_value": 0,
                            "discount_amount": 0,
                            "subtotal": 50000,
                            "total": 50000,
                            "sort_order": 0
                          }
                        ],
                        "created_at": "2026-09-16T09:12:04+00:00",
                        "updated_at": "2026-09-16T10:15:37+00:00"
                      }
                    ],
                    "meta": {
                      "current_page": 1,
                      "last_page": 1,
                      "per_page": 25,
                      "total": 1,
                      "next_cursor": null,
                      "has_more": false
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invoices retrieved"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Invoice"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "last_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "per_page": {
                          "type": "integer",
                          "example": 25
                        },
                        "total": {
                          "type": "integer",
                          "example": 1
                        },
                        "next_cursor": {
                          "type": "string",
                          "example": null,
                          "nullable": true
                        },
                        "has_more": {
                          "type": "boolean",
                          "example": false
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Invoices"
        ]
      },
      "post": {
        "summary": "Create an invoice.",
        "operationId": "createAnInvoice",
        "description": "The invoice is created as a `draft`, with no `invoice_number`: the number is drawn when you send it. Live only, on a plan that includes invoicing, within the plan's invoice quota. Requires the secret key.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "invoice-order-1042",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "201": {
            "description": "Draft created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 201,
                    "status": "Created",
                    "message": "Invoice created",
                    "invoice": {
                      "id": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
                      "invoice_number": null,
                      "document_type": "invoice",
                      "status": "draft",
                      "customer": null,
                      "customer_id": null,
                      "customer_name": "Amina Diallo",
                      "customer_email": "amina@example.com",
                      "customer_company_name": null,
                      "customer_phone": null,
                      "customer_address": null,
                      "invoice_date": "2026-09-16",
                      "due_date": "2026-09-30",
                      "currency": "XAF",
                      "language": "fr",
                      "subtotal": 50000,
                      "discount_amount": 0,
                      "tax_amount": 0,
                      "total": 50000,
                      "amount_paid": 0,
                      "amount_due": 50000,
                      "payment_type": "full",
                      "is_recurring": false,
                      "recurring_interval": null,
                      "next_invoice_date": null,
                      "recurring_parent": null,
                      "notes": null,
                      "terms": null,
                      "footer": null,
                      "accept": null,
                      "sent_at": null,
                      "paid_at": null,
                      "cancelled_at": null,
                      "items": [
                        {
                          "id": "9d3f6a2e-4b1c-4e8a-9f27-6c5d8b1a0e43",
                          "name": "Website design",
                          "description": null,
                          "quantity": 1,
                          "unit": null,
                          "unit_price": 50000,
                          "tax_rate": 0,
                          "tax_amount": 0,
                          "discount_type": null,
                          "discount_value": 0,
                          "discount_amount": 0,
                          "subtotal": 50000,
                          "total": 50000,
                          "sort_order": 0
                        }
                      ],
                      "created_at": "2026-09-16T09:12:04+00:00",
                      "updated_at": "2026-09-16T09:12:04+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 201
                    },
                    "status": {
                      "type": "string",
                      "example": "Created"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invoice created"
                    },
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Sandbox key",
                      "example": {
                        "code": 403,
                        "status": "Forbidden",
                        "message": "This feature is only available in live mode."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Plan without invoicing",
                      "example": {
                        "code": 403,
                        "status": "Forbidden",
                        "message": "Invoicing is not available on your plan. Please upgrade."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Invoice quota reached",
                      "example": {
                        "code": 403,
                        "status": "Forbidden",
                        "message": "You have reached the maximum number of invoices for your plan. Please upgrade to create more."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "The items field is required.",
                    "errors": {
                      "items": [
                        "The items field is required."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Invoices"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "customer_id": {
                    "type": "string",
                    "description": "One of your own customers, by the `cus_` id the Customers API returns. Their details are copied onto the invoice. Another merchant's customer answers 422.",
                    "example": "cus_7Kq2mX9vL4tRb3nP8sZcWd1e"
                  },
                  "is_recurring": {
                    "type": "boolean",
                    "description": "Make the invoice a recurring template: a draft copy is generated each cycle of `recurring_interval`. Only a `document_type` of `invoice` can recur, and never a copy the series generated: both answer 422.",
                    "example": true
                  },
                  "currency": {
                    "type": "string",
                    "description": "A currency Wajub supports, as on `POST /payments`. Any other code answers 422.",
                    "example": "XAF"
                  },
                  "language": {
                    "type": "string",
                    "description": "The language of the invoice's e-mail and PDF: `fr` or `en`. Defaults to the linked customer's preferred language, else your account's language (Settings → Regional → Language), else `en`.",
                    "example": "fr",
                    "enum": [
                      "fr",
                      "en"
                    ],
                    "nullable": true
                  },
                  "template_id": {
                    "type": "string",
                    "description": "One of the invoice templates set up in the Dashboard, by id.",
                    "example": null,
                    "nullable": true
                  },
                  "accept": {
                    "type": "object",
                    "description": "Restricts the methods the payer is offered on the invoice's page, as on `POST /payments`.",
                    "example": null,
                    "properties": {},
                    "nullable": true
                  },
                  "recurring_frequency": {
                    "type": "string",
                    "description": "Same as `recurring_interval`, accepted for older integrations: `daily`, `weekly`, `monthly`, `quarterly` or `yearly`.",
                    "example": null,
                    "enum": [
                      "daily",
                      "weekly",
                      "monthly",
                      "quarterly",
                      "yearly"
                    ],
                    "nullable": true
                  },
                  "payment_schedules": {
                    "type": "array",
                    "description": "With a `payment_type` of `split` or `milestone`, the instalments the payer settles one at a time.",
                    "example": null,
                    "items": {
                      "type": "object"
                    },
                    "nullable": true
                  },
                  "customer_address": {
                    "type": "string",
                    "description": "The customer's postal address, printed on the invoice.",
                    "example": "12 Rue Joffre, Douala"
                  },
                  "customer_company_name": {
                    "type": "string",
                    "description": "The customer's company, printed under their name.",
                    "example": "Diallo Consulting SARL"
                  },
                  "customer_email": {
                    "type": "string",
                    "description": "Where `POST /invoices/{id}/send` e-mails the invoice and its PDF, and where the Dashboard sends its reminders.",
                    "example": "amina@example.com"
                  },
                  "customer_name": {
                    "type": "string",
                    "description": "The name printed on the invoice. Required, even with `customer_id`: the customer can be a person or a business you only name.",
                    "example": "Amina Diallo"
                  },
                  "customer_phone": {
                    "type": "string",
                    "description": "The customer's phone number, international format.",
                    "example": "+237670000000"
                  },
                  "document_type": {
                    "type": "string",
                    "description": "Defaults to `invoice`. A `quote` or an `estimate` is not returned by the other `/invoices` routes.",
                    "example": null,
                    "enum": [
                      "invoice",
                      "quote",
                      "estimate"
                    ]
                  },
                  "due_date": {
                    "type": "string",
                    "description": "On or after `invoice_date`.",
                    "example": "2026-09-30"
                  },
                  "footer": {
                    "type": "string",
                    "description": "Up to 500 characters.",
                    "example": null
                  },
                  "global_discount_type": {
                    "type": "string",
                    "description": "`percentage` or `fixed`.",
                    "example": null,
                    "enum": [
                      "percentage",
                      "fixed"
                    ]
                  },
                  "global_discount_value": {
                    "type": "number",
                    "description": "A percentage or an amount, by `global_discount_type`.",
                    "example": null
                  },
                  "has_global_discount": {
                    "type": "boolean",
                    "description": "Apply a discount to the whole invoice, set by `global_discount_type` and `global_discount_value`.",
                    "example": false
                  },
                  "invoice_date": {
                    "type": "string",
                    "description": "The date printed on the invoice, `YYYY-MM-DD`.",
                    "example": "2026-09-16"
                  },
                  "items": {
                    "type": "array",
                    "description": "At least one line.",
                    "example": null,
                    "items": {
                      "type": "object",
                      "properties": {
                        "description": {
                          "type": "string",
                          "description": "Detail printed under the name.",
                          "example": "Five pages, French and English"
                        },
                        "discount_type": {
                          "type": "string",
                          "description": "`percentage` or `fixed`.",
                          "example": null,
                          "enum": [
                            "percentage",
                            "fixed"
                          ]
                        },
                        "discount_value": {
                          "type": "number",
                          "description": "A percentage or an amount, by `discount_type`.",
                          "example": null
                        },
                        "name": {
                          "type": "string",
                          "description": "What the line bills, up to 255 characters.",
                          "example": "Website design"
                        },
                        "quantity": {
                          "type": "number",
                          "description": "How many units, more than 0.",
                          "example": 1
                        },
                        "tax_rate": {
                          "type": "number",
                          "description": "A percentage, from 0 to 100.",
                          "example": null
                        },
                        "unit": {
                          "type": "string",
                          "description": "Up to 50 characters, such as `hour` or `kg`.",
                          "example": null
                        },
                        "unit_price": {
                          "type": "number",
                          "description": "The price of one unit, in the major unit of the currency.",
                          "example": 50000
                        }
                      },
                      "required": [
                        "name",
                        "quantity",
                        "unit_price"
                      ]
                    }
                  },
                  "notes": {
                    "type": "string",
                    "description": "Up to 5 000 characters.",
                    "example": null
                  },
                  "payment_terms_days": {
                    "type": "integer",
                    "description": "Sets `due_date` this many days from today when `due_date` is left out.",
                    "example": null
                  },
                  "payment_type": {
                    "type": "string",
                    "description": "`full` (default), `split` or `milestone`.",
                    "example": null,
                    "enum": [
                      "full",
                      "split",
                      "milestone"
                    ]
                  },
                  "recurring_interval": {
                    "type": "string",
                    "description": "`daily`, `weekly`, `monthly`, `quarterly` or `yearly`.",
                    "example": null,
                    "enum": [
                      "daily",
                      "weekly",
                      "monthly",
                      "quarterly",
                      "yearly"
                    ]
                  },
                  "terms": {
                    "type": "string",
                    "description": "Up to 5 000 characters.",
                    "example": null
                  }
                },
                "required": [
                  "currency",
                  "customer_name",
                  "invoice_date",
                  "items"
                ]
              }
            }
          }
        }
      }
    },
    "/invoices/{id}": {
      "get": {
        "summary": "Retrieve an invoice.",
        "operationId": "retrieveAnInvoice",
        "description": "Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Invoice",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Invoice retrieved",
                    "invoice": {
                      "id": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
                      "invoice_number": "INV-2026-0001",
                      "document_type": "invoice",
                      "status": "sent",
                      "customer": null,
                      "customer_id": null,
                      "customer_name": "Amina Diallo",
                      "customer_email": "amina@example.com",
                      "customer_company_name": null,
                      "customer_phone": null,
                      "customer_address": null,
                      "invoice_date": "2026-09-16",
                      "due_date": "2026-09-30",
                      "currency": "XAF",
                      "language": "fr",
                      "subtotal": 50000,
                      "discount_amount": 0,
                      "tax_amount": 0,
                      "total": 50000,
                      "amount_paid": 0,
                      "amount_due": 50000,
                      "payment_type": "full",
                      "is_recurring": false,
                      "recurring_interval": null,
                      "next_invoice_date": null,
                      "recurring_parent": null,
                      "notes": null,
                      "terms": null,
                      "footer": null,
                      "accept": null,
                      "sent_at": "2026-09-16T10:15:37+00:00",
                      "paid_at": null,
                      "cancelled_at": null,
                      "items": [
                        {
                          "id": "9d3f6a2e-4b1c-4e8a-9f27-6c5d8b1a0e43",
                          "name": "Website design",
                          "description": null,
                          "quantity": 1,
                          "unit": null,
                          "unit_price": 50000,
                          "tax_rate": 0,
                          "tax_amount": 0,
                          "discount_type": null,
                          "discount_value": 0,
                          "discount_amount": 0,
                          "subtotal": 50000,
                          "total": 50000,
                          "sort_order": 0
                        }
                      ],
                      "created_at": "2026-09-16T09:12:04+00:00",
                      "updated_at": "2026-09-16T10:15:37+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invoice retrieved"
                    },
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Invoices"
        ]
      },
      "put": {
        "summary": "Update an invoice.",
        "operationId": "updateAnInvoice",
        "description": "Only a `draft` with nothing paid on it can be updated. The body replaces the invoice: it takes the same fields as `POST /invoices`, except `document_type`, and `items` replaces every line. Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Invoice updated",
                    "invoice": {
                      "id": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
                      "invoice_number": null,
                      "status": "draft",
                      "currency": "XAF",
                      "subtotal": 65000,
                      "total": 65000,
                      "amount_paid": 0,
                      "amount_due": 65000,
                      "updated_at": "2026-09-16T10:02:51+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invoice updated"
                    },
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Not a draft",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "message": "This invoice cannot be edited (paid, cancelled, or has payments)."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Unknown invoice",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Invoice Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Invoices"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "language": {
                    "type": "string",
                    "description": "The language of the invoice's e-mail and PDF: `fr` or `en`. Left as it is when omitted, even when `customer_id` changes.",
                    "example": "en",
                    "enum": [
                      "fr",
                      "en"
                    ],
                    "nullable": true
                  },
                  "customer_id": {
                    "type": "string",
                    "description": "One of your own customers, by the `cus_` id the Customers API returns. Their details are copied onto the invoice. Another merchant's customer answers 422.",
                    "example": "cus_7Kq2mX9vL4tRb3nP8sZcWd1e"
                  },
                  "is_recurring": {
                    "type": "boolean",
                    "description": "Make the invoice a recurring template: a draft copy is generated each cycle of `recurring_interval`. Only a `document_type` of `invoice` can recur, and never a copy the series generated: both answer 422.",
                    "example": true
                  },
                  "customer_address": {
                    "type": "string",
                    "description": "The customer's postal address, printed on the invoice.",
                    "example": "12 Rue Joffre, Douala"
                  },
                  "customer_company_name": {
                    "type": "string",
                    "description": "The customer's company, printed under their name.",
                    "example": "Diallo Consulting SARL"
                  },
                  "customer_email": {
                    "type": "string",
                    "description": "Where `POST /invoices/{id}/send` e-mails the invoice and its PDF, and where the Dashboard sends its reminders.",
                    "example": "amina@example.com"
                  },
                  "customer_name": {
                    "type": "string",
                    "description": "The name printed on the invoice. Required, even with `customer_id`: the customer can be a person or a business you only name.",
                    "example": "Amina Diallo"
                  },
                  "customer_phone": {
                    "type": "string",
                    "description": "The customer's phone number, international format.",
                    "example": "+237670000000"
                  },
                  "due_date": {
                    "type": "string",
                    "description": "On or after `invoice_date`.",
                    "example": "2026-09-30"
                  },
                  "footer": {
                    "type": "string",
                    "description": "Up to 500 characters.",
                    "example": null
                  },
                  "global_discount_type": {
                    "type": "string",
                    "description": "`percentage` or `fixed`.",
                    "example": null,
                    "enum": [
                      "percentage",
                      "fixed"
                    ]
                  },
                  "global_discount_value": {
                    "type": "number",
                    "description": "A percentage or an amount, by `global_discount_type`.",
                    "example": null
                  },
                  "has_global_discount": {
                    "type": "boolean",
                    "description": "Apply a discount to the whole invoice, set by `global_discount_type` and `global_discount_value`.",
                    "example": false
                  },
                  "invoice_date": {
                    "type": "string",
                    "description": "The date printed on the invoice, `YYYY-MM-DD`.",
                    "example": "2026-09-16"
                  },
                  "items": {
                    "type": "array",
                    "description": "Replaces every line of the invoice: at least one.",
                    "example": null,
                    "items": {
                      "type": "object",
                      "properties": {
                        "description": {
                          "type": "string",
                          "description": "Detail printed under the name.",
                          "example": "Five pages, French and English"
                        },
                        "discount_type": {
                          "type": "string",
                          "description": "`percentage` or `fixed`.",
                          "example": null,
                          "enum": [
                            "percentage",
                            "fixed"
                          ]
                        },
                        "discount_value": {
                          "type": "number",
                          "description": "A percentage or an amount, by `discount_type`.",
                          "example": null
                        },
                        "name": {
                          "type": "string",
                          "description": "What the line bills, up to 255 characters.",
                          "example": "Website design"
                        },
                        "quantity": {
                          "type": "number",
                          "description": "How many units, more than 0.",
                          "example": 1
                        },
                        "tax_rate": {
                          "type": "number",
                          "description": "A percentage, from 0 to 100.",
                          "example": null
                        },
                        "unit": {
                          "type": "string",
                          "description": "Up to 50 characters, such as `hour` or `kg`.",
                          "example": null
                        },
                        "unit_price": {
                          "type": "number",
                          "description": "The price of one unit, in the major unit of the currency.",
                          "example": 50000
                        }
                      },
                      "required": [
                        "name",
                        "quantity",
                        "unit_price"
                      ]
                    }
                  },
                  "notes": {
                    "type": "string",
                    "description": "Up to 5 000 characters.",
                    "example": null
                  },
                  "payment_terms_days": {
                    "type": "integer",
                    "description": "Sets `due_date` this many days from today when `due_date` is left out.",
                    "example": null
                  },
                  "payment_type": {
                    "type": "string",
                    "description": "`full` (default), `split` or `milestone`.",
                    "example": null,
                    "enum": [
                      "full",
                      "split",
                      "milestone"
                    ]
                  },
                  "recurring_interval": {
                    "type": "string",
                    "description": "`daily`, `weekly`, `monthly`, `quarterly` or `yearly`.",
                    "example": null,
                    "enum": [
                      "daily",
                      "weekly",
                      "monthly",
                      "quarterly",
                      "yearly"
                    ]
                  },
                  "terms": {
                    "type": "string",
                    "description": "Up to 5 000 characters.",
                    "example": null
                  },
                  "currency": {
                    "type": "string",
                    "description": "A currency Wajub supports, as on `POST /payments`. Any other code answers 422.",
                    "example": "XAF"
                  },
                  "accept": {
                    "type": "object",
                    "description": "Restricts the methods the payer is offered on the invoice's page, as on `POST /payments`.",
                    "example": null,
                    "properties": {},
                    "nullable": true
                  },
                  "payment_schedules": {
                    "type": "array",
                    "description": "With a `payment_type` of `split` or `milestone`, the instalments the payer settles one at a time.",
                    "example": null,
                    "items": {
                      "type": "object"
                    },
                    "nullable": true
                  }
                },
                "required": [
                  "customer_name",
                  "invoice_date",
                  "items",
                  "currency"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete an invoice.",
        "operationId": "deleteAnInvoice",
        "description": "Only a `draft` with nothing paid on it can be deleted. A sent invoice is cancelled instead, with `POST /invoices/{id}/cancel`. Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Invoice deleted"
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invoice deleted"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Not a draft",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "message": "This invoice cannot be deleted."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Unknown invoice",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Invoice Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Invoices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The invoice `id`.",
          "example": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/invoices/{id}/send": {
      "post": {
        "summary": "Send an invoice.",
        "operationId": "sendAnInvoice",
        "description": "E-mails the invoice to `customer_email`, with a link to the hosted invoice and a PDF copy. A draft gets its `invoice_number` and moves to `sent`. Calling it again on an invoice already sent e-mails it again without changing its status.\n\nThe invoice needs someone to send it to: `customer_email`, or the e-mail of the customer `customer_id` names. Without either, the call answers `422` on `customer_email` and changes nothing, a draft included. An invoice already `paid`, `cancelled` or `refunded` answers `400`. Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Invoice sent",
                    "invoice": {
                      "id": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
                      "invoice_number": "INV-2026-0001",
                      "status": "sent",
                      "total": 50000,
                      "amount_paid": 0,
                      "amount_due": 50000,
                      "sent_at": "2026-09-16T10:15:37+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invoice sent"
                    },
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Paid, cancelled or refunded",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "message": "This invoice cannot be sent again (paid, cancelled or refunded)."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Unknown invoice",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Invoice Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "No recipient",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "This invoice has nobody to send it to. Set customer_email, or a customer_id whose customer has an e-mail.",
                    "errors": {
                      "customer_email": [
                        "This invoice has nobody to send it to. Set customer_email, or a customer_id whose customer has an e-mail."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Invoices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The invoice `id`.",
          "example": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/invoices/{id}/mark-paid": {
      "post": {
        "summary": "Mark an invoice as paid.",
        "operationId": "markAnInvoiceAsPaid",
        "description": "Records a payment received outside Wajub. Without `amount`, the invoice is paid in full. A smaller `amount` adds to `amount_paid` and leaves the invoice `partial` until the total is reached.\n\nThe invoice has to be open. A draft answers `400`: send it first. An invoice already `paid` answers `400` and keeps its `paid_at`, and so do a cancelled and a refunded one. An `amount` of zero or less answers `422`. Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Partly paid",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Invoice marked as paid",
                    "invoice": {
                      "id": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
                      "invoice_number": "INV-2026-0001",
                      "status": "partial",
                      "total": 50000,
                      "amount_paid": 20000,
                      "amount_due": 30000,
                      "paid_at": null
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invoice marked as paid"
                    },
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "A draft",
                      "example": {
                        "code": 400,
                        "status": "Bad Request",
                        "message": "A draft cannot be marked as paid. Send it first."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Already paid",
                      "example": {
                        "code": 400,
                        "status": "Bad Request",
                        "message": "This invoice is already paid."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Cancelled or refunded",
                      "example": {
                        "code": 400,
                        "status": "Bad Request",
                        "message": "This invoice cannot be marked as paid (cancelled or refunded)."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Unknown invoice",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Invoice Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "An amount of zero or less",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "The amount field must be greater than 0.",
                    "errors": {
                      "amount": [
                        "The amount field must be greater than 0."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Invoices"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "type": "number",
                    "description": "The amount received, in the major unit, above zero. Defaults to the invoice total.",
                    "example": 20000,
                    "nullable": true
                  },
                  "transaction_id": {
                    "type": "string",
                    "description": "Your reference for the money received (a bank transfer number, a receipt). Kept on the payment the invoice records, which the Dashboard shows in its history; the API does not return it.",
                    "example": "VIR-2026-0042",
                    "nullable": true
                  },
                  "payment_date": {
                    "type": "string",
                    "description": "The day the money came in. Becomes `paid_at` when this payment settles the invoice; today otherwise.",
                    "example": "2026-10-10",
                    "nullable": true
                  },
                  "payment_method": {
                    "type": "string",
                    "description": "How the payment was received, free text up to 255 characters, such as `cash` or `bank transfer`.",
                    "example": "cash",
                    "nullable": true
                  },
                  "notes": {
                    "type": "string",
                    "description": "Your note on the payment, up to 1 000 characters.",
                    "example": "Paid at the counter",
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The invoice `id`.",
          "example": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/invoices/{id}/cancel": {
      "post": {
        "summary": "Cancel an invoice.",
        "operationId": "cancelAnInvoice",
        "description": "Any invoice not yet paid, cancelled or refunded can be cancelled, including one partly paid. Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Invoice cancelled",
                    "invoice": {
                      "id": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
                      "invoice_number": "INV-2026-0001",
                      "status": "cancelled",
                      "cancelled_at": "2026-09-18T08:40:12+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Invoice cancelled"
                    },
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Already closed",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "message": "This invoice cannot be cancelled (already paid, cancelled, or refunded)."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Unknown invoice",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Invoice Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Invoices"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "description": "Why the invoice is cancelled, up to 500 characters.",
                    "example": "Order cancelled by the customer",
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The invoice `id`.",
          "example": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/invoices/{id}/stop-recurring": {
      "post": {
        "summary": "Stop a recurring invoice.",
        "operationId": "stopARecurringInvoice",
        "description": "Ends the series: no copy is generated after this call, and the copies already generated stay as they are. It works whatever the invoice's status, paid included, which `PUT /invoices/{id}` cannot do since it only edits drafts. `is_recurring` becomes `false` and `next_invoice_date` `null`, and `invoice.updated` is sent. Stopping a series already stopped answers `200` and changes nothing.\n\nA copy generated from a recurring invoice has no series of its own: it answers `400` with the id of its template in `recurring_parent`, which is the invoice to stop. Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Series stopped",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Recurring invoice stopped",
                    "invoice": {
                      "id": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
                      "invoice_number": "INV-202609-0001",
                      "status": "paid",
                      "is_recurring": false,
                      "recurring_interval": "monthly",
                      "next_invoice_date": null,
                      "recurring_parent": null
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Recurring invoice stopped"
                    },
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A generated copy",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "message": "This invoice was generated by a recurring invoice. Stop the series on that one.",
                    "recurring_parent": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "recurring_parent": {
                          "type": "string",
                          "example": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Invoice not found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Invoices"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The recurring invoice's `id`.",
          "example": "inv_Hq7Lm2Xp9Rt4Vb8Nc3Kd",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/links": {
      "get": {
        "summary": "List payment links.",
        "operationId": "listPaymentLinks",
        "description": "Live links only, newest first by default. Requires the secret key.",
        "parameters": [
          {
            "in": "query",
            "name": "per_page",
            "description": "Max per page (1–100).",
            "example": 10,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Max per page (1–100).",
              "example": 10,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "page",
            "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
            "example": 2,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
              "example": 2
            }
          },
          {
            "in": "query",
            "name": "search",
            "description": "Full-text search over the title, description and custom URL.",
            "example": "masterclass",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Full-text search over the title, description and custom URL.",
              "example": "masterclass"
            }
          },
          {
            "in": "query",
            "name": "type",
            "description": "Only links of this type.",
            "example": "event",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only links of this type.",
              "example": "event",
              "enum": [
                "product",
                "event",
                "fundraising",
                "donation"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "archived",
            "description": "`true` lists the archived links instead of the active ones.",
            "example": false,
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true` lists the archived links instead of the active ones.",
              "example": false
            }
          },
          {
            "in": "query",
            "name": "only_public",
            "description": "`true` keeps only the links whose page is published.",
            "example": true,
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true` keeps only the links whose page is published.",
              "example": true
            }
          },
          {
            "in": "query",
            "name": "sort_by",
            "description": "The field to order by. Defaults to `created_at`.",
            "example": "title",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The field to order by. Defaults to `created_at`.",
              "example": "title",
              "enum": [
                "created_at",
                "updated_at",
                "title",
                "type"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "sort_dir",
            "description": "The direction of the order. Defaults to `desc`.",
            "example": "asc",
            "required": false,
            "schema": {
              "type": "string",
              "description": "The direction of the order. Defaults to `desc`.",
              "example": "asc",
              "enum": [
                "asc",
                "desc"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "description": "The `next_cursor` of the previous page. Only with the default sort (`created_at`, `desc`): with another sort the list is paged by number and carries no cursor.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "The `next_cursor` of the previous page. Only with the default sort (`created_at`, `desc`): with another sort the list is paged by number and carries no cursor.",
              "example": null
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Payment links retrieved",
                    "items": [
                      {
                        "id": "aB3dE5fG7",
                        "type": "product",
                        "product_type": "service",
                        "category_id": null,
                        "title": "Annual subscription",
                        "description": "One year of the members' area.",
                        "external_reference": "CAT-2026-014",
                        "custom_url": null,
                        "url": "https://wajub.link/aB3dE5fG7",
                        "qr_url": null,
                        "price": 25000,
                        "target_amount": null,
                        "min_amount": null,
                        "max_amount": null,
                        "currency": "XAF",
                        "cta_type": "pay",
                        "custom_cta_text": null,
                        "callback_url": "https://example.com/thanks",
                        "expiry_date": null,
                        "sales_limit": null,
                        "is_public": true,
                        "show_progress": false,
                        "show_contributors": false,
                        "allow_overflow": false,
                        "allow_custom_amount": false,
                        "is_archived": false,
                        "tags": [
                          "membership"
                        ],
                        "accept": {},
                        "suggested_amounts": [],
                        "extra_fields": {},
                        "product_variants": [],
                        "event_start_date": null,
                        "event_end_date": null,
                        "event_location": null,
                        "event_address": null,
                        "event_city": null,
                        "event_country": null,
                        "event_capacity": null,
                        "event_timezone": null,
                        "fundraising_milestones": [],
                        "campaign_deadline": null,
                        "recurring_enabled": false,
                        "recurring_intervals": [],
                        "allow_anonymous": false,
                        "show_donor_wall": false,
                        "impact_tiers": [],
                        "single_use_link": false,
                        "stock_quantity": null,
                        "allow_backorder": false,
                        "shipping_required": false,
                        "shipping_flat_rate": null,
                        "shipping_zones": [],
                        "product_weight": null,
                        "product_weight_unit": null,
                        "service_duration": null,
                        "service_location_type": null,
                        "service_meeting_url": null,
                        "service_requirements": null,
                        "cancellation_policy": null,
                        "refund_policy": null,
                        "poster": null,
                        "gallery": [],
                        "file_url": null,
                        "download_instructions": null,
                        "generate_qr_tickets": false,
                        "attendee_info_fields": [],
                        "thank_you_message": "Welcome aboard!",
                        "created_at": "2026-09-10T09:00:00+00:00",
                        "updated_at": "2026-09-10T09:00:00+00:00"
                      }
                    ],
                    "meta": {
                      "current_page": 1,
                      "last_page": 1,
                      "per_page": 25,
                      "total": 1,
                      "next_cursor": null,
                      "has_more": false
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment links retrieved"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Link"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "last_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "per_page": {
                          "type": "integer",
                          "example": 25
                        },
                        "total": {
                          "type": "integer",
                          "example": 1
                        },
                        "next_cursor": {
                          "type": "string",
                          "example": null,
                          "nullable": true
                        },
                        "has_more": {
                          "type": "boolean",
                          "example": false
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payment Links"
        ]
      },
      "post": {
        "summary": "Create a payment link.",
        "operationId": "createAPaymentLink",
        "description": "Creates a shareable payment URL. Live only. Subject to plan limits. Requires the secret key.",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "description": "Your key for this request, 1 to 128 characters of letters, digits and `. _ : -`. The same request sent again with the same key returns the first answer instead of doing the work twice. See [Idempotency](/api/idempotency).",
            "example": "link-masterclass-2026",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 201,
                    "status": "Created",
                    "message": "Payment link created",
                    "link": {
                      "id": "aB3dE5fG7",
                      "type": "product",
                      "url": "https://wajub.link/aB3dE5fG7",
                      "title": "Annual subscription"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 201
                    },
                    "status": {
                      "type": "string",
                      "example": "Created"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment link created"
                    },
                    "link": {
                      "$ref": "#/components/schemas/Link"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not on your plan, plan limit reached, or sandbox key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 403,
                    "status": "Forbidden",
                    "message": "Payment links are not available on your plan. Please upgrade."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "errors": {}
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payment Links"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "description": "Link title displayed to customers.",
                    "example": "Annual subscription"
                  },
                  "amount": {
                    "type": "number",
                    "description": "Fixed amount in major currency unit.",
                    "example": 25000
                  },
                  "currency": {
                    "type": "string",
                    "description": "ISO 4217 code.",
                    "example": "XAF"
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional description.",
                    "example": null
                  },
                  "is_public": {
                    "type": "boolean",
                    "description": "Whether the page opens at its URL. Defaults to true; pass false to create the link offline and publish it later.",
                    "example": true
                  },
                  "custom_url": {
                    "type": "string",
                    "description": "Your own slug for the link's address, in place of the generated one: letters, digits, dashes and underscores. Unique across Wajub, deleted links included: a slug already taken answers `422`.",
                    "example": "masterclass-2026"
                  },
                  "external_reference": {
                    "type": "string",
                    "description": "Your own reference for the link, returned as it is and never shown to payers.",
                    "example": "CAT-2026-014"
                  },
                  "callback_url": {
                    "type": "string",
                    "description": "Where the payer is sent once the payment ends.",
                    "example": null
                  },
                  "cta_type": {
                    "type": "string",
                    "description": "The button label: `buy_now`, `pay`, `donate`, `register` or `custom`.",
                    "example": "pay"
                  },
                  "event_location": {
                    "type": "string",
                    "description": "Required when `type` is `event`.",
                    "example": null
                  },
                  "event_start_date": {
                    "type": "string",
                    "description": "Required when `type` is `event`, in the future.",
                    "example": null
                  },
                  "event_timezone": {
                    "type": "string",
                    "description": "Required when `type` is `event`.",
                    "example": null
                  },
                  "price": {
                    "type": "number",
                    "description": "Required when `type` is `product`, in major currency unit.",
                    "example": 25000
                  },
                  "product_type": {
                    "type": "string",
                    "description": "Required when `type` is `product`: `physical`, `digital` or `service`.",
                    "example": "service"
                  },
                  "target_amount": {
                    "type": "number",
                    "description": "Required when `type` is `fundraising`.",
                    "example": null
                  },
                  "type": {
                    "type": "string",
                    "description": "`product`, `event`, `fundraising` or `donation`.",
                    "example": "product"
                  }
                },
                "required": [
                  "title",
                  "amount",
                  "currency",
                  "cta_type",
                  "type"
                ]
              }
            }
          }
        }
      }
    },
    "/links/{id}": {
      "get": {
        "summary": "Retrieve a payment link.",
        "operationId": "retrieveAPaymentLink",
        "description": "Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Payment link retrieved",
                    "link": {
                      "id": "aB3dE5fG7",
                      "type": "product",
                      "product_type": "service",
                      "category_id": null,
                      "title": "Annual subscription",
                      "description": "One year of the members' area.",
                      "external_reference": "CAT-2026-014",
                      "custom_url": null,
                      "url": "https://wajub.link/aB3dE5fG7",
                      "qr_url": null,
                      "price": 25000,
                      "target_amount": null,
                      "min_amount": null,
                      "max_amount": null,
                      "currency": "XAF",
                      "cta_type": "pay",
                      "custom_cta_text": null,
                      "callback_url": "https://example.com/thanks",
                      "expiry_date": null,
                      "sales_limit": null,
                      "is_public": true,
                      "show_progress": false,
                      "show_contributors": false,
                      "allow_overflow": false,
                      "allow_custom_amount": false,
                      "is_archived": false,
                      "tags": [
                        "membership"
                      ],
                      "accept": {},
                      "suggested_amounts": [],
                      "extra_fields": {},
                      "product_variants": [],
                      "event_start_date": null,
                      "event_end_date": null,
                      "event_location": null,
                      "event_address": null,
                      "event_city": null,
                      "event_country": null,
                      "event_capacity": null,
                      "event_timezone": null,
                      "fundraising_milestones": [],
                      "campaign_deadline": null,
                      "recurring_enabled": false,
                      "recurring_intervals": [],
                      "allow_anonymous": false,
                      "show_donor_wall": false,
                      "impact_tiers": [],
                      "single_use_link": false,
                      "stock_quantity": null,
                      "allow_backorder": false,
                      "shipping_required": false,
                      "shipping_flat_rate": null,
                      "shipping_zones": [],
                      "product_weight": null,
                      "product_weight_unit": null,
                      "service_duration": null,
                      "service_location_type": null,
                      "service_meeting_url": null,
                      "service_requirements": null,
                      "cancellation_policy": null,
                      "refund_policy": null,
                      "poster": null,
                      "gallery": [],
                      "file_url": null,
                      "download_instructions": null,
                      "generate_qr_tickets": false,
                      "attendee_info_fields": [],
                      "thank_you_message": "Welcome aboard!",
                      "created_at": "2026-09-10T09:00:00+00:00",
                      "updated_at": "2026-09-10T09:00:00+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment link retrieved"
                    },
                    "link": {
                      "$ref": "#/components/schemas/Link"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payment Links"
        ]
      },
      "put": {
        "summary": "Update a payment link.",
        "operationId": "updateAPaymentLink",
        "description": "Send only the fields you change. Archiving (`is_archived`) sends `link.updated`; only a deletion sends `link.deleted`. Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Payment link updated",
                    "link": {
                      "id": "lnk_01JXXXXXXXXXXXXX",
                      "title": "Masterclass 2026, second session",
                      "custom_url": "masterclass-2026-bis"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment link updated"
                    },
                    "link": {
                      "$ref": "#/components/schemas/Link"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "message": "Payment link not found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "message": "This custom URL is already taken.",
                    "errors": {
                      "custom_url": [
                        "This custom URL is already taken."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payment Links"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "description": "The title shown to payers, 3 to 255 characters.",
                    "example": "Masterclass 2026, second session"
                  },
                  "description": {
                    "type": "string",
                    "description": "Up to 5 000 characters.",
                    "example": null
                  },
                  "custom_url": {
                    "type": "string",
                    "description": "Your own slug for the link's address: letters, digits, dashes and underscores. Unique across Wajub, deleted links included: a slug already taken answers `422`.",
                    "example": "masterclass-2026-bis"
                  },
                  "price": {
                    "type": "number",
                    "description": "A product link's price, in the major unit of the link's currency.",
                    "example": 20000
                  },
                  "target_amount": {
                    "type": "number",
                    "description": "A fundraising link's goal, in the major unit.",
                    "example": 5000000
                  },
                  "min_amount": {
                    "type": "number",
                    "description": "The smallest amount a payer may enter, in the major unit.",
                    "example": 1000
                  },
                  "max_amount": {
                    "type": "number",
                    "description": "The largest amount a payer may enter, in the major unit.",
                    "example": 500000
                  },
                  "is_public": {
                    "type": "boolean",
                    "description": "`false` takes the page offline; `true` publishes it.",
                    "example": true
                  },
                  "is_archived": {
                    "type": "boolean",
                    "description": "`true` archives the link (its page stops taking payments), `false` restores it.",
                    "example": false
                  },
                  "expiry_date": {
                    "type": "string",
                    "description": "When the page stops taking payments, ISO 8601. `null` removes the date.",
                    "example": "2026-12-31T23:59:59Z",
                    "nullable": true
                  },
                  "sales_limit": {
                    "type": "integer",
                    "description": "How many units the link may sell, payments in progress included; `null` removes the limit.",
                    "example": 200,
                    "nullable": true
                  },
                  "tags": {
                    "type": "array",
                    "description": "Your own labels, up to 50 characters each.",
                    "example": [
                      "masterclass",
                      "2026"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "callback_url": {
                    "type": "string",
                    "description": "Where the payer is sent back after paying. HTTPS (`http://localhost` in sandbox).",
                    "example": "https://example.com/thanks"
                  },
                  "cta_type": {
                    "type": "string",
                    "description": "The pay button: `buy_now`, `pay`, `donate`, `register` or `custom`.",
                    "example": "register"
                  },
                  "custom_cta_text": {
                    "type": "string",
                    "description": "The button's text when `cta_type` is `custom`, up to 50 characters.",
                    "example": "Book my seat"
                  },
                  "accept": {
                    "type": "object",
                    "description": "Restricts the methods a payer is offered, as on `POST /payments`; `{}` removes the restriction.",
                    "example": null,
                    "properties": {}
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a payment link.",
        "operationId": "deleteAPaymentLink",
        "description": "Archives the link: its URL stops working at once. Requires the secret key.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "message": "Payment link deleted"
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "message": {
                      "type": "string",
                      "example": "Payment link deleted"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "406": {
            "description": "Publishable key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 406,
                    "status": "Not Acceptable",
                    "message": "Private Key Required"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Payment Links"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "Link identifier.",
          "example": "aB3dE5fG7",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/providers": {
      "get": {
        "summary": "List connected providers.",
        "operationId": "listConnectedProviders",
        "description": "The authenticated merchant's connected payment providers, each with the channels actually available through it, the intersection of what the provider supports and what this merchant has enabled, exactly what the hosted checkout session offers. Restricted keys need `payment.read`.\n\nOnly the active connections are listed, so `is_active` is always true. Connections are live: a test key gets an empty list.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Providers list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Providers retrieved",
                    "items": [
                      {
                        "id": "9c1b3f6e-8a2d-4e7f-b5c4-1d9e6a3f8b20",
                        "slug": "stripe",
                        "name": "Stripe",
                        "logo": "https://assets.wajub.com/img/providers/stripe/icon.jpeg",
                        "type": "card",
                        "is_active": true,
                        "sandbox": false,
                        "channels": [
                          {
                            "id": "chn.K4mX9vR2pT7w",
                            "slug": "card",
                            "name": "Card",
                            "type": "card"
                          },
                          {
                            "id": "chn.B8nQ3sL6cY1d",
                            "slug": "klarna",
                            "name": "Klarna",
                            "type": "bnpl"
                          }
                        ]
                      }
                    ]
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Providers retrieved"
                    },
                    "items": {
                      "type": "array",
                      "example": [
                        {
                          "id": "9c1b3f6e-8a2d-4e7f-b5c4-1d9e6a3f8b20",
                          "slug": "stripe",
                          "name": "Stripe",
                          "logo": "https://assets.wajub.com/img/providers/stripe/icon.jpeg",
                          "type": "card",
                          "is_active": true,
                          "sandbox": false,
                          "channels": [
                            {
                              "id": "chn.K4mX9vR2pT7w",
                              "slug": "card",
                              "name": "Card",
                              "type": "card"
                            },
                            {
                              "id": "chn.B8nQ3sL6cY1d",
                              "slug": "klarna",
                              "name": "Klarna",
                              "type": "bnpl"
                            }
                          ]
                        }
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "9c1b3f6e-8a2d-4e7f-b5c4-1d9e6a3f8b20"
                          },
                          "slug": {
                            "type": "string",
                            "example": "stripe"
                          },
                          "name": {
                            "type": "string",
                            "example": "Stripe"
                          },
                          "logo": {
                            "type": "string",
                            "example": "https://assets.wajub.com/img/providers/stripe/icon.jpeg"
                          },
                          "type": {
                            "type": "string",
                            "example": "card"
                          },
                          "is_active": {
                            "type": "boolean",
                            "example": true
                          },
                          "sandbox": {
                            "type": "boolean",
                            "example": false
                          },
                          "channels": {
                            "type": "array",
                            "example": [
                              {
                                "id": "chn.K4mX9vR2pT7w",
                                "slug": "card",
                                "name": "Card",
                                "type": "card"
                              },
                              {
                                "id": "chn.B8nQ3sL6cY1d",
                                "slug": "klarna",
                                "name": "Klarna",
                                "type": "bnpl"
                              }
                            ],
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "example": "chn.K4mX9vR2pT7w"
                                },
                                "slug": {
                                  "type": "string",
                                  "example": "card"
                                },
                                "name": {
                                  "type": "string",
                                  "example": "Card"
                                },
                                "type": {
                                  "type": "string",
                                  "example": "card"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Restricted key missing payment.read",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 403,
                    "status": "Forbidden",
                    "message": "This API key does not have permission to read payment"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Providers"
        ]
      }
    },
    "/accounts": {
      "get": {
        "summary": "List subaccounts.",
        "operationId": "listSubaccounts",
        "description": "",
        "parameters": [
          {
            "in": "query",
            "name": "per_page",
            "description": "Max per page.",
            "example": 10,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Max per page.",
              "example": 10,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "page",
            "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
            "example": 2,
            "required": false,
            "schema": {
              "type": "integer",
              "description": "The page to read, from 1, for offset pagination. Ignored with `cursor`.",
              "example": 2
            }
          },
          {
            "in": "query",
            "name": "status",
            "description": "Only the connections whose `status` reads this: `pending`, `active`, `expired` or `cancelled`, as the Account object shows it.",
            "example": "active",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only the connections whose `status` reads this: `pending`, `active`, `expired` or `cancelled`, as the Account object shows it.",
              "example": "active",
              "enum": [
                "pending",
                "active",
                "expired",
                "cancelled"
              ],
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "The `next_cursor` of a previous response, a numbered page included: switches the list to cursor pagination.",
              "example": null,
              "nullable": true
            }
          },
          {
            "in": "query",
            "name": "search",
            "description": "Full-text search over the reference and description.",
            "example": null,
            "required": false,
            "schema": {
              "type": "string",
              "description": "Full-text search over the reference and description.",
              "example": null
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Accounts retrieved",
                    "items": [
                      {
                        "id": "acc_Gt6yU3nE8rM1kS5vX9bQ",
                        "reference": "shop-amina",
                        "sandbox": false,
                        "account_type": "direct",
                        "capabilities": [
                          "read",
                          "payments",
                          "refunds"
                        ],
                        "profile": {
                          "business_name": "Boutique Amina",
                          "email": "contact@shop-amina.example",
                          "country": "CM"
                        },
                        "metadata": {
                          "vendor_id": "4172"
                        },
                        "callback": "https://example.com/connected",
                        "status": "active",
                        "payment_status": "active",
                        "commission_refund_policy": "prorata",
                        "slave": {
                          "id": "9b2f4c1e-6a3d-4e8f-b7c5-2d1e0f9a8b76",
                          "name": "Boutique Amina",
                          "email": "contact@shop-amina.example"
                        },
                        "pricing": {
                          "percentage_fee": 2.5,
                          "fixed_fee": 0,
                          "min_fee": 0,
                          "max_fee": 0,
                          "currency": "XAF"
                        },
                        "expires_at": null,
                        "created_at": "2026-08-20T10:30:00+00:00",
                        "updated_at": "2026-09-01T07:45:12+00:00"
                      }
                    ],
                    "meta": {
                      "current_page": 1,
                      "last_page": 1,
                      "per_page": 25,
                      "total": 1,
                      "next_cursor": null,
                      "has_more": false
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Accounts retrieved"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Account"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "current_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "last_page": {
                          "type": "integer",
                          "example": 1
                        },
                        "per_page": {
                          "type": "integer",
                          "example": 25
                        },
                        "total": {
                          "type": "integer",
                          "example": 1
                        },
                        "next_cursor": {
                          "type": "string",
                          "example": null,
                          "nullable": true
                        },
                        "has_more": {
                          "type": "boolean",
                          "example": false
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Sync is not on your plan",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 403,
                    "status": "Forbidden",
                    "error_code": "feature_not_in_plan",
                    "message": "Sync is not included in your plan. Upgrade your plan or add the Sync add-on."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Subaccounts"
        ]
      },
      "post": {
        "summary": "Create a subaccount.",
        "operationId": "createASubaccount",
        "description": "Creates a connected subaccount for marketplace/platform use. Grant it capabilities and optionally configure per-account pricing (the fee your platform retains on its activity).\n\nThe `authorization_url` in the response is shown once: send it to the merchant. A `relay` connection has no merchant to invite: its `authorization_url` is `null`.",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 201,
                    "account": {
                      "id": "acc_Gt6yU3nE8rM1kS5vX9bQ",
                      "reference": "shop-amina",
                      "status": "pending",
                      "authorization_url": "https://sync.wajub.com/oauth/v2/authorize?access_token=…"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 201
                    },
                    "account": {
                      "$ref": "#/components/schemas/Account"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payout terms on a connection that is not lite",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "message": "payout_schedule and payout_min_amount only apply to a lite account: Wajub pays a Lite merchant, a Direct merchant withdraws for themselves, and a Relay marketplace pays its own sellers."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Sync is not on your plan",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 403,
                    "status": "Forbidden",
                    "error_code": "feature_not_in_plan",
                    "message": "Sync is not included in your plan. Upgrade your plan or add the Sync add-on."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Reference already used",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "An account with this reference already exists.",
                    "errors": {
                      "reference": [
                        "An account with this reference already exists."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Too many open invitations",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 429,
                    "status": "Too Many Requests",
                    "message": "You have reached the maximum of 50 pending invitations."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Subaccounts"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reference": {
                    "type": "string",
                    "description": "Your own reference for this subaccount. Unique among your connections of the environment for good: a cancelled connection keeps its reference, and it cannot be changed afterwards.",
                    "example": "shop-amina",
                    "nullable": true
                  },
                  "capabilities": {
                    "type": "array",
                    "description": "One or more of: read, payments, withdrawals, refunds, disputes, customers, invoices.",
                    "example": [
                      "read",
                      "payments",
                      "refunds"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "pricing": {
                    "type": "object",
                    "description": "Your fee on the account's activity: `percentage_fee`, `fixed_fee`, `min_fee`, `max_fee`, `currency`.",
                    "example": null,
                    "properties": {
                      "percentage_fee": {
                        "type": "number",
                        "description": "Percentage the platform retains (0–100).",
                        "example": 2.5,
                        "nullable": true
                      },
                      "fixed_fee": {
                        "type": "number",
                        "description": "Flat fee per operation (major unit).",
                        "example": 100,
                        "nullable": true
                      },
                      "max_fee": {
                        "type": "number",
                        "description": "Cap on the computed fee.",
                        "example": 5000,
                        "nullable": true
                      },
                      "min_fee": {
                        "type": "number",
                        "description": "Floor on the computed fee.",
                        "example": 50,
                        "nullable": true
                      },
                      "currency": {
                        "type": "string",
                        "description": "Currency for the fee figures, required if any of fixed_fee/min_fee/max_fee is set.",
                        "example": "XAF",
                        "nullable": true
                      }
                    },
                    "nullable": true
                  },
                  "callback": {
                    "type": "string",
                    "description": "The page the merchant is sent back to once they have accepted the connection. HTTPS only; `http://localhost` and `http://127.0.0.1` are accepted with a sandbox key. It also registers the origin a `redirect_uri` on the authorization link must share. No event is sent to it: `account.*` events go to your webhook endpoints.",
                    "example": "https://example.com/connected",
                    "nullable": true
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Free-form key-value data of yours, returned on the Account object and editable with `PUT /accounts/{id}`.",
                    "example": {
                      "vendor_id": "4172"
                    },
                    "properties": {},
                    "nullable": true
                  },
                  "email": {
                    "type": "string",
                    "description": "The merchant's address. Wajub sends the invitation reminder there three days before the invitation expires. Kept in `profile.email`.",
                    "example": "contact@shop-amina.example",
                    "nullable": true
                  },
                  "commission_refund_policy": {
                    "type": "string",
                    "description": "What happens to your commission when a sale is refunded: `prorata` (default, in proportion to the refund), `full` (all of it, on the first refund) or `none`.",
                    "example": "prorata",
                    "enum": [
                      "prorata",
                      "full",
                      "none"
                    ],
                    "nullable": true
                  },
                  "account_type": {
                    "type": "string",
                    "description": "The connection mode: `direct` (the merchant runs a full Wajub account), `lite` (a hosted portal, always collecting on the Wajub rail) or `relay` (no merchant account, you collect, Wajub relays the payouts). Defaults to `direct` and cannot be changed afterwards.",
                    "example": "lite",
                    "enum": [
                      "direct",
                      "lite",
                      "relay"
                    ],
                    "nullable": true
                  },
                  "payout_schedule": {
                    "type": "string",
                    "description": "How often a `lite` merchant is paid what they have earned: `manual` (default, you ask, with `POST /accounts/{id}/payouts`), `daily`, `weekly` or `monthly`.",
                    "example": "weekly",
                    "enum": [
                      "manual",
                      "daily",
                      "weekly",
                      "monthly"
                    ],
                    "nullable": true
                  },
                  "payout_min_amount": {
                    "type": "number",
                    "description": "Do not pay out below this, in the merchant's own currency. Defaults to the platform minimum.",
                    "example": 5000,
                    "nullable": true
                  }
                },
                "required": [
                  "capabilities"
                ]
              }
            }
          }
        }
      }
    },
    "/accounts/{id}": {
      "get": {
        "summary": "Retrieve a subaccount.",
        "operationId": "retrieveASubaccount",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Account retrieved",
                    "account": {
                      "id": "acc_Gt6yU3nE8rM1kS5vX9bQ",
                      "reference": "shop-amina",
                      "sandbox": false,
                      "account_type": "direct",
                      "capabilities": [
                        "read",
                        "payments",
                        "refunds"
                      ],
                      "profile": {
                        "business_name": "Boutique Amina",
                        "email": "contact@shop-amina.example",
                        "country": "CM"
                      },
                      "metadata": {
                        "vendor_id": "4172"
                      },
                      "callback": "https://example.com/connected",
                      "status": "active",
                      "payment_status": "active",
                      "commission_refund_policy": "prorata",
                      "slave": {
                        "id": "9b2f4c1e-6a3d-4e8f-b7c5-2d1e0f9a8b76",
                        "name": "Boutique Amina",
                        "email": "contact@shop-amina.example"
                      },
                      "pricing": {
                        "percentage_fee": 2.5,
                        "fixed_fee": 0,
                        "min_fee": 0,
                        "max_fee": 0,
                        "currency": "XAF"
                      },
                      "expires_at": null,
                      "created_at": "2026-08-20T10:30:00+00:00",
                      "updated_at": "2026-09-01T07:45:12+00:00"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Account retrieved"
                    },
                    "account": {
                      "$ref": "#/components/schemas/Account"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Resource Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Subaccounts"
        ]
      },
      "put": {
        "summary": "Update a subaccount.",
        "operationId": "updateASubaccount",
        "description": "Capabilities and pricing on a connection the merchant has accepted are not changed outright: the merchant is asked to approve them, the answer is `202` with `pending_changes`, and the connection keeps its current terms until they answer. Everything else changes at once. `reference` and `account_type` cannot be changed. A call that changes the account sends `account.updated`, with the account as the call left it; a call that changes nothing, or only proposes new terms, does not.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "account": {
                      "id": "acc_Gt6yU3nE8rM1kS5vX9bQ"
                    },
                    "status": "OK",
                    "message": "Account updated"
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "account": {
                      "$ref": "#/components/schemas/Account"
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Account updated"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "New terms proposed to the merchant",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 202,
                    "status": "Accepted",
                    "message": "The merchant has been asked to approve the new terms. The connection keeps its current terms until they answer.",
                    "account": {
                      "id": "acc_Gt6yU3nE8rM1kS5vX9bQ"
                    },
                    "pending_changes": [
                      {
                        "id": "9d2c4f0e-7b1a-4c3e-9f2d-5a6b7c8d9e0f",
                        "type": "pricing",
                        "proposed": {
                          "percentage_fee": 3
                        },
                        "current": {
                          "percentage_fee": 2.5
                        },
                        "requested_at": "2026-10-12T09:00:00+00:00"
                      }
                    ]
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 202
                    },
                    "status": {
                      "type": "string",
                      "example": "Accepted"
                    },
                    "message": {
                      "type": "string",
                      "example": "The merchant has been asked to approve the new terms. The connection keeps its current terms until they answer."
                    },
                    "account": {
                      "$ref": "#/components/schemas/Account"
                    },
                    "pending_changes": {
                      "type": "array",
                      "example": [
                        {
                          "id": "9d2c4f0e-7b1a-4c3e-9f2d-5a6b7c8d9e0f",
                          "type": "pricing",
                          "proposed": {
                            "percentage_fee": 3
                          },
                          "current": {
                            "percentage_fee": 2.5
                          },
                          "requested_at": "2026-10-12T09:00:00+00:00"
                        }
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "9d2c4f0e-7b1a-4c3e-9f2d-5a6b7c8d9e0f"
                          },
                          "type": {
                            "type": "string",
                            "example": "pricing"
                          },
                          "proposed": {
                            "type": "object",
                            "properties": {
                              "percentage_fee": {
                                "type": "integer",
                                "example": 3
                              }
                            }
                          },
                          "current": {
                            "type": "object",
                            "properties": {
                              "percentage_fee": {
                                "type": "number",
                                "example": 2.5
                              }
                            }
                          },
                          "requested_at": {
                            "type": "string",
                            "example": "2026-10-12T09:00:00+00:00"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Commission refund policy on an accepted connection",
                      "example": {
                        "code": 400,
                        "status": "Bad Request",
                        "message": "Cannot update the commission refund policy on an active connection."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    },
                    {
                      "description": "Payment status on a pending connection",
                      "example": {
                        "code": 400,
                        "status": "Bad Request",
                        "message": "Cannot change payment status on a pending connection."
                      },
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Error"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 404,
                    "status": "Not Found",
                    "message": "Resource Not Found"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "Merchant not verified",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 409,
                    "status": "Conflict",
                    "error_code": "merchant_not_verified",
                    "message": "Payments cannot be activated: the merchant's verification has not been approved."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Subaccounts"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "capabilities": {
                    "type": "array",
                    "description": "The new set of capabilities. Proposed to the merchant once they have accepted the connection.",
                    "example": [
                      "read",
                      "payments"
                    ],
                    "items": {
                      "type": "string"
                    }
                  },
                  "pricing": {
                    "type": "object",
                    "description": "Your fee on the account's activity: `percentage_fee`, `fixed_fee`, `min_fee`, `max_fee`, `currency`.",
                    "example": null,
                    "properties": {
                      "percentage_fee": {
                        "type": "number",
                        "description": "Percentage the platform retains (0–100). Proposed to the merchant once they have accepted the connection.",
                        "example": 3,
                        "nullable": true
                      },
                      "fixed_fee": {
                        "type": "number",
                        "description": "Flat fee per operation (major unit).",
                        "example": null,
                        "nullable": true
                      },
                      "max_fee": {
                        "type": "number",
                        "description": "Cap on the computed fee.",
                        "example": null,
                        "nullable": true
                      },
                      "min_fee": {
                        "type": "number",
                        "description": "Floor on the computed fee.",
                        "example": null,
                        "nullable": true
                      },
                      "currency": {
                        "type": "string",
                        "description": "Currency for the fee figures, required if any of fixed_fee/min_fee/max_fee is set.",
                        "example": "XAF",
                        "nullable": true
                      }
                    },
                    "nullable": true
                  },
                  "callback": {
                    "type": "string",
                    "description": "The page the merchant is sent back to once they have accepted the connection. HTTPS only; `http://localhost` and `http://127.0.0.1` are accepted with a sandbox key.",
                    "example": "https://example.com/connected",
                    "nullable": true
                  },
                  "email": {
                    "type": "string",
                    "description": "The merchant's address, where the invitation reminder is sent. Kept in `profile.email`; `null` removes it.",
                    "example": "contact@shop-amina.example",
                    "nullable": true
                  },
                  "metadata": {
                    "type": "object",
                    "description": "Merged into the connection's metadata; a key sent as `null` is removed.",
                    "example": {
                      "vendor_id": "4172"
                    },
                    "properties": {},
                    "nullable": true
                  },
                  "payment_status": {
                    "type": "string",
                    "description": "`active` or `suspended`: your own switch on the connection's payments. `active` cannot lift a suspension Wajub applied because the merchant's verification is pending or was rejected.",
                    "example": "suspended",
                    "enum": [
                      "active",
                      "suspended"
                    ],
                    "nullable": true
                  },
                  "commission_refund_policy": {
                    "type": "string",
                    "description": "`prorata`, `full` or `none`. Only while the connection is pending.",
                    "example": "full",
                    "enum": [
                      "prorata",
                      "full",
                      "none"
                    ],
                    "nullable": true
                  },
                  "payout_schedule": {
                    "type": "string",
                    "description": "`manual`, `daily`, `weekly` or `monthly`. Lite accounts only.",
                    "example": "weekly",
                    "enum": [
                      "manual",
                      "daily",
                      "weekly",
                      "monthly"
                    ],
                    "nullable": true
                  },
                  "payout_min_amount": {
                    "type": "number",
                    "description": "Do not pay out below this, in the merchant's own currency. Lite accounts only.",
                    "example": 5000,
                    "nullable": true
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a subaccount.",
        "operationId": "deleteASubaccount",
        "description": "Disconnects/cancels the subaccount and revokes its tokens.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Account disconnected"
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Account disconnected"
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Subaccounts"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The subaccount `id`.",
          "example": "acc_Gt6yU3nE8rM1kS5vX9bQ",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/accounts/{id}/token": {
      "post": {
        "summary": "Regenerate a subaccount's authorization token.",
        "operationId": "regenerateASubaccountsAuthorizationToken",
        "description": "Only allowed while the connection is not yet active. The response is the only place the new onboarding link appears, and every link issued before stops working, this is also how you recover a link you did not keep. The invitation runs for 30 days again from this call, and one that had expired or was cancelled is pending again. A `relay` connection has no link: the call answers `422`. Putting a cancelled invitation back to pending sends `account.updated`, once, with the account; a new link on an invitation still pending sends nothing.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "account": {
                      "authorization_url": "https://sync.wajub.com/oauth/v2/authorize?access_token=…"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "account": {
                      "$ref": "#/components/schemas/Account"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "message": "Cannot generate a new token for an active connection."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Relay connection",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 422,
                    "status": "Unprocessable Content",
                    "message": "A Relay connection has no merchant to invite, so it has no authorization link.",
                    "errors": {
                      "account": [
                        "A Relay connection has no merchant to invite, so it has no authorization link."
                      ]
                    }
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Subaccounts"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The subaccount `id`.",
          "example": "acc_Gt6yU3nE8rM1kS5vX9bQ",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/accounts/{id}/commission-receivables": {
      "get": {
        "summary": "List the commissions owed on a connection.",
        "operationId": "listTheCommissionsOwedOnAConnection",
        "description": "",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Commission receivables",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Commission receivables retrieved",
                    "outstanding": [
                      {
                        "currency": "XAF",
                        "amount": 1500
                      }
                    ],
                    "receivables": [
                      {
                        "id": "crv_Kp4Tz8Wm2Qx6Hb9Lc3Nd",
                        "account": "acc_Fq2Wm8Tz5Lr1Hx7Nc4Pb",
                        "transaction": "trx_CSUGajfv9xh0XQ5wu2lx",
                        "currency": "XAF",
                        "amount": 1500,
                        "reduced": 0,
                        "outstanding": 1500,
                        "status": "open",
                        "collected_at": null,
                        "created_at": "2026-09-20T11:04:33+00:00"
                      }
                    ]
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Commission receivables retrieved"
                    },
                    "outstanding": {
                      "type": "array",
                      "example": [
                        {
                          "currency": "XAF",
                          "amount": 1500
                        }
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "currency": {
                            "type": "string",
                            "example": "XAF"
                          },
                          "amount": {
                            "type": "integer",
                            "example": 1500
                          }
                        }
                      }
                    },
                    "receivables": {
                      "type": "array",
                      "example": [
                        {
                          "id": "crv_Kp4Tz8Wm2Qx6Hb9Lc3Nd",
                          "account": "acc_Fq2Wm8Tz5Lr1Hx7Nc4Pb",
                          "transaction": "trx_CSUGajfv9xh0XQ5wu2lx",
                          "currency": "XAF",
                          "amount": 1500,
                          "reduced": 0,
                          "outstanding": 1500,
                          "status": "open",
                          "collected_at": null,
                          "created_at": "2026-09-20T11:04:33+00:00"
                        }
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "crv_Kp4Tz8Wm2Qx6Hb9Lc3Nd"
                          },
                          "account": {
                            "type": "string",
                            "example": "acc_Fq2Wm8Tz5Lr1Hx7Nc4Pb"
                          },
                          "transaction": {
                            "type": "string",
                            "example": "trx_CSUGajfv9xh0XQ5wu2lx"
                          },
                          "currency": {
                            "type": "string",
                            "example": "XAF"
                          },
                          "amount": {
                            "type": "integer",
                            "example": 1500
                          },
                          "reduced": {
                            "type": "integer",
                            "example": 0
                          },
                          "outstanding": {
                            "type": "integer",
                            "example": 1500
                          },
                          "status": {
                            "type": "string",
                            "example": "open"
                          },
                          "collected_at": {
                            "type": "string",
                            "example": null,
                            "nullable": true
                          },
                          "created_at": {
                            "type": "string",
                            "example": "2026-09-20T11:04:33+00:00"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 401,
                    "status": "Unauthorized",
                    "message": "Invalid API credentials"
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Subaccounts"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The subaccount `id`.",
          "example": "acc_Gt6yU3nE8rM1kS5vX9bQ",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/accounts/{id}/payouts": {
      "post": {
        "summary": "Pay a Lite merchant now.",
        "operationId": "payALiteMerchantNow",
        "description": "The merchant has no dashboard to withdraw from, so the platform can ask on their behalf instead of waiting for the connection's schedule. The amount is not the caller's to choose: it is whatever is available, less what the rolling reserve still holds against refunds. Nothing is sent below the connection's `payout_min_amount`, or 1 000 in the merchant's currency when it has none.\n\nAt most one automatic payout a day: a second call the same day sends nothing and returns the payout already made that day, whatever its status, a `failed` one included.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {
                    "code": 200,
                    "status": "OK",
                    "message": "Payout sent",
                    "transfer": {
                      "id": "po_…",
                      "amount": 12500,
                      "currency": "XAF",
                      "status": "processing"
                    }
                  },
                  "properties": {
                    "code": {
                      "type": "integer",
                      "example": 200
                    },
                    "status": {
                      "type": "string",
                      "example": "OK"
                    },
                    "message": {
                      "type": "string",
                      "example": "Payout sent"
                    },
                    "transfer": {
                      "$ref": "#/components/schemas/Transfer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Sandbox key",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 400,
                    "status": "Bad Request",
                    "error_code": "live_mode_only",
                    "message": "Payouts are only sent in live mode."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "code": 409,
                    "status": "Conflict",
                    "error_code": "nothing_to_pay_out",
                    "message": "There is nothing to pay out yet."
                  },
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        },
        "tags": [
          "Subaccounts"
        ]
      },
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "description": "The subaccount `id`.",
          "example": "acc_Gt6yU3nE8rM1kS5vX9bQ",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    }
  }
}