{
	"openapi": "3.1.0",
	"info": {
		"title": "Afriex Business API",
		"version": "1.0.8",
		"description": "Welcome to the Afriex Business API. This API allows you to manage customers, process payments, handle payouts, and receive real-time notifications via webhooks.\n\nFor detailed guidance on authentication, pagination, error handling, and webhooks, please refer to the [dedicated guides](https://docs.afriex.com) in the top bar. The guide provides a step-by-step instructions to help you integrate seamlessly.",
		"termsOfService": "https://www.afriex.com/terms-and-condition",
		"contact": {
			"name": "Afriex API Support",
			"email": "support@afriex.com",
			"url": "https://docs.afriex.com"
		},
		"license": {
			"name": "Proprietary",
			"url": "https://www.afriex.com/terms-and-condition"
		}
	},
	"servers": [
		{
			"url": "https://sandbox.api.afriex.com",
			"description": "Staging Base URL"
		},
		{
			"url": "https://api.afriex.com",
			"description": "Production Base URL"
		}
	],
	"components": {
		"securitySchemes": {
			"ApiKey": {
				"type": "apiKey",
				"in": "header",
				"name": "x-api-key",
				"description": "Static business API key issued from the dashboard. A business can provision **multiple API keys**, each scoped to a configurable set of **permissions** (e.g. read transactions, create deposits, etc). Permissions are chosen per key at creation time in the dashboard and may be revoked by deleting the key. Requests made with a key that does not include the permission required by the target endpoint will be rejected with a `403 Forbidden` response; an unrecognised, malformed or revoked key returns `401 Unauthorized`. Manage your keys and their permissions under **Developer → API keys** in the dashboard."
			}
		},
		"parameters": {
			"x-api-version": {
				"name": "x-api-version",
				"in": "header",
				"required": false,
				"description": "API version in ISO 8601 format (e.g. 2025-12-28). Defaults to latest stable.",
				"schema": {
					"type": "string"
				}
			},
			"x-api-signature": {
				"name": "x-api-signature",
				"in": "header",
				"required": false,
				"description": "Signature of the request payload, used for request authentication where payload signing is enabled for your business.",
				"schema": {
					"type": "string"
				}
			}
		},
		"schemas": {
			"BankCodeResolverResponse": {
				"type": [
					"object",
					"null"
				],
				"properties": {
					"bankName": {
						"type": "string",
						"description": "The resolved bank or institution name."
					}
				}
			},
			"Customer": {
				"type": "object",
				"properties": {
					"customerId": {
						"type": "string",
						"description": "The unique identifier for the customer."
					},
					"reference": {
						"type": "string",
						"description": "A shortened reference for the customer. Returned on customer reads (list and by-ID) and used as the pool-account reference when submitting a payment proof. Falls back to the customer id when no shortened reference has been assigned."
					},
					"name": {
						"type": "string",
						"description": "The full name of the customer."
					},
					"email": {
						"type": "string",
						"format": "email",
						"description": "The email of the customer."
					},
					"phone": {
						"type": "string",
						"description": "The phone number of the customer in E.164 format."
					},
					"countryCode": {
						"type": "string",
						"description": "The country code of the customer in ISO 3166-1 alpha-2 format."
					},
					"meta": {
						"type": "object",
						"description": "optional meta data you can attach to the customer."
					},
					"createdAt": {
						"type": "string",
						"description": "The date and time the customer was created."
					},
					"updatedAt": {
						"type": "string",
						"description": "The date and time the customer was last updated."
					}
				}
			},
			"Transaction": {
				"type": "object",
				"properties": {
					"transactionId": {
						"type": "string",
						"description": "The unique identifier for the transaction."
					},
					"customerId": {
						"type": "string",
						"description": "The unique identifier of the customer."
					},
					"sourceId": {
						"type": "string",
						"description": "The unique identifier of the source payment method."
					},
					"destinationId": {
						"type": "string",
						"description": "The unique identifier of the destination payment method."
					},
					"sourceAmount": {
						"type": "string",
						"description": "The souce transaction amount value"
					},
					"sourceCurrency": {
						"type": "string",
						"description": "The currency code of the wallet charged."
					},
					"destinationAmount": {
						"type": "string",
						"description": "The destination transaction amount value"
					},
					"destinationCurrency": {
						"type": "string",
						"description": "The description currency code."
					},
					"type": {
						"type": "string",
						"enum": [
							"DEPOSIT",
							"WITHDRAW",
							"SWAP"
						],
						"description": "The type of transaction."
					},
					"channel": {
						"type": "string",
						"enum": [
							"BANK_ACCOUNT",
							"SWIFT",
							"MOBILE_MONEY",
							"UPI",
							"INTERAC",
							"WE_CHAT",
							"CARD",
							"CRYPTO",
							"VIRTUAL_BANK_ACCOUNT",
							"POOL_ACCOUNT",
							"ACH_BANK_ACCOUNT",
							"PAYBILL_TILL",
							"RFP",
							"VIRTUAL_CARD",
							"ALIPAY",
							"WALLET"
						],
						"description": "The payment channel of the transaction."
					},
					"status": {
						"type": "string",
						"enum": [
							"PENDING",
							"PROCESSING",
							"SUCCESS",
							"FAILED",
							"CANCELLED",
							"REFUNDED",
							"RETRY",
							"UNKNOWN",
							"SCHEDULED",
							"CUSTOMER_ACTION_REQUIRED",
							"REJECTED",
							"IN_REVIEW",
							"DISPUTED",
							"DISPUTE_RESOLVED",
							"DISPUTE_WON",
							"DISPUTE_LOST",
							"DISPUTE_EVIDENCE_SUBMITTED"
						],
						"description": "The current status of the transaction."
					},
					"merchantReference": {
						"type": "string",
						"description": "The merchant-supplied reference for the transaction (mirrors meta.reference from the create request)."
					},
					"rate": {
						"type": "string",
						"description": "The realized source-to-destination exchange rate for the transaction, expressed as `1 sourceCurrency = rate destinationCurrency` (equal to destinationAmount / sourceAmount)."
					},
					"fee": {
						"type": "string",
						"description": "The fee charged for this transaction, denominated in `sourceCurrency`. It is reported separately from `sourceAmount`. Omitted when no fee applied to the transaction."
					},
					"meta": {
						"type": "object",
						"description": "Transaction metadata. Echoes the metadata you attached on create and may include server-set state flags such as `otpRequired` and `failureReason`.",
						"properties": {
							"narration": {
								"type": "string",
								"description": "The narration you attached when creating the transaction, echoed back. An empty string when none was provided."
							},
							"otpRequired": {
								"type": "boolean",
								"description": "Returned on deposits that may need an extra authorization step. When `true`, the deposit is waiting for the customer to submit a one-time password; call `POST /transaction/{transactionId}/authorize` to complete it."
							},
							"failureReason": {
								"type": "object",
								"description": "Present only when `status` is `FAILED` or `REJECTED`. Carries a stable `AFX_*` code and a customer-safe message. Branch on `code` rather than the underlying rail so your integration stays stable across routing changes.",
								"required": [
									"code",
									"message",
									"retryable"
								],
								"properties": {
									"code": {
										"type": "string",
										"description": "Stable `AFX_*` failure code. Safe to switch on; the set grows over time but existing values do not change meaning.",
										"example": "AFX_VELOCITY_LIMIT_EXCEEDED",
										"enum": [
											"AFX_REQUEST_FAILED",
											"AFX_SYSTEM_ERROR",
											"AFX_SERVICE_UNAVAILABLE",
											"AFX_INVALID_CURRENCY",
											"AFX_INVALID_AMOUNT",
											"AFX_INVALID_RECIPIENT",
											"AFX_RECIPIENT_NOT_FOUND",
											"AFX_BENEFICIARY_RESTRICTED",
											"AFX_INVALID_SENDER",
											"AFX_INVALID_REQUEST",
											"AFX_VELOCITY_LIMIT_EXCEEDED",
											"AFX_AMOUNT_LIMIT_EXCEEDED",
											"AFX_PAYMENT_FAILED",
											"AFX_COMPLIANCE_REJECTED",
											"AFX_PROPOSAL_EXPIRED"
										]
									},
									"message": {
										"type": "string",
										"description": "Customer-safe short description of the failure. Suitable for display; do not parse — branch on `code` instead."
									},
									"retryable": {
										"type": "boolean",
										"description": "`true` when re-submitting the same request (or, for `AFX_PROPOSAL_EXPIRED`, starting a fresh proposal) may succeed. `false` when the caller must change the request before retrying."
									}
								}
							}
						},
						"additionalProperties": true
					},
					"createdAt": {
						"type": "string",
						"description": "The date and time the transaction was created."
					},
					"updatedAt": {
						"type": "string",
						"description": "The date and time the transaction was last updated."
					}
				}
			},
			"TransactionMeta": {
				"type": "object",
				"properties": {
					"narration": {
						"type": "string",
						"description": "The optional reason for the transaction."
					},
					"invoice": {
						"type": "string",
						"description": "The invoice filename (S3 object key) for the transaction, as returned by the media upload endpoint. Required for SWIFT withdrawals: the referenced object is verified to exist in storage before the transaction is created, so upload the file first and pass the returned key verbatim."
					},
					"idempotencyKey": {
						"type": "string",
						"description": "The idempotency key for the transaction."
					},
					"reference": {
						"type": "string",
						"description": "The reference for the transaction."
					},
					"settlement": {
						"type": "string",
						"enum": [
							"spot",
							"request"
						],
						"description": "Optional settlement handling for the transaction. `spot` (the default) processes immediately and debits your Payout wallet. `request` is only supported for WITHDRAW transactions: it debits your Collection wallet (rather than the default Payout wallet) and queues the payout for the next business day in the destination payment method's country. Omit `settlement` (or send `spot`) for an ordinary payout from the Payout wallet."
					}
				},
				"required": [
					"idempotencyKey",
					"reference"
				]
			},
			"PaymentMethod": {
				"type": "object",
				"description": "A payment method. Empty fields are omitted. Account-shaped channels (BANK_ACCOUNT, MOBILE_MONEY, SWIFT, etc.) populate accountName, accountNumber, and institution; the CARD channel instead populates last4, brand, expiration, and cardName.",
				"properties": {
					"paymentMethodId": {
						"type": "string",
						"description": "The unique identifier for the payment method."
					},
					"customerId": {
						"$ref": "#/components/schemas/customerId"
					},
					"reference": {
						"type": "string",
						"description": "Identifier to reconcile incoming deposits against."
					},
					"institution": {
						"$ref": "#/components/schemas/PaymentMethodInstitution"
					},
					"transaction": {
						"$ref": "#/components/schemas/PaymentMethodTransaction"
					},
					"recipient": {
						"$ref": "#/components/schemas/PaymentMethodRecipient"
					},
					"channel": {
						"type": "string",
						"enum": [
							"BANK_ACCOUNT",
							"MOBILE_MONEY",
							"SWIFT",
							"INTERAC",
							"UPI",
							"WE_CHAT",
							"ALIPAY",
							"CARD",
							"CRYPTO",
							"VIRTUAL_BANK_ACCOUNT",
							"POOL_ACCOUNT",
							"ACH_BANK_ACCOUNT",
							"PAYBILL_TILL",
							"RFP",
							"VIRTUAL_CARD"
						],
						"description": "The payment method channel."
					},
					"countryCode": {
						"type": "string",
						"description": "The ISO 3166-1 alpha-2 country code."
					},
					"currency": {
						"type": "string",
						"description": "The payment method's currency (ISO 4217). Use this instead of inferring currency from countryCode, which is ambiguous (e.g. a USD account in a non-US country)."
					},
					"capabilities": {
						"type": "array",
						"items": {
							"type": "string"
						},
						"description": "The operations this payment method is enabled for (e.g. DEPOSIT, WITHDRAW). Use it to select deposit-capable vs withdraw-capable methods. Also filterable via the `capabilities` query parameter."
					},
					"accountName": {
						"type": "string",
						"description": "Name of the account holder. Present for account-shaped channels."
					},
					"accountNumber": {
						"type": "string",
						"description": "Account number. Present for account-shaped channels."
					},
					"routingNumber": {
						"type": "string",
						"description": "Bank routing number. Present for account-shaped channels that carry one (e.g. ACH bank accounts)."
					},
					"status": {
						"type": "string",
						"enum": [
							"active",
							"pending",
							"deleted",
							"expired",
							"blocked"
						],
						"description": "Lifecycle status of the payment method."
					},
					"last4": {
						"type": "string",
						"description": "Last 4 digits of the card. CARD channel only."
					},
					"brand": {
						"type": "string",
						"enum": [
							"Visa",
							"MasterCard",
							"Discover",
							"American Express",
							"JCB",
							"Diners Club",
							"Eftpos Australia",
							"UnionPay",
							"Unknown"
						],
						"description": "Card brand. CARD channel only."
					},
					"expiration": {
						"type": "object",
						"description": "Card expiration. CARD channel only.",
						"properties": {
							"month": {
								"type": "integer"
							},
							"year": {
								"type": "integer"
							}
						}
					},
					"cardName": {
						"type": "string",
						"description": "Name on the card. CARD channel only."
					},
					"expiresInMinutes": {
						"type": "integer",
						"description": "Minutes until a dynamic virtual account expires, when applicable."
					},
					"amount": {
						"type": "number",
						"description": "Requested amount for a dynamic virtual account, when applicable."
					},
					"extra": {
						"type": "object",
						"description": "Additional channel-specific properties.",
						"additionalProperties": true
					},
					"meta": {
						"type": "object",
						"description": "Optional meta data you attached to the payment method."
					}
				}
			},
			"PaymentMethodInstitution": {
				"type": "object",
				"properties": {
					"institutionId": {
						"type": "string",
						"description": "The unique identifier of the bank or mobile money provider if required."
					},
					"institutionName": {
						"type": "string",
						"description": "The name of the bank or mobile money provider if required."
					},
					"institutionCode": {
						"type": "string",
						"description": "The code of the bank or mobile money provider."
					},
					"institutionAddress": {
						"type": "string",
						"description": "The address of the bank or mobile money provider if required."
					},
					"correspondentBankName": {
						"type": "string",
						"description": "The correspondent (intermediary) bank name. Mandatory for USD (SWIFT) payout payment methods; required to produce settlement advices/invoices."
					},
					"correspondentBankAccountNumber": {
						"type": "string",
						"description": "The correspondent (intermediary) bank account number. Mandatory for USD (SWIFT) payout payment methods; required to produce settlement advices/invoices."
					}
				}
			},
			"PaymentMethodRecipient": {
				"type": "object",
				"properties": {
					"recipientEmail": {
						"type": "string",
						"format": "email",
						"description": "The email address of the recipient if needed."
					},
					"recipientPhone": {
						"type": "string",
						"description": "The phone number of the recipient in E.164 format."
					},
					"recipientAddress": {
						"type": "string",
						"description": "The address of the recipient if needed."
					},
					"recipientName": {
						"type": "string",
						"description": "The name of the recipient if needed."
					}
				}
			},
			"PaymentMethodTransaction": {
				"type": "object",
				"properties": {
					"transactionInvoice": {
						"type": "string",
						"description": "The invoice filename (S3 object key) for the transaction, as returned by the media upload endpoint."
					},
					"transactionNarration": {
						"type": "string",
						"description": "The optional reason for the transaction."
					}
				}
			},
			"customerId": {
				"type": "string",
				"description": "The unique identifier of the customer."
			},
			"amount": {
				"description": "A monetary amount. Accepts a number or a numeric string; responses return amounts as strings.",
				"oneOf": [
					{
						"type": "number"
					},
					{
						"type": "string"
					}
				],
				"examples": [
					"100.50"
				]
			},
			"ErrorDetails": {
				"type": "object",
				"properties": {
					"errorMessage": {
						"type": "string",
						"description": "Detailed/technical error message."
					},
					"friendlyMessage": {
						"type": "string",
						"description": "User-facing error message safe to display."
					},
					"data": {
						"type": "object",
						"description": "Optional caller-safe context for the error. On a customer-create uniqueness conflict (EMAIL_ALREADY_EXISTS / PHONE_NUMBER_ALREADY_EXISTS) this carries the existing customer's id, so you can adopt it without a follow-up lookup.",
						"properties": {
							"customerId": {
								"type": "string",
								"description": "Id of the existing customer (on a create conflict)."
							}
						}
					}
				}
			},
			"ErrorResponse": {
				"type": "object",
				"properties": {
					"code": {
						"type": "string",
						"description": "Machine-readable error code."
					},
					"error": {
						"type": "string",
						"description": "Human-readable error message."
					},
					"details": {
						"$ref": "#/components/schemas/ErrorDetails"
					}
				}
			},
			"CheckoutSessionCustomer": {
				"type": "object",
				"required": [
					"name",
					"email",
					"phone",
					"countryCode"
				],
				"properties": {
					"name": {
						"type": "string",
						"description": "The full name of the customer.",
						"examples": [
							"John Doe"
						]
					},
					"email": {
						"type": "string",
						"format": "email",
						"description": "The email address of the customer.",
						"examples": [
							"john.doe@example.com"
						]
					},
					"phone": {
						"type": "string",
						"description": "The phone number of the customer in E.164 format.",
						"examples": [
							"+2348192837465"
						]
					},
					"countryCode": {
						"type": "string",
						"description": "The ISO 3166-1 alpha-2 country code of the customer (e.g., 'NG', 'GH'). Case-insensitive; values are normalized to uppercase.",
						"examples": [
							"NG"
						]
					}
				}
			},
			"CreateCheckoutSessionResponse": {
				"type": "object",
				"properties": {
					"checkoutUrl": {
						"type": "string",
						"format": "uri",
						"description": "The URL the customer should be redirected to in order to complete the hosted checkout flow.",
						"examples": [
							"https://pay.afriex.com/pay/eyJhbGciOiJI..."
						]
					},
					"channels": {
						"type": "array",
						"description": "The payment channels the customer will actually be offered on the checkout page: the request's `channels`, in the order you sent them, minus any the currency cannot collect on. Never empty.",
						"items": {
							"type": "string",
							"enum": [
								"VIRTUAL_BANK_ACCOUNT",
								"MOBILE_MONEY",
								"CARD"
							]
						},
						"examples": [
							[
								"MOBILE_MONEY"
							]
						]
					}
				}
			},
			"PaymentMethodResolveResponse": {
				"type": "object",
				"properties": {
					"recipientName": {
						"type": "string",
						"description": "The resolved name on the account."
					},
					"institutionName": {
						"type": "string",
						"description": "The name of the resolved bank or mobile money provider."
					},
					"institutionCode": {
						"type": "string",
						"description": "The code of the resolved bank or mobile money provider."
					}
				}
			},
			"PoolAccountPaymentProofSenderDetails": {
				"type": "object",
				"required": [
					"name"
				],
				"properties": {
					"name": {
						"type": "string",
						"description": "The sender's full name."
					},
					"accountNumber": {
						"type": "string",
						"description": "The sender's account number or wallet identifier."
					},
					"bankName": {
						"type": "string",
						"description": "The sender's bank or financial institution."
					},
					"countryCode": {
						"type": "string",
						"description": "ISO 3166-1 alpha-2 country code for the sender."
					}
				}
			},
			"PoolAccountPaymentProofRequest": {
				"type": "object",
				"required": [
					"amount",
					"customerId",
					"countryCode",
					"reference",
					"fileKey",
					"timestamp"
				],
				"properties": {
					"amount": {
						"type": "number",
						"minimum": 0,
						"exclusiveMinimum": true,
						"description": "The deposit amount in the major currency unit."
					},
					"customerId": {
						"type": "string",
						"description": "The Afriex customer ID the deposit should be credited to. Applies when `reference` is a customer reference, in which case it must match that customer. When `reference` is the business's own pool-account reference the deposit is credited to the business and this field is not used for routing."
					},
					"countryCode": {
						"type": "string",
						"description": "ISO 3166-1 alpha-2 country code of the pool account."
					},
					"reference": {
						"type": "string",
						"description": "The pool-account reference returned by `GET /api/v1/payment-method/pool-account`. Used to reconcile the deposit."
					},
					"fileKey": {
						"type": "string",
						"description": "The S3 object key of the uploaded proof-of-payment file. Obtain this from `POST /api/v1/media/url` with `type: transaction` first; a URL requested without that type uploads to a different bucket and the key will be rejected as not found."
					},
					"timestamp": {
						"type": "string",
						"format": "date-time",
						"description": "ISO 8601 timestamp of when the payment was sent. Used for idempotency together with the other request fields."
					},
					"senderDetails": {
						"$ref": "#/components/schemas/PoolAccountPaymentProofSenderDetails"
					}
				}
			},
			"MediaURLRequest": {
				"type": "object",
				"required": [
					"fileName"
				],
				"properties": {
					"fileName": {
						"type": "string",
						"description": "The name of the file to upload.",
						"examples": [
							"document.pdf"
						]
					},
					"type": {
						"type": "string",
						"enum": [
							"transaction",
							"user"
						],
						"description": "The category of the file being uploaded. Use `transaction` for transaction-related files (e.g. a transactions CSV) and `user` for user identity documents. Defaults to `user` when omitted.\n"
					}
				}
			},
			"MediaURLResponse": {
				"type": "object",
				"properties": {
					"data": {
						"type": "object",
						"properties": {
							"url": {
								"type": "string",
								"description": "The presigned URL for the requested upload operation.",
								"examples": [
									"https://s3.amazonaws.com/bucket/key?X-Amz-Algorithm=AWS4-HMAC-SHA256&..."
								]
							},
							"key": {
								"type": "string",
								"description": "A stable reference to the uploaded object. Attach this to a later request (e.g. a SWIFT payout invoice) rather than the presigned URL, which expires shortly after it is issued.\n",
								"examples": [
									"64f0c2a1e4b0a1b2c3d4e5f6/invoice.pdf"
								]
							},
							"expiresIn": {
								"type": "integer",
								"description": "Number of seconds the presigned URL remains valid for the upload. Complete the PUT upload within this window; afterwards, request a fresh URL.\n",
								"examples": [
									300
								]
							}
						}
					}
				}
			},
			"WebhookEventName": {
				"type": "string",
				"description": "The webhook event identifier.",
				"enum": [
					"CUSTOMER.CREATED",
					"CUSTOMER.UPDATED",
					"CUSTOMER.DELETED",
					"PAYMENT_METHOD.CREATED",
					"PAYMENT_METHOD.UPDATED",
					"PAYMENT_METHOD.DELETED",
					"TRANSACTION.CREATED",
					"TRANSACTION.UPDATED",
					"CHECKOUT_SESSION.CREATED"
				]
			}
		}
	},
	"security": [
		{
			"ApiKey": []
		}
	],
	"paths": {
		"/api/v1/customer": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "createCustomer",
				"summary": "Create a new customer",
				"description": "Creates a new customer for a business, with optional KYC information.",
				"tags": [
					"Customers"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"required": [
									"fullName",
									"email",
									"phone",
									"countryCode"
								],
								"properties": {
									"fullName": {
										"type": "string",
										"description": "The full name of the customer.",
										"examples": [
											"John Doe"
										]
									},
									"email": {
										"type": "string",
										"format": "email",
										"description": "The email address of the customer.",
										"examples": [
											"john.doe@example.com"
										]
									},
									"phone": {
										"type": "string",
										"description": "The phone number of the customer.",
										"examples": [
											"+2348192837465"
										]
									},
									"countryCode": {
										"type": "string",
										"description": "The ISO 3166-1 alpha-2 country code of the customer (e.g., 'NG', 'US').",
										"examples": [
											"NG"
										]
									},
									"meta": {
										"type": "object",
										"description": "Optional meta data you can attach to the customer."
									}
								}
							},
							"examples": {
								"basicCustomer": {
									"summary": "Minimal, name, email, phone, country",
									"value": {
										"fullName": "Jane Smith",
										"email": "jane.smith@example.com",
										"phone": "+2348192837465",
										"countryCode": "NG"
									}
								},
								"customerWithMeta": {
									"summary": "With custom meta data",
									"value": {
										"fullName": "Jane Smith",
										"email": "jane.smith@example.com",
										"phone": "+2348192837465",
										"countryCode": "NG",
										"meta": {
											"externalId": "usr_abc123",
											"tier": "premium"
										}
									}
								}
							}
						}
					}
				},
				"responses": {
					"201": {
						"description": "Customer created successfully. Returns the newly created customer object.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/Customer"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Customer created",
										"value": {
											"data": {
												"name": "Jane Smith",
												"email": "jane.smith@example.com",
												"phone": "+2348192837465",
												"customerId": "69d5ffe1ab82306f11b032f3",
												"reference": "afx121011",
												"countryCode": "NG",
												"createdAt": "2026-04-08T07:12:33.519Z",
												"updatedAt": "2026-04-08T07:12:33.519Z"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingPhone": {
										"summary": "Missing required field (phone)",
										"value": {
											"code": "INVALID_BUSINESS_CUSTOMER_REQUEST",
											"error": "Invalid business customer request",
											"details": {
												"errorMessage": "Invalid business customer request",
												"friendlyMessage": "No customer phone provided"
											}
										}
									},
									"invalidEmail": {
										"summary": "Invalid email format",
										"value": {
											"code": "INVALID_BUSINESS_CUSTOMER_REQUEST",
											"error": "Invalid business customer request",
											"details": {
												"errorMessage": "Invalid business customer request",
												"friendlyMessage": "Invalid customer email provided: INVALID_EMAIL"
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const customer = await afriex.customers.create({\n  fullName: \"John Doe\",\n  email: \"john@example.com\",\n  phone: \"+1234567890\",\n  countryCode: \"US\",\n});\n"
					}
				]
			},
			"get": {
				"operationId": "listCustomers",
				"summary": "Get customer list",
				"description": "Retrieves a paginated list of customers.",
				"tags": [
					"Customers"
				],
				"parameters": [
					{
						"name": "page",
						"in": "query",
						"description": "Page number for pagination (starting from 0)",
						"required": false,
						"schema": {
							"type": "integer",
							"minimum": 0,
							"default": 0
						}
					},
					{
						"name": "limit",
						"in": "query",
						"description": "Number of items per page",
						"required": false,
						"schema": {
							"type": "integer",
							"minimum": 1,
							"maximum": 100,
							"default": 10
						}
					},
					{
						"name": "email",
						"in": "query",
						"description": "Filter by customer email address (exact match, case-insensitive).",
						"required": false,
						"schema": {
							"type": "string",
							"format": "email",
							"examples": [
								"john.doe@example.com"
							]
						}
					},
					{
						"name": "phone",
						"in": "query",
						"description": "Filter by customer phone number in E.164 format.",
						"required": false,
						"schema": {
							"type": "string",
							"examples": [
								"+2348192837465"
							]
						}
					}
				],
				"responses": {
					"200": {
						"description": "List of customers retrieved successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "array",
											"items": {
												"$ref": "#/components/schemas/Customer"
											}
										},
										"page": {
											"type": "integer",
											"description": "Current page number"
										},
										"total": {
											"type": "integer",
											"description": "Total number of customers matching the query"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Customer list retrieved",
										"value": {
											"data": [
												{
													"name": "Addams Oshay",
													"email": "addams@example.com",
													"phone": "+15086340138",
													"customerId": "6929843e2c4653277440acc0",
													"reference": "afx121011",
													"countryCode": "US",
													"createdAt": "2025-11-28T11:15:10.812Z",
													"updatedAt": "2025-11-28T11:15:10.812Z"
												},
												{
													"name": "Daniel Obirije",
													"email": "daniel@example.com",
													"phone": "+2347049861191",
													"customerId": "6930610b0d8aab4a00b3f918",
													"reference": "afx121011",
													"countryCode": "NG",
													"createdAt": "2025-12-03T16:10:51.291Z",
													"updatedAt": "2025-12-03T16:10:51.291Z"
												}
											],
											"total": 1448,
											"page": 0
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request parameters.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'page' must be a number",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const response = await afriex.customers.list({\n  page: 0,\n  limit: 20,\n  email: \"john@example.com\",\n});\n\nconsole.log(response.data);  // Customer[]\nconsole.log(response.total); // Total count\n"
					}
				]
			}
		},
		"/api/v1/customer/{customerId}": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-signature"
				},
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "getCustomer",
				"summary": "Get customer by ID",
				"description": "Retrieves a specific customer by their unique identifier. The response includes the customer's `reference`, which is the value to supply as the pool-account `reference` when submitting a payment proof.",
				"tags": [
					"Customers"
				],
				"parameters": [
					{
						"name": "customerId",
						"in": "path",
						"description": "The unique identifier of the customer",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Customer retrieved successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/Customer"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Customer retrieved",
										"value": {
											"data": {
												"name": "Jane Smith",
												"email": "jane.smith@example.com",
												"phone": "+2348192837465",
												"customerId": "69d5ffe1ab82306f11b032f3",
												"reference": "afx121011",
												"countryCode": "NG",
												"createdAt": "2026-04-08T07:12:33.519Z",
												"updatedAt": "2026-04-08T07:12:33.519Z"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid customer ID format.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'customerId' must be a string",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Customer not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Customer not found",
										"value": {
											"code": "BUSINESS_CUSTOMER_NOT_FOUND",
											"error": "Business customer not found",
											"details": {
												"errorMessage": "Business customer not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const customer = await afriex.customers.get(\"customer-id\");\n"
					}
				]
			},
			"patch": {
				"operationId": "updateCustomer",
				"summary": "Update customer profile",
				"description": "Partially updates a customer's profile. Send at least one of `fullName`, `email`, or `phone`; omitted fields are left unchanged.",
				"tags": [
					"Customers"
				],
				"parameters": [
					{
						"name": "customerId",
						"in": "path",
						"description": "The unique identifier of the customer",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"description": "Partial profile update. At least one of fullName, email, or phone must be present.",
								"properties": {
									"fullName": {
										"type": "string",
										"description": "The full name of the customer."
									},
									"email": {
										"type": "string",
										"format": "email",
										"description": "The email of the customer."
									},
									"phone": {
										"type": "string",
										"description": "The phone number of the customer in E.164 format."
									}
								},
								"minProperties": 1,
								"additionalProperties": false
							},
							"examples": {
								"name": {
									"summary": "Update name only",
									"value": {
										"fullName": "Jane Doe"
									}
								},
								"contact": {
									"summary": "Update email and phone",
									"value": {
										"email": "jane.doe@example.com",
										"phone": "+2348192837465"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Customer updated successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/Customer"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Profile updated",
										"value": {
											"data": {
												"name": "Jane Doe",
												"email": "jane.doe@example.com",
												"phone": "+2348192837465",
												"customerId": "69d5ffe1ab82306f11b032f3",
												"reference": "afx121011",
												"countryCode": "NG",
												"createdAt": "2026-04-08T07:12:33.519Z",
												"updatedAt": "2026-04-08T07:20:11.004Z"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: value must contain at least one of [fullName, email, phone]",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Customer not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Customer not found",
										"value": {
											"code": "BUSINESS_CUSTOMER_NOT_FOUND",
											"error": "Business customer not found",
											"details": {
												"errorMessage": "Business customer not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const customer = await afriex.customers.update(\"customer-id\", {\n  fullName: \"Jane Doe\",\n});\n"
					}
				]
			},
			"delete": {
				"operationId": "deleteCustomer",
				"summary": "Delete customer by ID",
				"description": "Deletes a specific customer by their unique identifier.",
				"tags": [
					"Customers"
				],
				"parameters": [
					{
						"name": "customerId",
						"in": "path",
						"description": "The unique identifier of the customer",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Customer deleted successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": [
												"object",
												"null"
											],
											"description": "Empty on success."
										}
									}
								},
								"examples": {
									"deleted": {
										"summary": "Customer deleted",
										"value": {
											"data": null
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid customer ID format.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'customerId' must be a string",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Customer not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Customer not found",
										"value": {
											"code": "BUSINESS_CUSTOMER_NOT_FOUND",
											"error": "Business customer not found",
											"details": {
												"errorMessage": "Business customer not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "await afriex.customers.delete(\"customer-id\");\n"
					}
				]
			}
		},
		"/api/v1/customer/{customerId}/kyc": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"patch": {
				"operationId": "updateCustomerKyc",
				"summary": "Update customer KYC information",
				"description": "Partially updates a customer's KYC information.",
				"tags": [
					"Customers"
				],
				"parameters": [
					{
						"name": "customerId",
						"in": "path",
						"description": "The unique identifier of the customer",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"description": "A flat map of KYC document types to their values. Send the document map directly as the request body (do not wrap it in a `kyc` field). Each key must be one of the allowed KYC document types and each value is a string.",
								"additionalProperties": {
									"type": "string"
								},
								"propertyNames": {
									"enum": [
										"REPRESENTATIVE_TYPE",
										"DATE_OF_BIRTH",
										"ADDRESS",
										"BANK_STATEMENT",
										"BUSINESS_CERTIFICATE",
										"COUNTRY",
										"ID_FRONT",
										"ID_BACK",
										"PHONE",
										"SELFIE",
										"PROOF_OF_ADDRESS",
										"PROOF_OF_INCOME",
										"BVN",
										"DRIVER_LICENSE",
										"PASSPORT",
										"NATIONAL_ID",
										"PAYMENT_METHOD",
										"RESIDENCE_PERMIT",
										"VEHICLE_REGISTRATION",
										"VOTER_ID",
										"OTHERS"
									]
								},
								"examples": [
									{
										"PASSPORT": "passport.png",
										"DATE_OF_BIRTH": "2000-01-01",
										"COUNTRY": "KE"
									}
								]
							},
							"examples": {
								"bvnAndDob": {
									"summary": "BVN and date of birth (Nigeria)",
									"value": {
										"BVN": "22222222222",
										"DATE_OF_BIRTH": "1990-05-15",
										"COUNTRY": "NG"
									}
								},
								"passport": {
									"summary": "Passport number",
									"value": {
										"PASSPORT": "A12345678",
										"DATE_OF_BIRTH": "1990-05-15",
										"COUNTRY": "GH"
									}
								},
								"nationalId": {
									"summary": "National ID",
									"value": {
										"NATIONAL_ID": "GHA-123456789-0",
										"DATE_OF_BIRTH": "1990-05-15",
										"COUNTRY": "GH"
									}
								},
								"driverLicense": {
									"summary": "Driver's license",
									"value": {
										"DRIVER_LICENSE": "DL-987654",
										"DATE_OF_BIRTH": "1990-05-15",
										"COUNTRY": "KE"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Customer updated successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/Customer"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "KYC updated",
										"value": {
											"data": {
												"name": "Test User KYC",
												"email": "test.kyc.user@example.com",
												"phone": "+2348192837001",
												"customerId": "69d5fff7ab82306f11b0330e",
												"reference": "afx121011",
												"countryCode": "NG",
												"meta": {
													"kyc": {
														"data": {
															"BVN": "22222222222",
															"DATE_OF_BIRTH": "2000-01-15",
															"COUNTRY": "NG"
														}
													}
												},
												"createdAt": "2026-04-08T07:12:55.888Z",
												"updatedAt": "2026-04-08T07:17:18.638Z"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"invalidKycType": {
										"summary": "Invalid KYC document type key",
										"value": {
											"code": "INVALID_KYC_DOCUMENT_TYPE",
											"error": "Invalid kyc document type",
											"details": {
												"errorMessage": "Invalid kyc document type",
												"friendlyMessage": "Invalid KYC document type provided"
											}
										}
									},
									"invalidBvn": {
										"summary": "Invalid BVN value",
										"value": {
											"code": "INVALID_KYC_DOCUMENT_TYPE",
											"error": "Invalid kyc document type",
											"details": {
												"errorMessage": "Invalid kyc document type",
												"friendlyMessage": "Invalid BVN provided"
											}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Customer not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Customer not found",
										"value": {
											"code": "BUSINESS_CUSTOMER_NOT_FOUND",
											"error": "Business customer not found",
											"details": {
												"errorMessage": "Business customer not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const customer = await afriex.customers.updateKyc(\"customer-id\", {\n  kyc: {\n    documentType: \"passport\",\n    documentNumber: \"AB123456\",\n  },\n});\n"
					}
				]
			}
		},
		"/api/v1/customer/{customerId}/verify": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "verifyCustomer",
				"summary": "Verify a customer document",
				"description": "Runs an identity verification against a customer document. Today the only supported `docType` is `BVN` (Nigeria); `docValue` is the document number. Verification is rate limited per business.",
				"tags": [
					"Customers"
				],
				"parameters": [
					{
						"name": "customerId",
						"in": "path",
						"description": "The unique identifier of the customer",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"properties": {
									"docType": {
										"type": "string",
										"description": "The type of document to verify.",
										"enum": [
											"BVN"
										]
									},
									"docValue": {
										"type": "string",
										"minLength": 1,
										"description": "The document number to verify."
									}
								},
								"required": [
									"docType",
									"docValue"
								]
							},
							"examples": {
								"bvn": {
									"summary": "Verify a Nigerian BVN",
									"value": {
										"docType": "BVN",
										"docValue": "22222222222"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Customer verified successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/Customer"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Customer verified",
										"value": {
											"data": {
												"name": "Jane Smith",
												"email": "jane.smith@example.com",
												"phone": "+2348192837465",
												"customerId": "69d5ffe1ab82306f11b032f3",
												"reference": "afx121011",
												"countryCode": "NG",
												"createdAt": "2026-04-08T07:12:33.519Z",
												"updatedAt": "2026-04-08T07:21:09.872Z"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'docValue' is required",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Customer not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Customer not found",
										"value": {
											"code": "BUSINESS_CUSTOMER_NOT_FOUND",
											"error": "Business customer not found",
											"details": {
												"errorMessage": "Business customer not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"429": {
						"description": "Too many verification requests.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"rateLimited": {
										"summary": "Rate limit exceeded",
										"value": {
											"code": "RATE_LIMIT_EXCEEDED",
											"error": "Too many requests, please try again later",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const customer = await afriex.customers.verify(\"customer-id\", {\n  docType: \"BVN\",\n  docValue: \"22222222222\",\n});\n"
					}
				]
			}
		},
		"/api/v1/transaction": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "createTransaction",
				"summary": "Create a new transaction",
				"description": "Create a new transaction to process a payment for a customer. Use `type: WITHDRAW` to send funds to a destination payment method (requires `destinationId`), `type: DEPOSIT` to pull funds from a source payment method (requires `sourceId`), or `type: SWAP` to convert funds between currencies within the Afriex wallet (requires `sourceCurrency`, `destinationCurrency`, `meta`, and exactly one of `sourceAmount` or `destinationAmount`).\n",
				"tags": [
					"Transactions"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"properties": {
									"customerId": {
										"type": "string",
										"description": "The unique identifier of the customer. Required for DEPOSIT and WITHDRAW transactions. Not required for SWAP, if omitted, the transaction runs against the business wallet.",
										"examples": [
											"69528240ba52c13b669fb239"
										]
									},
									"type": {
										"type": "string",
										"description": "The type of transaction. DEPOSIT pulls funds from the customer's source payment method (requires sourceId). WITHDRAW sends funds to the customer's destination payment method (requires destinationId). SWAP converts funds between currencies within the Afriex wallet (requires sourceCurrency, destinationCurrency, meta, and exactly one of sourceAmount or destinationAmount; the API computes the other side at the live exchange rate, and sending both is rejected). If omitted, defaults to WITHDRAW.",
										"enum": [
											"DEPOSIT",
											"WITHDRAW",
											"SWAP"
										]
									},
									"sourceAmount": {
										"description": "The transaction amount in the source currency. For WITHDRAW, provide exactly one of sourceAmount or destinationAmount: sending sourceAmount alone lets the API compute destinationAmount at the live forward rate (useful when you know only how much you want to send, e.g. a SWIFT payout of a fixed source balance). For DEPOSIT the required amount is destinationAmount, so sourceAmount is optional. For SWAP, provide exactly one of sourceAmount or destinationAmount: setting sourceAmount makes the API compute destinationAmount at the live exchange rate.",
										"$ref": "#/components/schemas/amount"
									},
									"destinationAmount": {
										"description": "The transaction amount in the destination currency. Required for DEPOSIT. For WITHDRAW, provide exactly one of sourceAmount or destinationAmount: setting destinationAmount fixes the payout amount, while omitting it and sending sourceAmount lets the API compute destinationAmount at the live forward rate. For SWAP, provide exactly one of sourceAmount or destinationAmount: setting destinationAmount instead makes the API compute sourceAmount at the inverse rate. Sending both amounts on a SWAP is rejected.",
										"$ref": "#/components/schemas/amount"
									},
									"destinationCurrency": {
										"type": "string",
										"description": "The 3-letter ISO 4217 currency code of the destination currency (e.g., USD, NGN).",
										"examples": [
											"USD"
										]
									},
									"sourceCurrency": {
										"type": "string",
										"description": "The 3-letter ISO 4217 currency code of the source currency (e.g., USD, NGN).",
										"examples": [
											"NGN"
										]
									},
									"destinationId": {
										"type": "string",
										"description": "Required for WITHDRAW transactions. The id of the destination payment method that money will be sent to.\n",
										"examples": [
											"690df3281c11eea59108fcaf"
										]
									},
									"sourceId": {
										"type": "string",
										"description": "Required for DEPOSIT transactions. The id of the source payment method that money will be pulled from.\n",
										"examples": [
											"690df3281c11eea59108fcaf"
										]
									},
									"meta": {
										"description": "Transaction metadata. idempotencyKey and reference are required.",
										"$ref": "#/components/schemas/TransactionMeta"
									},
									"shouldPreferSourceAmount": {
										"type": "boolean",
										"description": "Opt in to deriving destinationAmount from sourceAmount even when both amounts are sent. Defaults to false, which keeps destination-wins semantics so a caller that echoes both amounts still gets the destinationAmount they asked for. Set true to have sourceAmount drive the payout via the forward rate."
									},
									"correspondentBankName": {
										"type": "string",
										"description": "The correspondent (intermediary) bank name for USD payouts (WITHDRAW with destinationCurrency USD and meta.settlement 'request'). Only used as a fallback when the destination payment method lacks it — the payment method's value takes precedence. Must be provided together with correspondentBankAccountNumber."
									},
									"correspondentBankAccountNumber": {
										"type": "string",
										"description": "The correspondent (intermediary) bank account number for USD payouts (WITHDRAW with destinationCurrency USD and meta.settlement 'request'). Only used as a fallback when the destination payment method lacks it — the payment method's value takes precedence. Must be provided together with correspondentBankName."
									}
								},
								"oneOf": [
									{
										"title": "Withdraw",
										"description": "Send funds to a customer's destination payment method. This is the default when type is omitted. Provide exactly one of sourceAmount or destinationAmount; sending sourceAmount alone lets the API compute the destination side at the live forward rate.",
										"required": [
											"customerId",
											"sourceCurrency",
											"destinationCurrency",
											"destinationId",
											"meta"
										],
										"properties": {
											"type": {
												"enum": [
													"WITHDRAW"
												]
											}
										}
									},
									{
										"title": "Deposit",
										"description": "Pull funds from a customer's source payment method.",
										"required": [
											"type",
											"customerId",
											"destinationAmount",
											"sourceCurrency",
											"destinationCurrency",
											"sourceId",
											"meta"
										],
										"properties": {
											"type": {
												"enum": [
													"DEPOSIT"
												]
											}
										}
									},
									{
										"title": "Swap",
										"description": "Convert funds between currencies within the Afriex wallet. Provide exactly one of sourceAmount or destinationAmount; sending both is rejected.",
										"required": [
											"type",
											"sourceCurrency",
											"destinationCurrency",
											"meta"
										],
										"properties": {
											"type": {
												"enum": [
													"SWAP"
												]
											}
										}
									}
								]
							},
							"examples": {
								"Withdraw": {
									"summary": "Withdraw (destination amount): fix the payout amount the customer receives",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "WITHDRAW",
										"destinationAmount": 5000,
										"sourceCurrency": "USD",
										"destinationCurrency": "NGN",
										"destinationId": "690df3281c11eea59108fcaf",
										"meta": {
											"reference": "ref-withdraw-001",
											"idempotencyKey": "idem-withdraw-001"
										}
									}
								},
								"WithdrawSourceAmount": {
									"summary": "Withdraw (source amount, SWIFT MZN→USD): send the full source balance and let the API compute the payout at the live forward rate",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "WITHDRAW",
										"sourceAmount": 10000,
										"sourceCurrency": "MZN",
										"destinationCurrency": "USD",
										"destinationId": "690df3281c11eea59108fcaf",
										"meta": {
											"reference": "ref-withdraw-002",
											"idempotencyKey": "idem-withdraw-002"
										}
									}
								},
								"Deposit": {
									"summary": "Deposit, pull funds from a customer's source payment method",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "DEPOSIT",
										"sourceAmount": "10",
										"destinationAmount": 5000,
										"sourceCurrency": "USD",
										"destinationCurrency": "NGN",
										"sourceId": "690df3281c11eea59108fcaf",
										"meta": {
											"reference": "ref-deposit-001",
											"idempotencyKey": "idem-deposit-001"
										}
									}
								},
								"Swap": {
									"summary": "Swap (source-only): convert funds between currencies within the Afriex wallet",
									"value": {
										"type": "SWAP",
										"sourceAmount": 10,
										"sourceCurrency": "USD",
										"destinationCurrency": "NGN",
										"meta": {
											"reference": "ref-swap-001",
											"idempotencyKey": "idem-swap-001"
										}
									}
								},
								"SwapDestination": {
									"summary": "Swap (destination-only): the API computes the source amount at the inverse rate",
									"value": {
										"type": "SWAP",
										"destinationAmount": 16500,
										"sourceCurrency": "USD",
										"destinationCurrency": "NGN",
										"meta": {
											"reference": "ref-swap-002",
											"idempotencyKey": "idem-swap-002"
										}
									}
								}
							}
						}
					}
				},
				"responses": {
					"201": {
						"description": "Transaction created successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/Transaction"
										}
									}
								},
								"examples": {
									"withdraw": {
										"summary": "WITHDRAW transaction created (pending)",
										"value": {
											"data": {
												"status": "PENDING",
												"type": "WITHDRAW",
												"channel": "BANK_ACCOUNT",
												"sourceAmount": "3.28847",
												"sourceCurrency": "USD",
												"destinationAmount": "5000",
												"destinationCurrency": "NGN",
												"destinationId": "690df3281c11eea59108fcaf",
												"customerId": "69528240ba52c13b669fb239",
												"transactionId": "69d60071ab82306f11b03393",
												"meta": {
													"reference": "ref-withdraw-001",
													"idempotencyKey": "idem-withdraw-001"
												},
												"createdAt": "2026-04-08T07:14:57.444Z",
												"updatedAt": "2026-04-08T07:14:57.444Z"
											}
										}
									},
									"swap": {
										"summary": "SWAP transaction created (success)",
										"value": {
											"data": {
												"status": "SUCCESS",
												"type": "SWAP",
												"channel": "WALLET",
												"sourceAmount": "10",
												"sourceCurrency": "USD",
												"destinationAmount": "14101.041",
												"destinationCurrency": "NGN",
												"destinationId": "",
												"customerId": "",
												"transactionId": "69d60072ab82306f11b033b9",
												"meta": {
													"reference": "ref-swap-001",
													"idempotencyKey": "idem-swap-001"
												},
												"createdAt": "2026-04-08T07:14:58.237Z",
												"updatedAt": "2026-04-08T07:14:58.237Z"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"swapBothAmounts": {
										"summary": "SWAP with both amounts provided",
										"value": {
											"code": "INVALID_BUSINESS_TRANSACTION_REQUEST",
											"error": "Invalid business transaction request",
											"details": {
												"errorMessage": "Invalid business transaction request",
												"friendlyMessage": "Only one of source amount or destination amount can be provided"
											}
										}
									},
									"missingDestinationAmount": {
										"summary": "Missing destination amount",
										"value": {
											"code": "INVALID_BUSINESS_TRANSACTION_REQUEST",
											"error": "Invalid business transaction request",
											"details": {
												"errorMessage": "Invalid business transaction request",
												"friendlyMessage": "Invalid destination amount"
											}
										}
									},
									"invalidCurrency": {
										"summary": "Invalid currency code",
										"value": {
											"code": "INVALID_BUSINESS_TRANSACTION_REQUEST",
											"error": "Invalid business transaction request",
											"details": {
												"errorMessage": "Invalid business transaction request",
												"friendlyMessage": "Invalid source currency"
											}
										}
									},
									"missingIdempotencyKey": {
										"summary": "Missing idempotency key",
										"value": {
											"code": "INVALID_BUSINESS_TRANSACTION_REQUEST",
											"error": "Invalid business transaction request",
											"details": {
												"errorMessage": "Invalid business transaction request",
												"friendlyMessage": "No idempotency key provided"
											}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"customerNotFound": {
										"summary": "Customer not found",
										"value": {
											"code": "USER_NOT_FOUND",
											"error": "User not found",
											"details": {
												"errorMessage": "User not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const transaction = await afriex.transactions.create({\n  customerId: \"customer-id\",\n  sourceAmount: \"10\",\n  destinationAmount: \"5000\",\n  sourceCurrency: \"USD\",\n  destinationCurrency: \"NGN\",\n  destinationId: \"payment-method-id\",\n  meta: {\n    idempotencyKey: \"unique-key-123\",\n    reference: \"order-456\",\n    narration: \"Payment for services\",\n  },\n});\n"
					}
				]
			},
			"get": {
				"operationId": "listTransactions",
				"summary": "Get transaction list",
				"description": "Retrieves a paginated list of transactions.",
				"tags": [
					"Transactions"
				],
				"parameters": [
					{
						"name": "page",
						"in": "query",
						"description": "Zero-based page number for pagination.",
						"required": false,
						"schema": {
							"type": "integer",
							"minimum": 0,
							"default": 0
						}
					},
					{
						"name": "limit",
						"in": "query",
						"description": "Number of items per page (max 100).",
						"required": false,
						"schema": {
							"type": "integer",
							"minimum": 1,
							"maximum": 100,
							"default": 10
						}
					},
					{
						"name": "transactionId",
						"in": "query",
						"description": "Filter by the Afriex transaction ID (`transactionId`) returned when the transaction was created.",
						"required": false,
						"schema": {
							"type": "string"
						}
					},
					{
						"name": "reference",
						"in": "query",
						"description": "Filter by the merchant-supplied reference set in `meta.reference` at transaction creation.",
						"required": false,
						"schema": {
							"type": "string"
						}
					},
					{
						"name": "status",
						"in": "query",
						"description": "Filter by one or more transaction statuses. Use a comma-separated list for multiple values (e.g. `?status=PENDING,PROCESSING`).",
						"required": false,
						"schema": {
							"type": "array",
							"items": {
								"type": "string",
								"enum": [
									"PENDING",
									"PROCESSING",
									"SUCCESS",
									"FAILED",
									"CANCELLED",
									"REFUNDED",
									"RETRY",
									"UNKNOWN",
									"SCHEDULED",
									"CUSTOMER_ACTION_REQUIRED",
									"REJECTED",
									"IN_REVIEW",
									"DISPUTED",
									"DISPUTE_RESOLVED",
									"DISPUTE_WON",
									"DISPUTE_LOST",
									"DISPUTE_EVIDENCE_SUBMITTED"
								]
							}
						},
						"style": "form",
						"explode": false
					},
					{
						"name": "type",
						"in": "query",
						"description": "Filter by one or more transaction types. Use a comma-separated list for multiple values (e.g. `?type=DEPOSIT,WITHDRAW`).",
						"required": false,
						"schema": {
							"type": "array",
							"items": {
								"type": "string",
								"enum": [
									"DEPOSIT",
									"WITHDRAW",
									"SWAP"
								]
							}
						},
						"style": "form",
						"explode": false
					},
					{
						"name": "channel",
						"in": "query",
						"description": "Filter by one or more payment channels (source or destination). Use a comma-separated list for multiple values (e.g. `?channel=BANK_ACCOUNT,MOBILE_MONEY`).",
						"required": false,
						"schema": {
							"type": "array",
							"items": {
								"type": "string",
								"enum": [
									"BANK_ACCOUNT",
									"MOBILE_MONEY",
									"CARD",
									"CRYPTO",
									"VIRTUAL_BANK_ACCOUNT",
									"ACH_BANK_ACCOUNT",
									"INTERAC",
									"PAYBILL_TILL",
									"RFP",
									"UPI",
									"VIRTUAL_CARD",
									"SWIFT",
									"WE_CHAT",
									"ALIPAY",
									"WALLET"
								]
							}
						},
						"style": "form",
						"explode": false
					},
					{
						"name": "currency",
						"in": "query",
						"description": "Filter by one or more 3-letter ISO 4217 currency codes (source or destination). Use a comma-separated list for multiple values (e.g. `?currency=USD,NGN`).",
						"required": false,
						"schema": {
							"type": "array",
							"items": {
								"type": "string",
								"examples": [
									"USD"
								]
							}
						},
						"style": "form",
						"explode": false
					},
					{
						"name": "fromDate",
						"in": "query",
						"description": "Return only transactions created on or after this ISO 8601 date-time (e.g. `2025-01-01T00:00:00.000Z`).",
						"required": false,
						"schema": {
							"type": "string",
							"format": "date-time"
						}
					},
					{
						"name": "toDate",
						"in": "query",
						"description": "Return only transactions created on or before this ISO 8601 date-time. Must be equal to or later than `fromDate`.",
						"required": false,
						"schema": {
							"type": "string",
							"format": "date-time"
						}
					}
				],
				"responses": {
					"200": {
						"description": "List of transactions retrieved successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "array",
											"items": {
												"$ref": "#/components/schemas/Transaction"
											}
										},
										"page": {
											"type": "integer",
											"description": "Current page number"
										},
										"total": {
											"type": "integer",
											"description": "Total number of transactions matching the query"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Transaction list retrieved",
										"value": {
											"data": [
												{
													"status": "SUCCESS",
													"type": "SWAP",
													"channel": "WALLET",
													"sourceAmount": "10",
													"sourceCurrency": "USD",
													"destinationAmount": "14101.041",
													"destinationCurrency": "NGN",
													"destinationId": "",
													"customerId": "68e6717848e1f632e9686460",
													"transactionId": "69d3c79531c0234586ad5ee0",
													"meta": {
														"reference": "ref-swap-minimal-002",
														"idempotencyKey": "idem-swap-minimal-002"
													},
													"createdAt": "2026-04-06T14:47:49.166Z",
													"updatedAt": "2026-04-06T14:47:49.166Z"
												},
												{
													"status": "PENDING",
													"type": "WITHDRAW",
													"channel": "BANK_ACCOUNT",
													"sourceAmount": "3.28847",
													"sourceCurrency": "USD",
													"destinationAmount": "5000",
													"destinationCurrency": "NGN",
													"destinationId": "690df3281c11eea59108fcaf",
													"customerId": "69528240ba52c13b669fb239",
													"transactionId": "69d60071ab82306f11b03393",
													"meta": {
														"reference": "ref-withdraw-001",
														"idempotencyKey": "idem-withdraw-001"
													},
													"createdAt": "2026-04-08T07:14:57.444Z",
													"updatedAt": "2026-04-08T07:14:57.444Z"
												}
											],
											"total": 285,
											"page": 0
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request parameters.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'page' must be a number",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const response = await afriex.transactions.list({\n  page: 0,\n  limit: 20,\n  status: [\"PENDING\", \"PROCESSING\"],\n  currency: [\"USD\", \"NGN\"],\n  fromDate: \"2026-01-01T00:00:00.000Z\",\n  toDate: \"2026-01-31T23:59:59.999Z\",\n});\n\nconsole.log(response.data); // Transaction[]\n"
					}
				]
			}
		},
		"/api/v1/transaction/{transactionId}": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-signature"
				},
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "getTransaction",
				"summary": "Get transaction by ID",
				"description": "Retrieves a specific transaction by its unique identifier.",
				"tags": [
					"Transactions"
				],
				"parameters": [
					{
						"name": "transactionId",
						"in": "path",
						"description": "The unique identifier of the transaction",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Transaction retrieved successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/Transaction"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Transaction retrieved",
										"value": {
											"data": {
												"status": "SUCCESS",
												"type": "SWAP",
												"channel": "WALLET",
												"sourceAmount": "10",
												"sourceCurrency": "USD",
												"destinationAmount": "14101.041",
												"destinationCurrency": "NGN",
												"destinationId": "",
												"customerId": "68e6717848e1f632e9686460",
												"transactionId": "69d3c79531c0234586ad5ee0",
												"meta": {
													"reference": "ref-swap-minimal-002",
													"idempotencyKey": "idem-swap-minimal-002"
												},
												"createdAt": "2026-04-06T14:47:49.166Z",
												"updatedAt": "2026-04-06T14:47:49.166Z"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid transaction ID format.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'transactionId' must be a string",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Transaction not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Transaction not found",
										"value": {
											"code": "BUSINESS_TRANSACTION_NOT_FOUND",
											"error": "Business transaction not found",
											"details": {
												"errorMessage": "Business transaction not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const transaction = await afriex.transactions.get(\"transaction-id\");\n"
					}
				]
			}
		},
		"/api/v1/transaction/{transactionId}/authorize": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "authorizeTransaction",
				"summary": "Authorize a pending transaction",
				"description": "Completes a transaction that was created in a `CUSTOMER_ACTION_REQUIRED` state and needs an extra authorization step (for example, a one-time password on a mobile-money deposit). The body is discriminated by `type`; today the only supported variant is `OTP`.",
				"tags": [
					"Transactions"
				],
				"parameters": [
					{
						"name": "transactionId",
						"in": "path",
						"description": "The unique identifier of the transaction",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"properties": {
									"type": {
										"type": "string",
										"description": "The authorization method.",
										"enum": [
											"OTP"
										]
									},
									"otp": {
										"type": "string",
										"description": "The one-time password supplied by the customer."
									}
								},
								"required": [
									"type",
									"otp"
								]
							},
							"examples": {
								"otp": {
									"summary": "Authorize a deposit with an OTP",
									"value": {
										"type": "OTP",
										"otp": "123456"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Transaction authorized successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/Transaction"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Transaction authorized",
										"value": {
											"data": {
												"status": "PROCESSING",
												"type": "DEPOSIT",
												"channel": "MOBILE_MONEY",
												"sourceAmount": "10",
												"sourceCurrency": "USD",
												"destinationAmount": "14101.041",
												"destinationCurrency": "NGN",
												"customerId": "68e6717848e1f632e9686460",
												"transactionId": "69d3c79531c0234586ad5ee0",
												"meta": {
													"reference": "ref-deposit-001",
													"idempotencyKey": "idem-deposit-001"
												},
												"createdAt": "2026-04-06T14:47:49.166Z",
												"updatedAt": "2026-04-06T14:49:02.110Z"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'otp' is required",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Transaction not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Transaction not found",
										"value": {
											"code": "BUSINESS_TRANSACTION_NOT_FOUND",
											"error": "Business transaction not found",
											"details": {
												"errorMessage": "Business transaction not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const transaction = await afriex.transactions.authorize(\"transaction-id\", {\n  type: \"OTP\",\n  otp: \"123456\",\n});\n"
					}
				]
			}
		},
		"/api/v1/transaction/{transactionId}/advice": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-signature"
				},
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "getTransactionAdvice",
				"summary": "Get settlement & remittance advice",
				"description": "Returns a short-lived presigned download URL for the settlement & remittance advice PDF auto-generated for a USD withdrawal from your collection wallet (a withdrawal created with `settlement: \"request\"`). The advice is issued with status `PENDING` when the withdrawal is created and regenerated with status `COMPLETED` (same reference, incremented version) once the withdrawal succeeds. Scoped to your business: you can only fetch advices for your own transactions. This document is a settlement and remittance advice, not a tax invoice.",
				"tags": [
					"Transactions"
				],
				"parameters": [
					{
						"name": "transactionId",
						"in": "path",
						"description": "The unique identifier of the transaction",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Settlement advice download URL retrieved successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "object",
											"properties": {
												"url": {
													"type": "string",
													"description": "Short-lived (5 minute) presigned S3 URL for the advice PDF."
												},
												"reference": {
													"type": "string",
													"description": "Stable advice reference number. Generated once per transaction and reused across regenerations."
												},
												"status": {
													"type": "string",
													"enum": [
														"PENDING",
														"COMPLETED"
													],
													"description": "PENDING until the withdrawal succeeds, COMPLETED afterwards."
												},
												"version": {
													"type": "integer",
													"description": "Regeneration counter. Starts at 1 at creation and increments when the advice is regenerated on completion."
												},
												"generatedAt": {
													"type": "string",
													"format": "date-time"
												}
											}
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Advice retrieved",
										"value": {
											"data": {
												"url": "https://example-bucket.s3.amazonaws.com/<redacted-object-key>.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=...",
												"reference": "ADV-EXAMPLE-0001",
												"status": "PENDING",
												"version": 1,
												"generatedAt": "2026-01-01T00:00:00.000Z"
											}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Transaction not found, or no settlement advice exists for this transaction (only USD withdrawals from the collection wallet qualify).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Transaction or advice not found",
										"value": {
											"code": "BUSINESS_TRANSACTION_NOT_FOUND",
											"error": "Business transaction not found",
											"details": {
												"errorMessage": "No settlement advice exists for this transaction",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const advice = await afriex.transactions.getAdvice(\"transaction-id\");\n"
					}
				]
			}
		},
		"/api/v1/transaction/pool-account": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-signature"
				},
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "submitPoolAccountPaymentProof",
				"summary": "Submit a pool-account payment proof",
				"description": "Submits proof of a deposit made to the business pool account. The request creates a business deposit transaction in `IN_REVIEW` status; an operator confirms the bank inflow before the funds are credited. The response returns that transaction. Duplicate submissions of the same business, customer, amount, reference, timestamp and sender details within the configured idempotency window are rejected.",
				"tags": [
					"Transactions"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"$ref": "#/components/schemas/PoolAccountPaymentProofRequest"
							},
							"examples": {
								"minimal": {
									"summary": "Submit a pool-account proof of payment",
									"value": {
										"amount": 5000,
										"customerId": "6929843e2c4653277440acc0",
										"countryCode": "NG",
										"reference": "6929843e2c4653277440acc0",
										"fileKey": "64f0c2a1e4b0a1b2c3d4e5f6/proof.pdf",
										"timestamp": "2026-01-01T12:00:00.000Z"
									}
								},
								"withSenderDetails": {
									"summary": "Submit a proof with sender details",
									"value": {
										"amount": 5000,
										"customerId": "6929843e2c4653277440acc0",
										"countryCode": "NG",
										"reference": "6929843e2c4653277440acc0",
										"fileKey": "64f0c2a1e4b0a1b2c3d4e5f6/proof.pdf",
										"timestamp": "2026-01-01T12:00:00.000Z",
										"senderDetails": {
											"name": "John Doe",
											"accountNumber": "0123456789",
											"bankName": "GTBank",
											"countryCode": "NG"
										}
									}
								}
							}
						}
					}
				},
				"responses": {
					"201": {
						"description": "Proof submitted successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/Transaction"
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingRequiredField": {
										"summary": "Missing required field",
										"value": {
											"code": "INVALID_BUSINESS_POOL_ACCOUNT_REQUEST",
											"error": "Invalid business pool account request",
											"details": {
												"errorMessage": "Invalid business pool account request",
												"friendlyMessage": "No amount provided"
											}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"409": {
						"description": "Duplicate submission within the idempotency window.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"duplicateRequest": {
										"summary": "Duplicate submission within the idempotency window",
										"value": {
											"code": "DUPLICATE_REQUEST",
											"error": "Duplicate request",
											"details": {
												"errorMessage": "Duplicate request",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "await afriex.transactions.submitPoolAccountPaymentProof({\n  amount: 5000,\n  customerId: \"customer-id\",\n  countryCode: \"NG\",\n  reference: \"pool-account-reference\",\n  fileKey: \"s3-object-key\",\n  timestamp: \"2026-01-01T12:00:00.000Z\",\n});\n"
					}
				]
			}
		},
		"/api/v1/payment-method": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-signature"
				},
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "createPaymentMethod",
				"summary": "Create a payment method",
				"description": "Creates a new payment method.",
				"tags": [
					"Payment Methods"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"required": [
									"channel",
									"accountName",
									"accountNumber",
									"countryCode",
									"institution"
								],
								"properties": {
									"channel": {
										"type": "string",
										"description": "The payment method channel",
										"enum": [
											"BANK_ACCOUNT",
											"MOBILE_MONEY",
											"VIRTUAL_BANK_ACCOUNT",
											"ACH_BANK_ACCOUNT",
											"INTERAC",
											"UPI",
											"SWIFT",
											"WE_CHAT",
											"ALIPAY",
											"PAYBILL_TILL"
										]
									},
									"customerId": {
										"description": "Optional. The customer to attach this payment method to. When omitted, it is attached to the business owner.",
										"$ref": "#/components/schemas/customerId"
									},
									"type": {
										"type": "string",
										"description": "The capability of this payment method. DEPOSIT means funds can be pulled from this method (e.g. charge/collect from the customer). WITHDRAW means funds can be sent to this method (e.g. pay out to the customer). If omitted, defaults to WITHDRAW.\n",
										"enum": [
											"DEPOSIT",
											"WITHDRAW"
										]
									},
									"accountName": {
										"type": "string",
										"description": "The name of the account holder. Must use Latin-script letters (A-Z / a-z, including accented forms such as é, ñ, ü, ç) or Chinese (Han) characters, digits (0-9), spaces and the characters & ( ) + , - . / : ? and apostrophe; it must contain at least one letter. Names in other scripts (e.g. Arabic, Cyrillic) or containing other symbols are rejected. Exception: WeChat and Alipay (WE_CHAT / ALIPAY channels) payouts accept the beneficiary's local-script (e.g. Chinese) name."
									},
									"accountNumber": {
										"type": "string",
										"description": "The account number"
									},
									"countryCode": {
										"type": "string",
										"description": "The ISO 3166-1 alpha-2 country code. This has to be one of the countries we support"
									},
									"institution": {
										"description": "The destination institution. For USD (SWIFT) payout payment methods, correspondentBankName and correspondentBankAccountNumber are mandatory.",
										"$ref": "#/components/schemas/PaymentMethodInstitution"
									},
									"recipient": {
										"$ref": "#/components/schemas/PaymentMethodRecipient"
									},
									"transaction": {
										"$ref": "#/components/schemas/PaymentMethodTransaction"
									}
								}
							},
							"examples": {
								"Bank Account": {
									"summary": "Bank Account, register a bank account to send funds to",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "WITHDRAW",
										"channel": "BANK_ACCOUNT",
										"accountName": "John Doe",
										"accountNumber": "0123456789",
										"countryCode": "NG",
										"institution": {
											"institutionCode": "058",
											"institutionName": "GTBank"
										}
									}
								},
								"SWIFT Transfer": {
									"summary": "SWIFT, register an international bank account via SWIFT",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "WITHDRAW",
										"channel": "SWIFT",
										"accountName": "John Doe",
										"accountNumber": "DE89370400440532013000",
										"countryCode": "DE",
										"institution": {
											"institutionCode": "DEUTDEDB",
											"institutionName": "Deutsche Bank",
											"institutionAddress": "Taunusanlage 12, 60262 Frankfurt am Main, Germany",
											"correspondentBankName": "Citibank N.A. New York",
											"correspondentBankAccountNumber": "10991234"
										},
										"recipient": {
											"recipientAddress": "Musterstraße 1, 10115 Berlin, Germany"
										},
										"transaction": {
											"transactionNarration": "Payment for services"
										}
									}
								},
								"Mobile Money": {
									"summary": "Mobile Money, register a mobile money account to send funds to",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "WITHDRAW",
										"channel": "MOBILE_MONEY",
										"accountName": "John Doe",
										"accountNumber": "0201234567",
										"countryCode": "GH",
										"institution": {
											"institutionCode": "MTN",
											"institutionName": "MTN"
										}
									}
								},
								"Mobile Money (Deposit)": {
									"summary": "Mobile Money, register a mobile money account to pull funds from",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "DEPOSIT",
										"channel": "MOBILE_MONEY",
										"accountName": "John Doe",
										"accountNumber": "0201234567",
										"countryCode": "GH",
										"institution": {
											"institutionCode": "MTN",
											"institutionName": "MTN"
										}
									}
								},
								"UPI": {
									"summary": "UPI, register a UPI ID to send funds to (India)",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "WITHDRAW",
										"channel": "UPI",
										"accountName": "Raj Kumar",
										"accountNumber": "rajkumar@upi",
										"countryCode": "IN",
										"institution": {
											"institutionCode": "UPI",
											"institutionName": "UPI"
										},
										"recipient": {
											"recipientPhone": "+919876543210"
										}
									}
								},
								"Interac": {
									"summary": "Interac, register an Interac e-Transfer recipient (Canada)",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "WITHDRAW",
										"channel": "INTERAC",
										"accountName": "John Doe",
										"accountNumber": "john.doe@email.com",
										"countryCode": "CA",
										"institution": {
											"institutionCode": "INTERAC",
											"institutionName": "INTERAC"
										},
										"recipient": {
											"recipientEmail": "john.doe@email.com"
										}
									}
								},
								"WeChat Pay": {
									"summary": "WeChat Pay, register a WeChat Pay account to send funds to (China)",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "WITHDRAW",
										"channel": "WE_CHAT",
										"accountName": "Zhang Wei",
										"accountNumber": "+8613812345678",
										"countryCode": "CN",
										"institution": {
											"institutionCode": "WECHAT",
											"institutionName": "WECHAT"
										},
										"recipient": {
											"recipientPhone": "+8613812345678"
										}
									}
								},
								"Alipay": {
									"summary": "Alipay, register an Alipay account to send funds to (China)",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "WITHDRAW",
										"channel": "ALIPAY",
										"accountName": "Zhang Wei",
										"accountNumber": "+8613812345678",
										"countryCode": "CN",
										"institution": {
											"institutionCode": "ALIPAY",
											"institutionName": "ALIPAY"
										},
										"recipient": {
											"recipientPhone": "+8613812345678"
										}
									}
								},
								"Paybill / Till": {
									"summary": "Paybill / Till, register an M-Pesa Paybill or Till number to send funds to (Kenya)",
									"value": {
										"customerId": "69528240ba52c13b669fb239",
										"type": "WITHDRAW",
										"channel": "PAYBILL_TILL",
										"accountName": "Safaricom PLC",
										"accountNumber": "174379",
										"countryCode": "KE",
										"institution": {
											"institutionCode": "MPESA",
											"institutionName": "MPESA"
										}
									}
								}
							}
						}
					}
				},
				"responses": {
					"201": {
						"description": "Payment method created successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/PaymentMethod"
										}
									}
								},
								"examples": {
									"bankAccount": {
										"summary": "Bank account payment method created",
										"value": {
											"data": {
												"paymentMethodId": "69d6002579101baa20f63816",
												"channel": "BANK_ACCOUNT",
												"customerId": "69d60024ab82306f11b03325",
												"institution": {
													"institutionCode": "000013",
													"institutionName": "GTBank"
												},
												"accountName": "John Doe",
												"accountNumber": "0123456789",
												"countryCode": "NG"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingRequiredField": {
										"summary": "Missing required field",
										"value": {
											"code": "INVALID_USER_DATA",
											"error": "Invalid user data",
											"details": {
												"errorMessage": "Invalid user data",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const paymentMethod = await afriex.paymentMethods.create({\n  channel: \"BANK_ACCOUNT\",\n  customerId: \"customer-id\",\n  accountName: \"John Doe\",\n  accountNumber: \"1234567890\",\n  countryCode: \"NG\",\n  institution: {\n    institutionCode: \"044\",\n    institutionName: \"Access Bank\",\n  },\n});\n"
					}
				]
			},
			"get": {
				"operationId": "listPaymentMethods",
				"summary": "Get payment method list",
				"description": "Retrieves a paginated list of payment methods.",
				"tags": [
					"Payment Methods"
				],
				"parameters": [
					{
						"name": "page",
						"in": "query",
						"description": "Page number for pagination (starting from 0)",
						"required": false,
						"schema": {
							"type": "integer",
							"minimum": 0,
							"default": 0
						}
					},
					{
						"name": "limit",
						"in": "query",
						"description": "Number of items per page",
						"required": false,
						"schema": {
							"type": "integer",
							"minimum": 1,
							"maximum": 100,
							"default": 10
						}
					},
					{
						"name": "channel",
						"in": "query",
						"description": "Filter by one or more payment channels. Use a comma-separated list for multiple values (e.g. `?channel=BANK_ACCOUNT,MOBILE_MONEY`).",
						"required": false,
						"schema": {
							"type": "array",
							"items": {
								"type": "string",
								"enum": [
									"BANK_ACCOUNT",
									"MOBILE_MONEY",
									"INTERAC",
									"UPI",
									"WE_CHAT",
									"VIRTUAL_BANK_ACCOUNT",
									"RFP",
									"SWIFT"
								]
							}
						},
						"style": "form",
						"explode": false
					},
					{
						"name": "currencies",
						"in": "query",
						"description": "Filter by one or more 3-letter ISO 4217 currency codes. Use a comma-separated list for multiple values (e.g. `?currencies=USD,NGN`).",
						"required": false,
						"schema": {
							"type": "array",
							"items": {
								"type": "string"
							}
						},
						"style": "form",
						"explode": false
					},
					{
						"name": "capabilities",
						"in": "query",
						"description": "Filter by payment method capability. Only `WITHDRAW` is currently supported. Defaults to `WITHDRAW` when omitted.",
						"required": false,
						"schema": {
							"type": "array",
							"items": {
								"type": "string",
								"enum": [
									"WITHDRAW"
								]
							},
							"default": [
								"WITHDRAW"
							]
						},
						"style": "form",
						"explode": false
					},
					{
						"name": "status",
						"in": "query",
						"description": "Filter by one or more payment method statuses. Defaults to `active,pending` when omitted.",
						"required": false,
						"schema": {
							"type": "array",
							"items": {
								"type": "string",
								"enum": [
									"active",
									"pending"
								]
							},
							"default": [
								"active",
								"pending"
							]
						},
						"style": "form",
						"explode": false
					}
				],
				"responses": {
					"200": {
						"description": "List of payment methods retrieved successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "array",
											"items": {
												"$ref": "#/components/schemas/PaymentMethod"
											}
										},
										"page": {
											"type": "integer",
											"description": "Current page number"
										},
										"total": {
											"type": "integer",
											"description": "Total number of payment methods matching the query"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Payment method list retrieved",
										"value": {
											"data": [
												{
													"paymentMethodId": "6936b8774f987b2994865b73",
													"channel": "BANK_ACCOUNT",
													"customerId": "6922e4520a53e858ab42efa8",
													"institution": {
														"institutionCode": "000013",
														"institutionName": "GTBank"
													},
													"accountName": "John Doe",
													"accountNumber": "1234567890",
													"countryCode": "NG"
												},
												{
													"paymentMethodId": "6936b8e54f987b2994865b8b",
													"channel": "BANK_ACCOUNT",
													"customerId": "6928515c6befd180bc451622",
													"institution": {
														"institutionCode": "000017",
														"institutionName": "WEMA BANK"
													},
													"accountName": "Test Account",
													"accountNumber": "1213131313",
													"countryCode": "NG"
												}
											],
											"total": 1006,
											"page": 0
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request parameters.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'page' must be a number",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const response = await afriex.paymentMethods.list({\n  page: 1,\n  limit: 20,\n});\n"
					}
				]
			}
		},
		"/api/v1/payment-method/{paymentMethodId}": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-signature"
				},
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "getPaymentMethod",
				"summary": "Get payment method by ID",
				"description": "Retrieves a specific payment method by its unique identifier.",
				"tags": [
					"Payment Methods"
				],
				"parameters": [
					{
						"name": "paymentMethodId",
						"in": "path",
						"description": "The unique identifier of the payment method",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Payment method retrieved successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/PaymentMethod"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Payment method retrieved",
										"value": {
											"data": {
												"paymentMethodId": "6936b8774f987b2994865b73",
												"channel": "BANK_ACCOUNT",
												"customerId": "6922e4520a53e858ab42efa8",
												"institution": {
													"institutionCode": "000013",
													"institutionName": "GTBank"
												},
												"accountName": "John Doe",
												"accountNumber": "1234567890",
												"countryCode": "NG"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Request error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'paymentMethodId' must be a string",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Payment method not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Payment method not found",
										"value": {
											"code": "BUSINESS_PAYMENT_METHOD_NOT_FOUND",
											"error": "Business payment method not found",
											"details": {
												"errorMessage": "Business payment method not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const paymentMethod = await afriex.paymentMethods.get(\"payment-method-id\");\n"
					}
				]
			},
			"delete": {
				"operationId": "deletePaymentMethod",
				"summary": "Delete payment method",
				"description": "Removes a payment method from the system.",
				"tags": [
					"Payment Methods"
				],
				"parameters": [
					{
						"name": "paymentMethodId",
						"in": "path",
						"description": "The unique identifier of the payment method",
						"required": true,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Payment method deleted successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object"
								},
								"examples": {
									"success": {
										"summary": "Payment method deleted",
										"value": {}
									}
								}
							}
						}
					},
					"400": {
						"description": "Request error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"validationError": {
										"summary": "Validation error",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'paymentMethodId' must be a string",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Payment method not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Payment method not found",
										"value": {
											"code": "BUSINESS_PAYMENT_METHOD_NOT_FOUND",
											"error": "Business payment method not found",
											"details": {
												"errorMessage": "Business payment method not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "await afriex.paymentMethods.delete(\"payment-method-id\");\n"
					}
				]
			}
		},
		"/api/v1/payment-method/institution": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-signature"
				},
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "listInstitutions",
				"summary": "Get list of payment method institutions by country",
				"description": "Retrieves a list of banks or mobile money providers available for a specific country.",
				"tags": [
					"Payment Methods"
				],
				"parameters": [
					{
						"name": "channel",
						"in": "query",
						"description": "The payment method channel",
						"required": true,
						"schema": {
							"type": "string",
							"enum": [
								"BANK_ACCOUNT",
								"SWIFT",
								"MOBILE_MONEY",
								"UPI",
								"INTERAC",
								"WE_CHAT"
							]
						}
					},
					{
						"name": "countryCode",
						"in": "query",
						"description": "The ISO 3166-1 alpha-2 country code",
						"required": true,
						"schema": {
							"type": "string",
							"enum": [
								"US",
								"NG",
								"GB",
								"DE",
								"FR",
								"CA",
								"ZA",
								"GH",
								"KE",
								"UG",
								"TZ",
								"RW",
								"CM",
								"CG",
								"GA",
								"CF",
								"CI",
								"BF",
								"ML",
								"SN",
								"TG",
								"BJ",
								"NE",
								"GN",
								"ZM",
								"ET",
								"MW",
								"MZ",
								"BW",
								"SL",
								"LR",
								"GM",
								"GW",
								"CV",
								"ST",
								"AO",
								"KM",
								"DJ",
								"SO",
								"SC",
								"MU",
								"SZ",
								"LS"
							]
						}
					}
				],
				"responses": {
					"200": {
						"description": "List of banks or mobile money providers retrieved successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "array",
											"items": {
												"$ref": "#/components/schemas/PaymentMethodInstitution"
											}
										},
										"page": {
											"type": "integer",
											"description": "Current page number"
										},
										"total": {
											"type": "integer",
											"description": "Total number of items available"
										}
									}
								},
								"examples": {
									"nigeriaBanks": {
										"summary": "Nigerian bank accounts",
										"value": {
											"data": [
												{
													"institutionName": "Guaranty Trust Bank (GTBank) Plc",
													"institutionCode": "000013",
													"institutionBranch": "",
													"institutionAddress": ""
												},
												{
													"institutionName": "Zenith Bank",
													"institutionCode": "000015",
													"institutionBranch": "",
													"institutionAddress": ""
												},
												{
													"institutionName": "Wema Bank",
													"institutionCode": "000017",
													"institutionBranch": "",
													"institutionAddress": ""
												}
											],
											"total": 38,
											"page": 0
										}
									},
									"ghanaMobileMoney": {
										"summary": "Ghana mobile money providers",
										"value": {
											"data": [
												{
													"institutionName": "MTN",
													"institutionCode": "MTN"
												},
												{
													"institutionName": "TIGO",
													"institutionCode": "TIGO"
												},
												{
													"institutionName": "AIRTEL",
													"institutionCode": "AIRTEL"
												}
											],
											"total": 4,
											"page": 0
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request parameters.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingParams": {
										"summary": "Missing required query parameters",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'countryCode' is required, 'channel' is required",
											"details": {}
										}
									},
									"invalidChannel": {
										"summary": "Invalid channel value",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'channel' must be one of [BANK_ACCOUNT, MOBILE_MONEY, SWIFT, ...]",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const institutions = await afriex.paymentMethods.getInstitutions({\n  channel: \"BANK_ACCOUNT\",\n  countryCode: \"NG\",\n});\n\n// Returns: Institution[], { institutionId, institutionName, institutionCode }\n"
					}
				]
			}
		},
		"/api/v1/payment-method/institution/codes": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-signature"
				},
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "resolveInstitutionCode",
				"summary": "Resolve bank code to institution name",
				"description": "Resolves a bank code (SWIFT code or US routing number) to the corresponding bank or institution name.",
				"tags": [
					"Payment Methods"
				],
				"parameters": [
					{
						"name": "searchTerm",
						"in": "query",
						"description": "The bank code to resolve. A US routing number (8-9 digits) when codeType is routing_number, otherwise a SWIFT code.",
						"required": true,
						"schema": {
							"type": "string"
						}
					},
					{
						"name": "country",
						"in": "query",
						"description": "ISO country code of the institution. Defaults to US. routing_number lookups are only supported for US; all other countries use swift_code.",
						"required": true,
						"schema": {
							"type": "string",
							"default": "US"
						}
					},
					{
						"name": "codeType",
						"in": "query",
						"description": "The type of bank code. routing_number is only valid when country is US; for every other country only swift_code is accepted.",
						"required": true,
						"schema": {
							"type": "string",
							"enum": [
								"swift_code",
								"routing_number"
							]
						}
					}
				],
				"responses": {
					"200": {
						"description": "Bank code resolved successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/BankCodeResolverResponse"
										}
									}
								},
								"examples": {
									"routingNumberFound": {
										"summary": "Routing number resolved",
										"value": {
											"data": {
												"bankName": "JPMORGAN CHASE BANK"
											}
										}
									},
									"notFound": {
										"summary": "Bank code not found",
										"value": {
											"data": null
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request parameters.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingParams": {
										"summary": "Missing required parameters",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'country' is required, 'codeType' is required, 'searchTerm' is required",
											"details": {}
										}
									},
									"invalidFormat": {
										"summary": "Invalid routing number format",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: US routing number must be between 8 and 9 digits",
											"details": {}
										}
									},
									"swiftCountryMismatch": {
										"summary": "SWIFT code country mismatch",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: SWIFT code country DE does not match input US",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				}
			}
		},
		"/api/v1/payment-method/resolve": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-signature"
				},
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "resolveRecipient",
				"summary": "Resolve payment method recipient by account number",
				"description": "Resolves payment method user information for bank accounts or mobile money.",
				"tags": [
					"Payment Methods"
				],
				"parameters": [
					{
						"name": "channel",
						"in": "query",
						"description": "The payment method channel to resolve",
						"required": true,
						"schema": {
							"type": "string",
							"enum": [
								"MOBILE_MONEY",
								"BANK_ACCOUNT"
							]
						}
					},
					{
						"name": "accountNumber",
						"in": "query",
						"description": "Bank account number (required for BANK_ACCOUNT channel) or phone number (required for MOBILE_MONEY channel)",
						"required": false,
						"schema": {
							"type": "string"
						}
					},
					{
						"name": "institutionCode",
						"in": "query",
						"description": "Bank code (required for BANK_ACCOUNT channel)",
						"required": false,
						"schema": {
							"type": "string"
						}
					},
					{
						"name": "countryCode",
						"in": "query",
						"description": "The ISO 3166-1 alpha-2 country code. The accepted values depend on channel: BANK_ACCOUNT supports only NG and GH; MOBILE_MONEY supports the remaining countries listed in the enum.",
						"required": true,
						"schema": {
							"type": "string",
							"enum": [
								"NG",
								"GH",
								"ET",
								"KE",
								"MG",
								"MW",
								"MZ",
								"RW",
								"TZ",
								"UG",
								"CM",
								"CG",
								"GA",
								"CF",
								"CI",
								"BF",
								"ML",
								"SN",
								"TG",
								"BJ",
								"NE",
								"GN",
								"ZM"
							]
						}
					}
				],
				"responses": {
					"200": {
						"description": "Payment method resolved successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/PaymentMethodResolveResponse"
										}
									}
								},
								"examples": {
									"bankAccountResolved": {
										"summary": "Bank account resolved",
										"value": {
											"data": {
												"recipientName": "John Doe",
												"institutionName": "GUARANTY TRUST BANK",
												"institutionCode": "000013"
											}
										}
									},
									"mobileMoneyResolved": {
										"summary": "Mobile money account resolved",
										"value": {
											"data": {
												"recipientName": "John Doe",
												"institutionName": "MTN",
												"institutionCode": "MTN"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request parameters.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingParams": {
										"summary": "Missing required parameters",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'accountNumber' is required, 'institutionCode' is required, 'countryCode' is required",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Payment method not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Account not found",
										"value": {
											"code": "PAYMENT_METHOD_NOT_FOUND",
											"error": "Payment method not found",
											"details": {
												"errorMessage": "Payment method not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const accountInfo = await afriex.paymentMethods.resolveAccount({\n  channel: \"BANK_ACCOUNT\",\n  accountNumber: \"1234567890\",\n  institutionCode: \"044\",\n  countryCode: \"NG\",\n});\n\n// Returns: { recipientName, recipientEmail, recipientPhone }\n"
					}
				]
			}
		},
		"/api/v1/org/balance": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "getBalance",
				"summary": "Fetch wallet balance",
				"description": "Returns the balances of the business in the provided currencies.",
				"tags": [
					"Balance"
				],
				"parameters": [
					{
						"name": "currencies",
						"in": "query",
						"description": "Comma-separated list of currencies to fetch balances for. If omitted, balances for all supported currencies are returned.",
						"required": false,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Returns a map with currencies as keys and balances as values.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "object",
											"additionalProperties": {
												"type": "number",
												"format": "double",
												"description": "The balance of the currency."
											}
										}
									},
									"examples": [
										{
											"data": {
												"USD": 100.5,
												"EUR": 250.75,
												"GBP": 300
											}
										}
									]
								},
								"examples": {
									"success": {
										"summary": "Balance retrieved",
										"value": {
											"data": {
												"USD": 990.00532,
												"NGN": 39623.02258,
												"GBP": 0
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request parameters.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingCurrencies": {
										"summary": "Missing currencies parameter",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Payment method not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Business wallet not found",
										"value": {
											"code": "BUSINESS_NOT_FOUND",
											"error": "Business not found",
											"details": {
												"errorMessage": "Business not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const balances = await afriex.balance.getBalance({\n  currencies: [\"USD\", \"NGN\", \"GBP\"],\n});\n\n// Returns: { USD: 10000, NGN: 5000000, GBP: 8000 }\n"
					}
				]
			}
		},
		"/api/v1/org/balance/topup": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "topupBalance",
				"summary": "Top up sandbox balance",
				"description": "Credits the business wallet with the specified amount and currency. **This endpoint is only available in the sandbox/staging environment and will return a `403 Forbidden` response in production.** Use it during integration development to top up your test balance without making real transfers.",
				"tags": [
					"Balance"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"required": [
									"amount",
									"currency"
								],
								"properties": {
									"amount": {
										"type": "number",
										"format": "double",
										"description": "A positive number representing the amount to credit.",
										"examples": [
											500
										]
									},
									"currency": {
										"type": "string",
										"description": "Uppercase 3-letter ISO 4217 currency code (e.g. USD, NGN, GBP). Must be a supported Afriex currency.",
										"examples": [
											"USD"
										]
									}
								}
							},
							"examples": {
								"topupUSD": {
									"summary": "Top up USD balance",
									"value": {
										"amount": 500,
										"currency": "USD"
									}
								},
								"topupNGN": {
									"summary": "Top up NGN balance",
									"value": {
										"amount": 250000,
										"currency": "NGN"
									}
								},
								"topupGBP": {
									"summary": "Top up GBP balance",
									"value": {
										"amount": 200,
										"currency": "GBP"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Balance successfully topped up. Returns the created transaction record.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/Transaction"
										}
									}
								},
								"examples": {
									"success": {
										"summary": "Balance topped up",
										"value": {
											"data": {
												"status": "SUCCESS",
												"type": "DEPOSIT",
												"sourceAmount": "100",
												"sourceCurrency": "USD",
												"destinationAmount": "100",
												"destinationCurrency": "USD",
												"destinationId": "",
												"customerId": "",
												"transactionId": "69d6005dab82306f11b03360",
												"meta": {},
												"createdAt": "2026-04-08T07:14:37.568Z",
												"updatedAt": "2026-04-08T07:14:37.568Z"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request body (e.g. missing fields, negative amount, unsupported currency).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingCurrency": {
										"summary": "Missing currency field",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'currency' is required",
											"details": {}
										}
									},
									"unsupportedCurrency": {
										"summary": "Unsupported currency code",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'currency' must be one of [NGN, USD, GBP, EUR, ...]",
											"details": {}
										}
									},
									"negativeAmount": {
										"summary": "Negative or zero amount",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'amount' must be a positive number",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid or missing business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"403": {
						"description": "Forbidden - This endpoint is not available in the production environment.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"message": {
											"type": "string",
											"examples": [
												"Not allowed"
											]
										}
									}
								},
								"examples": {
									"productionForbidden": {
										"summary": "Endpoint disabled in production",
										"value": {
											"code": "FORBIDDEN",
											"error": "This endpoint is not available in the production environment",
											"details": {}
										}
									}
								}
							}
						}
					},
					"404": {
						"description": "Business not found.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"notFound": {
										"summary": "Business not found",
										"value": {
											"code": "BUSINESS_NOT_FOUND",
											"error": "Business not found",
											"details": {
												"errorMessage": "Business not found",
												"friendlyMessage": ""
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const transaction = await afriex.balance.topUpSandbox({\n  amount: 500,\n  currency: \"USD\",\n});\n\nconsole.log(transaction.transactionId);\nconsole.log(transaction.status); // 'SUCCESS'\n"
					}
				]
			}
		},
		"/api/v1/org/rates": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "getRates",
				"summary": "Get exchange rates",
				"description": "Retrieves real-time exchange rates.",
				"tags": [
					"Rates"
				],
				"parameters": [
					{
						"name": "fromSymbols",
						"in": "query",
						"description": "Comma-separated list of base currency symbols to filter rates by (e.g., USD,NGN,EUR). If omitted, defaults to USD only.",
						"required": false,
						"schema": {
							"type": "string",
							"examples": [
								"USD,NGN,EUR"
							]
						}
					},
					{
						"name": "toSymbols",
						"in": "query",
						"description": "Comma-separated list of target currency symbols to filter rates by (e.g., NGN,EUR,GBP). If omitted, all target currencies are returned.",
						"required": false,
						"schema": {
							"type": "string",
							"examples": [
								"NGN,EUR,GBP"
							]
						}
					}
				],
				"responses": {
					"200": {
						"description": "Successful retrieval of rates",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "object",
											"properties": {
												"rates": {
													"type": "object",
													"description": "Map of base currencies to their exchange rates",
													"additionalProperties": {
														"type": "object",
														"additionalProperties": {
															"type": "string",
															"examples": [
																"1.30272"
															]
														}
													},
													"examples": [
														{
															"USD": {
																"USD": "1",
																"GBP": "0.69255",
																"EUR": "0.80832",
																"CAD": "1.30272",
																"NGN": "1410.1041",
																"KES": "125.0912"
															}
														}
													]
												},
												"updatedAt": {
													"type": "integer",
													"format": "int64",
													"description": "Unix timestamp of the last update",
													"examples": [
														1773245407620
													]
												}
											}
										}
									}
								},
								"examples": {
									"allRates": {
										"summary": "All USD rates",
										"value": {
											"data": {
												"rates": {
													"USD": {
														"USD": "1",
														"EUR": "0.80832",
														"GBP": "0.69255",
														"CAD": "1.30272",
														"NGN": "1410.1041",
														"KES": "125.0912",
														"GHS": "10.96338",
														"UGX": "3485.0742"
													}
												},
												"updatedAt": 1775632339823
											}
										}
									},
									"filteredRates": {
										"summary": "Filtered, USD to NGN and GBP",
										"value": {
											"data": {
												"rates": {
													"USD": {
														"NGN": "1410.1041",
														"GBP": "0.69255"
													}
												},
												"updatedAt": 1775632523393
											}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Internal server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const response = await afriex.rates.getRates({\n  fromSymbols: \"USD,NGN\",\n  toSymbols: \"NGN,USD,GBP,KES\",\n});\n\nconsole.log(response.rates);\nconsole.log(response.updatedAt); // Unix timestamp\n"
					}
				]
			}
		},
		"/api/v1/payment-method/crypto-wallet": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "getCryptoWallet",
				"summary": "Get or create crypto wallet payment method",
				"description": "Retrieves an existing crypto wallet or creates a new one for the specified crypto asset. **Important:** This endpoint is **only active in production** and does **not work on staging/dev**. Supports idempotency to prevent duplicate wallet creation. Currently supports USDT and USDC assets. Send a GET request with the required `asset` parameter (and optional `customerId`). The system will either return existing wallet addresses or automatically create and return new ones if none exist for that asset/customer (or business if no customerId is provided).",
				"tags": [
					"Payment Methods"
				],
				"parameters": [
					{
						"name": "asset",
						"in": "query",
						"description": "The crypto asset symbol for the wallet",
						"required": true,
						"schema": {
							"type": "string",
							"enum": [
								"USDT",
								"USDC"
							]
						}
					},
					{
						"name": "customerId",
						"in": "query",
						"description": "Optional customer ID. If not provided, the wallet will be created for the business.",
						"required": false,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Crypto wallet addresses retrieved or created successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "object",
											"properties": {
												"id": {
													"type": "string",
													"description": "The identifier of the payment method backing this crypto wallet.",
													"examples": [
														"695271a3ba52c13b669fad2b"
													]
												},
												"addresses": {
													"type": "array",
													"items": {
														"type": "object",
														"properties": {
															"address": {
																"type": "string",
																"examples": [
																	"0x1234567890abcdef1234567890abcdef12345678"
																]
															},
															"network": {
																"type": "string",
																"examples": [
																	"ETHEREUM_MAINNET"
																]
															}
														}
													}
												}
											}
										}
									}
								},
								"examples": {
									"usdtWallet": {
										"summary": "USDT wallet addresses",
										"value": {
											"data": {
												"id": "695271a3ba52c13b669fad2b",
												"addresses": [
													{
														"address": "0x1234567890123456789012345678901234567890",
														"network": "ETHEREUM_MAINNET"
													},
													{
														"address": "TYASr5UV6HEcXatwdFQfmLVUqQQQMUxHLS",
														"network": "TRON_MAINNET"
													}
												]
											}
										}
									},
									"usdcWallet": {
										"summary": "USDC wallet addresses",
										"value": {
											"data": {
												"id": "695271a3ba52c13b669fad2c",
												"addresses": [
													{
														"address": "0xabcdef1234567890abcdef1234567890abcdef12",
														"network": "ETHEREUM_MAINNET"
													}
												]
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request parameters (e.g., invalid asset, user not verified, or service not available).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingAsset": {
										"summary": "Missing asset parameter",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'asset' is required",
											"details": {}
										}
									},
									"invalidAsset": {
										"summary": "Unsupported asset (only USDT and USDC are supported)",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'asset' must be one of [USDT, USDC]",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const response = await afriex.paymentMethods.getCryptoWallet({\n  asset: \"USDT\", // or 'USDC'\n  customerId: \"optional-customer-id\",\n});\n\n// Returns: { data: [{ address, network }], total, page }\n"
					}
				]
			}
		},
		"/api/v1/payment-method/virtual-account": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "listVirtualAccounts",
				"summary": "List existing virtual accounts",
				"description": "Returns every active virtual account for the resolved\ncustomer-or-owner and currency. Read-only: when no virtual account\nexists, the response is **200** with `data: []`.\n\nPass `customerId` to scope the list to a specific end-user; omit it\nto list the virtual accounts belonging to the business owner.\n\n**Breaking change from earlier versions:** the previous endpoint\nreturned a single virtual account and would create one on the fly\nwhen absent. It now returns a list and never creates. The create\npath lives at `POST /api/v1/payment-method/virtual-account`; the\n`POOL_ACCOUNT` variant has moved to\n`GET /api/v1/payment-method/pool-account`.\n",
				"tags": [
					"Payment Methods"
				],
				"parameters": [
					{
						"name": "currency",
						"in": "query",
						"description": "The 3-letter ISO 4217 currency code for the virtual account",
						"required": true,
						"schema": {
							"type": "string",
							"enum": [
								"USD",
								"NGN",
								"GBP",
								"EUR"
							]
						}
					},
					{
						"name": "customerId",
						"in": "query",
						"description": "Optional customer ID. When supplied, the lookup is scoped to that\ncustomer. When omitted, it resolves to the business owner.\n",
						"required": false,
						"schema": {
							"type": "string"
						}
					},
					{
						"name": "country",
						"in": "query",
						"description": "Optional ISO 3166-1 alpha-2 country code.",
						"required": false,
						"schema": {
							"type": "string"
						}
					},
					{
						"name": "amount",
						"in": "query",
						"description": "Optional positive amount.",
						"required": false,
						"schema": {
							"type": "number"
						}
					},
					{
						"name": "reference",
						"in": "query",
						"description": "Optional merchant-supplied reference.",
						"required": false,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Virtual accounts retrieved successfully (possibly empty list).",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "array",
											"items": {
												"$ref": "#/components/schemas/PaymentMethod"
											}
										},
										"total": {
											"type": "integer",
											"description": "Number of items in `data`."
										},
										"page": {
											"type": "integer",
											"description": "Page index. Currently always `0`, the endpoint returns all matching VAs in a single response."
										}
									}
								},
								"examples": {
									"twoNgnAccounts": {
										"summary": "Two NGN virtual accounts for a customer",
										"value": {
											"data": [
												{
													"paymentMethodId": "690cc5bbe2a1143ff6070119",
													"channel": "VIRTUAL_BANK_ACCOUNT",
													"customerId": "68e6717848e1f632e9686460",
													"institution": {
														"institutionName": "FIDELITY BANK"
													},
													"accountName": "Lily New",
													"accountNumber": "3820404958",
													"countryCode": "NG"
												},
												{
													"paymentMethodId": "690cc5bbe2a1143ff607011a",
													"channel": "VIRTUAL_BANK_ACCOUNT",
													"customerId": "68e6717848e1f632e9686460",
													"institution": {
														"institutionName": "FIDELITY BANK"
													},
													"accountName": "Lily New (Sales)",
													"accountNumber": "3820404971",
													"countryCode": "NG"
												}
											],
											"total": 2,
											"page": 0
										}
									},
									"noAccounts": {
										"summary": "No virtual accounts exist for this customer/currency",
										"value": {
											"data": [],
											"total": 0,
											"page": 0
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request parameters.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingCurrency": {
										"summary": "Missing currency parameter",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'currency' is required",
											"details": {}
										}
									},
									"invalidCurrency": {
										"summary": "Unsupported currency code",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'currency' must be one of [USD, NGN, GBP, EUR]",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const response = await afriex.paymentMethods.listVirtualAccounts({\n  customerId: \"customer-id\",\n  currency: \"USD\",\n});\n"
					}
				]
			},
			"post": {
				"operationId": "createVirtualAccount",
				"summary": "Create a virtual account payment method",
				"description": "Creates a new virtual account for the resolved customer-or-owner and\ncurrency. Pass `customerId` to mint the VA for a specific end-user;\nomit it to mint one for the business owner.\n\n**Customers are limited to `NGN`.** A virtual account for one of your\ncustomers can only be created in `NGN`. Any other currency returns\n`UNSUPPORTED_VIRTUAL_ACCOUNT_CURRENCY`; create it for the business\nitself by omitting `customerId`.\n\nSubject to a per-(business, customer, currency) limit. Requests that\nwould exceed the limit return `VIRTUAL_ACCOUNT_LIMIT_REACHED`.\n\n**Label vs amount:** `label` groups static virtual accounts by\npurpose (e.g. `SALES`, `OPERATIONS`). It is **mutually exclusive\nwith `amount`**, which routes to a dynamic (ephemeral) virtual\naccount. Supplying both is rejected at validation.\n",
				"tags": [
					"Payment Methods"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"required": [
									"currency"
								],
								"properties": {
									"currency": {
										"type": "string",
										"description": "The 3-letter ISO 4217 currency code for the virtual account.",
										"enum": [
											"USD",
											"NGN",
											"GBP",
											"EUR"
										]
									},
									"customerId": {
										"type": "string",
										"description": "Optional customer ID. When supplied, the VA is created\nfor that customer. When omitted, it is created for the\nbusiness owner.\n"
									},
									"amount": {
										"type": "number",
										"description": "Optional amount for a dynamic (ephemeral) virtual\naccount. Mutually exclusive with `label`.\n",
										"minimum": 0,
										"maximum": 5000000
									},
									"label": {
										"type": "string",
										"description": "Optional label that groups static virtual accounts by\npurpose. Mutually exclusive with `amount`.\n",
										"enum": [
											"SALES",
											"OPERATIONS",
											"PAYROLL",
											"COLLECTIONS",
											"VENDOR_PAYMENTS",
											"TAX",
											"REFUNDS",
											"MARKETING",
											"TREASURY",
											"GENERAL"
										]
									}
								}
							},
							"examples": {
								"staticWithLabel": {
									"summary": "Static virtual account grouped by label",
									"value": {
										"currency": "NGN",
										"customerId": "68e6717848e1f632e9686460",
										"label": "SALES"
									}
								},
								"dynamicWithAmount": {
									"summary": "Dynamic (ephemeral) virtual account tied to an amount",
									"value": {
										"currency": "NGN",
										"customerId": "68e6717848e1f632e9686460",
										"amount": 50000
									}
								},
								"businessOwner": {
									"summary": "Virtual account for the business owner (no customerId)",
									"value": {
										"currency": "USD",
										"label": "TREASURY"
									}
								}
							}
						}
					}
				},
				"responses": {
					"201": {
						"description": "Virtual account created successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/PaymentMethod"
										}
									}
								},
								"examples": {
									"ngnVirtualAccount": {
										"summary": "NGN dedicated virtual bank account",
										"value": {
											"data": {
												"paymentMethodId": "690cc5bbe2a1143ff6070119",
												"channel": "VIRTUAL_BANK_ACCOUNT",
												"customerId": "68e6717848e1f632e9686460",
												"institution": {
													"institutionName": "FIDELITY BANK"
												},
												"accountName": "Lily New",
												"accountNumber": "3820404958",
												"countryCode": "NG"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request (e.g. `label` and `amount` both supplied) or\nvirtual account limit reached.\n",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"labelAndAmount": {
										"summary": "Both label and amount supplied",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'label' and 'amount' are mutually exclusive",
											"details": {}
										}
									},
									"limitReached": {
										"summary": "Per-(business, customer, currency) cap reached",
										"value": {
											"code": "VIRTUAL_ACCOUNT_LIMIT_REACHED",
											"error": "Virtual account limit reached",
											"details": {
												"errorMessage": "Virtual account limit reached",
												"friendlyMessage": "You have reached the maximum number of virtual accounts for this customer and currency."
											}
										}
									},
									"missingCurrency": {
										"summary": "Missing currency",
										"value": {
											"code": "VALIDATION_ERROR",
											"error": "Failed to parse request. Issues: 'currency' is required",
											"details": {}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"403": {
						"description": "The requested currency is not available to the resolved account\nholder.\n",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"customerNonNgn": {
										"summary": "Non-NGN virtual account requested for a customer",
										"value": {
											"code": "UNSUPPORTED_VIRTUAL_ACCOUNT_CURRENCY",
											"error": "Unsupported virtual account currency",
											"details": {
												"errorMessage": "Unsupported virtual account currency",
												"friendlyMessage": "USD virtual accounts cannot be created for a customer. Create it for the business instead by omitting customerId."
											}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const account = await afriex.paymentMethods.createVirtualAccount({\n  currency: \"USD\",\n  label: \"SALES\",\n  customerId: \"optional-customer-id\",\n});\n"
					}
				]
			}
		},
		"/api/v1/payment-method/pool-account": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "getPoolAccount",
				"summary": "Get the business pool account",
				"description": "Returns the pool account for the supplied `country`. Use the\n`reference` on the response to reconcile incoming deposits.\n",
				"tags": [
					"Payment Methods"
				],
				"parameters": [
					{
						"name": "country",
						"in": "query",
						"description": "ISO 3166-1 alpha-2 country code.",
						"required": true,
						"schema": {
							"type": "string",
							"examples": [
								"NG"
							]
						}
					},
					{
						"name": "customerId",
						"in": "query",
						"description": "Optional customer ID to associate with this account.",
						"required": false,
						"schema": {
							"type": "string"
						}
					},
					{
						"name": "amount",
						"in": "query",
						"description": "Optional positive amount. Accepted but ignored.",
						"required": false,
						"schema": {
							"type": "number"
						}
					},
					{
						"name": "reference",
						"in": "query",
						"description": "Optional merchant-supplied reference. Accepted but ignored.",
						"required": false,
						"schema": {
							"type": "string"
						}
					}
				],
				"responses": {
					"200": {
						"description": "Pool account returned successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/PaymentMethod"
										}
									}
								},
								"examples": {
									"poolAccountNG": {
										"summary": "Pool account assigned for an NG/NGN deposit",
										"value": {
											"data": {
												"paymentMethodId": "69c2804b30314b491e48b305",
												"channel": "VIRTUAL_BANK_ACCOUNT",
												"customerId": "6929843e2c4653277440acc0",
												"reference": "6929843e2c4653277440acc0",
												"institution": {
													"institutionName": "UBA"
												},
												"accountName": "TEST",
												"accountNumber": "12345678",
												"countryCode": "NG"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request, no pool account configured for the country, or an unsupported country code was supplied.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingCountry": {
										"summary": "Missing country",
										"value": {
											"code": "INVALID_BUSINESS_POOL_ACCOUNT_REQUEST",
											"error": "Invalid business pool account request",
											"details": {
												"errorMessage": "Invalid business pool account request",
												"friendlyMessage": "No country code provided"
											}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"missingApiKey": {
										"summary": "Missing API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Authorization header is missing",
											"details": {}
										}
									},
									"invalidApiKey": {
										"summary": "Invalid API key",
										"value": {
											"code": "AUTHENTICATION_ERROR",
											"error": "Invalid authorization header",
											"details": {}
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								},
								"examples": {
									"processorNotFound": {
										"summary": "No pool account available for the country (for example, MX)",
										"value": {
											"code": "TRANSACTION_PROCESSOR_NOT_FOUND",
											"error": "Transaction processor not found",
											"details": {
												"errorMessage": "Transaction processor not found",
												"friendlyMessage": "No pool account available for business for this country"
											}
										}
									},
									"serverError": {
										"summary": "Unexpected server error",
										"value": {
											"code": "INTERNAL_SERVER_ERROR",
											"error": "It's not you, it's us, please reach out to support",
											"details": {}
										}
									}
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const poolAccount = await afriex.paymentMethods.listPoolAccounts({\n  customerId: \"customer-id\",\n  country: \"NG\",\n});\n"
					}
				]
			}
		},
		"/api/v1/checkout-session": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "createCheckoutSession",
				"summary": "Create a checkout session",
				"description": "Creates a hosted checkout session for a customer and returns a `checkoutUrl` that the customer should be redirected to in order to complete payment. The session captures the merchant intent (amount, currency, merchant reference, customer details, and allowed payment channels) and is identified end-to-end by the merchant-supplied `merchantReference`.",
				"tags": [
					"Checkout Sessions"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"required": [
									"amount",
									"currency",
									"merchantReference",
									"redirectUrl",
									"customer",
									"channels"
								],
								"properties": {
									"amount": {
										"type": "integer",
										"minimum": 100,
										"description": "The transaction amount in **minor currency units** (e.g. kobo for NGN, cents for USD). Minimum 100 (equivalent to 1 major currency unit).",
										"examples": [
											500000
										]
									},
									"currency": {
										"type": "string",
										"description": "Uppercase 3-letter ISO 4217 currency code (e.g. NGN, GHS). Must be a currency enabled for checkout sessions on the business.",
										"examples": [
											"NGN"
										]
									},
									"merchantReference": {
										"type": "string",
										"minLength": 1,
										"description": "Unique merchant-supplied reference for this session. Used end-to-end to look up the session and any resulting transaction.",
										"examples": [
											"order-2026-05-12-001"
										]
									},
									"redirectUrl": {
										"type": "string",
										"format": "uri",
										"description": "HTTPS URL the customer is redirected to after the hosted checkout flow completes.",
										"examples": [
											"https://merchant.example.com/checkout/return"
										]
									},
									"customer": {
										"$ref": "#/components/schemas/CheckoutSessionCustomer"
									},
									"channels": {
										"type": "array",
										"minItems": 1,
										"description": "The payment channels you are willing to offer the customer, at least one. **This is a cap, not an exact list: you do not need to vary it per country.** Channels the `currency` does not support are dropped and the session is created with the rest, so the same list works for every corridor (send `[\"VIRTUAL_BANK_ACCOUNT\", \"MOBILE_MONEY\", \"CARD\"]` and a KES session offers mobile money while a USD one offers cards). The channels the customer will actually be shown come back as `channels` on the response. The request is rejected (`422`) only when none of the requested channels are supported for the currency, or when the currency supports no deposit channel at all.",
										"items": {
											"type": "string",
											"enum": [
												"VIRTUAL_BANK_ACCOUNT",
												"MOBILE_MONEY",
												"CARD"
											]
										}
									},
									"metadata": {
										"type": "object",
										"maxProperties": 50,
										"description": "Optional flat key/value metadata to attach to the session. Both keys and values must be strings. At most 50 entries; keys up to 128 characters, values up to 1024 characters.",
										"additionalProperties": {
											"type": "string",
											"maxLength": 1024
										}
									}
								}
							},
							"examples": {
								"minimal": {
									"summary": "One channel list for every corridor",
									"value": {
										"amount": 500000,
										"currency": "NGN",
										"merchantReference": "order-2026-05-12-001",
										"redirectUrl": "https://merchant.example.com/checkout/return",
										"customer": {
											"name": "John Doe",
											"email": "john.doe@example.com",
											"phone": "+2348192837465",
											"countryCode": "NG"
										},
										"channels": [
											"VIRTUAL_BANK_ACCOUNT",
											"MOBILE_MONEY",
											"CARD"
										]
									}
								},
								"withChannelsAndMetadata": {
									"summary": "Narrowing to specific channels, plus metadata",
									"value": {
										"amount": 500000,
										"currency": "NGN",
										"merchantReference": "order-2026-05-12-002",
										"redirectUrl": "https://merchant.example.com/checkout/return",
										"customer": {
											"name": "John Doe",
											"email": "john.doe@example.com",
											"phone": "+2348192837465",
											"countryCode": "NG"
										},
										"channels": [
											"VIRTUAL_BANK_ACCOUNT",
											"CARD"
										],
										"metadata": {
											"orderId": "12345",
											"source": "web"
										}
									}
								}
							}
						}
					}
				},
				"responses": {
					"201": {
						"description": "Checkout session created successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"$ref": "#/components/schemas/CreateCheckoutSessionResponse"
										}
									}
								},
								"examples": {
									"created": {
										"summary": "Session created",
										"value": {
											"data": {
												"checkoutUrl": "https://pay.afriex.com/pay/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
												"channels": [
													"VIRTUAL_BANK_ACCOUNT",
													"CARD"
												]
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					},
					"422": {
						"description": "None of the requested `channels` are supported for the `currency`, or the currency has no deposit channel available at all.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const session = await afriex.checkout.createSession({\n  amount: 500000,\n  currency: \"NGN\",\n  merchantReference: \"order-2026-05-12-001\",\n  redirectUrl: \"https://yourapp.com/checkout/return\",\n  customer: {\n    name: \"John Doe\",\n    email: \"john@example.com\",\n    phone: \"+2348192837465\",\n    countryCode: \"NG\",\n  },\n  // Send the same list everywhere; unsupported ones are dropped\n  channels: [\"VIRTUAL_BANK_ACCOUNT\", \"MOBILE_MONEY\", \"CARD\"],\n  metadata: { orderId: \"order-456\", cartId: \"cart-123\" },\n});\n\n// Redirect customer to session.checkoutUrl\nconsole.log(session.checkoutUrl);\n// What the payer will be shown, e.g. [\"VIRTUAL_BANK_ACCOUNT\", \"CARD\"]\nconsole.log(session.channels);\n"
					}
				]
			}
		},
		"/api/v1/webhooks/trigger": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "triggerWebhook",
				"summary": "Trigger a test webhook (sandbox-only)",
				"description": "Fires a real signed webhook to the business's configured callback URL using a real entity (customer, payment method, transaction, or checkout session) as the payload. Useful for testing webhook handlers in sandbox without manufacturing the underlying activity. **This endpoint is only available in the sandbox/staging environment and will return a `403 Forbidden` response in production.**",
				"tags": [
					"Webhooks"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"required": [
									"event",
									"entityId"
								],
								"properties": {
									"event": {
										"$ref": "#/components/schemas/WebhookEventName"
									},
									"entityId": {
										"type": "string",
										"description": "The identifier of the entity to send in the webhook payload. Must be a UUID v4 when `event` is `CHECKOUT_SESSION.CREATED`; otherwise must be the 24-character hexadecimal id of the relevant customer, payment method, or transaction (the id returned when it was created).",
										"examples": [
											"69528240ba52c13b669fb239"
										]
									}
								}
							},
							"examples": {
								"transactionEvent": {
									"summary": "Trigger a transaction webhook",
									"value": {
										"event": "TRANSACTION.UPDATED",
										"entityId": "6952826eba52c13b669fb263"
									}
								},
								"checkoutSessionEvent": {
									"summary": "Trigger a checkout session webhook (UUID entityId)",
									"value": {
										"event": "CHECKOUT_SESSION.CREATED",
										"entityId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Webhook triggered successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "object",
											"description": "Details of the queued webhook delivery.",
											"properties": {
												"queued": {
													"type": "boolean",
													"description": "Always true; the webhook delivery was queued."
												},
												"event": {
													"$ref": "#/components/schemas/WebhookEventName"
												},
												"entityId": {
													"type": "string",
													"description": "The id of the entity used as the webhook payload."
												},
												"deliveryUrl": {
													"type": "string",
													"description": "The business webhook callback URL the event was queued to."
												}
											}
										}
									}
								},
								"examples": {
									"queued": {
										"summary": "Webhook queued",
										"value": {
											"data": {
												"queued": true,
												"event": "TRANSACTION.UPDATED",
												"entityId": "6952826eba52c13b669fb263",
												"deliveryUrl": "https://merchant.example.com/webhooks"
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request body.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					},
					"403": {
						"description": "Forbidden - This endpoint is not available in the production environment.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"message": {
											"type": "string",
											"examples": [
												"Not allowed"
											]
										}
									}
								}
							}
						}
					},
					"500": {
						"description": "Server error.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					}
				},
				"x-codeSamples": [
					{
						"lang": "TypeScript",
						"label": "Afriex SDK",
						"source": "const result = await afriex.webhooks.triggerTestWebhook({\n  event: \"TRANSACTION.UPDATED\",\n  resourceId: \"transaction-id\",\n});\n\nconsole.log(result); // { success: true, message: \"...\" }\n"
					}
				]
			}
		},
		"/api/v1/media/url": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "generatePresignedURL",
				"summary": "Generate a presigned URL for file upload",
				"description": "Generates a presigned S3 URL that the caller can use to upload a file (e.g. a KYC document) directly to Afriex's secure storage. The returned URL is time-limited and scoped to the requested operation.",
				"tags": [
					"Media"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"$ref": "#/components/schemas/MediaURLRequest"
							},
							"examples": {
								"upload-user": {
									"summary": "Generate a user KYC upload URL",
									"value": {
										"fileName": "passport.png",
										"type": "user"
									}
								},
								"upload-transaction": {
									"summary": "Generate a transaction file upload URL",
									"value": {
										"fileName": "report.csv",
										"type": "transaction"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Presigned URL generated successfully.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/MediaURLResponse"
								},
								"examples": {
									"url": {
										"summary": "Presigned URL",
										"value": {
											"data": {
												"url": "https://s3.amazonaws.com/bucket/key?X-Amz-Algorithm=AWS4-HMAC-SHA256&...",
												"key": "64f0c2a1e4b0a1b2c3d4e5f6/invoice.pdf",
												"expiresIn": 300
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request body.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					}
				}
			}
		},
		"/api/v1/sme-registration": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"post": {
				"operationId": "smeRegistration",
				"summary": "Register a business as an SME (step-based)",
				"description": "Registers a business as its own SME so that dedicated virtual accounts are issued under the business's own legal entity rather than the shared default. The flow is stateful and driven by this single endpoint: the `step` field selects the payload carried in `data`. Call the steps in order — `INITIATE` (triggers a one-time passcode to the supplied mobile number), `CONFIRM_OTP`, then `SUBMIT` (company details, directors and documents). Upload each document first via `POST /api/v1/media/url` and pass the returned object keys in the `SUBMIT` payload. Requires an API key with admin permission.",
				"tags": [
					"SME Registration"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"required": [
									"step",
									"data"
								],
								"properties": {
									"step": {
										"type": "string",
										"enum": [
											"INITIATE",
											"CONFIRM_OTP",
											"SUBMIT"
										],
										"description": "Selects the payload shape carried in `data`."
									},
									"data": {
										"type": "object",
										"description": "Step-specific payload. `INITIATE`: `mobile`, `email`, `businessType` (must be `2` — only Limited Liability Companies are supported at this time). `CONFIRM_OTP`: `onboardingRequestId`, `otp`. `SUBMIT`: company details, `directors[]`, and optional `organizationShareholders[]` / `media[]`, where every file field is an object key returned by `POST /api/v1/media/url`.\n\nEvery mobile number (the applicant's on `INITIATE` and each director's on `SUBMIT`) must be a valid Kenyan number. Any of `254712345678`, `+254712345678`, `0712345678` or `712345678` is accepted and normalised to E.164; a number that is not Kenyan is rejected with `422`. Directors do not need a `countryCode`: it is derived from the number, and ignored if sent."
									}
								}
							},
							"examples": {
								"initiate": {
									"summary": "Step 1 — initiate and trigger the OTP",
									"value": {
										"step": "INITIATE",
										"data": {
											"mobile": "254712345678",
											"email": "admin@company.co.ke",
											"businessType": 2
										}
									}
								},
								"confirm-otp": {
									"summary": "Step 2 — confirm the OTP",
									"value": {
										"step": "CONFIRM_OTP",
										"data": {
											"onboardingRequestId": "obr-12345",
											"otp": "483921"
										}
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Step processed successfully.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "object",
											"properties": {
												"onboardingRequestId": {
													"type": "string"
												},
												"step": {
													"type": "string",
													"enum": [
														"INITIATE",
														"CONFIRM_OTP",
														"SUBMIT"
													]
												},
												"status": {
													"type": "string",
													"enum": [
														"OTP_PENDING",
														"DETAILS_PENDING",
														"SUBMITTED",
														"REJECTED",
														"EXPIRED"
													]
												},
												"nextStep": {
													"type": "string",
													"nullable": true,
													"enum": [
														"CONFIRM_OTP",
														"SUBMIT"
													]
												},
												"expiresAt": {
													"type": "string",
													"format": "date-time",
													"description": "Deadline for the current step — OTP window after INITIATE, submit window after CONFIRM_OTP."
												}
											}
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Invalid request body or a step called out of order.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					}
				}
			}
		},
		"/api/v1/sme-registration/status": {
			"parameters": [
				{
					"$ref": "#/components/parameters/x-api-version"
				}
			],
			"get": {
				"operationId": "smeRegistrationStatus",
				"summary": "Get SME registration status",
				"description": "Returns the most recent SME registration status for the authenticated business. Once the registration has been submitted, the response also includes the latest review outcome. Requires an API key with admin permission.",
				"tags": [
					"SME Registration"
				],
				"responses": {
					"200": {
						"description": "Current SME registration status.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"properties": {
										"data": {
											"type": "object",
											"properties": {
												"onboardingRequestId": {
													"type": "string",
													"nullable": true,
													"description": "Null when the business has never registered."
												},
												"status": {
													"type": "string",
													"nullable": true,
													"enum": [
														"OTP_PENDING",
														"DETAILS_PENDING",
														"SUBMITTED",
														"REJECTED",
														"EXPIRED"
													]
												},
												"reviewStatus": {
													"type": "string",
													"description": "Public review outcome, present only once the registration has been submitted. `APPROVED` means the business's dedicated KES virtual accounts can be issued under its own entity; `UNKNOWN` is a forward-compatibility slot for any provider code Afriex has not mapped yet. The set may grow over time; handle unknown values by falling back to `UNKNOWN`.",
													"enum": [
														"SUBMITTED",
														"PROCESSING",
														"APPROVED",
														"REJECTED",
														"CLOSED",
														"UNDER_REVIEW",
														"UNKNOWN"
													]
												},
												"rejectReasons": {
													"type": "array",
													"nullable": true,
													"items": {
														"type": "string"
													}
												},
												"isReviewStatusStale": {
													"type": "boolean",
													"description": "True when Afriex could not reach the provider for a fresh review outcome on this read, so `reviewStatus` reflects the last known value (or `UNKNOWN` if none is cached) rather than the current one. Absent when the read succeeded."
												}
											}
										}
									}
								}
							}
						}
					},
					"401": {
						"description": "Unauthorized - Invalid business API key.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					}
				}
			}
		}
	},
	"webhooks": {
		"customer.events": {
			"post": {
				"operationId": "customerWebhookEvent",
				"summary": "Customer Events",
				"description": "Afriex delivers real-time notifications to your configured webhook URL whenever a customer is **created**, **updated**, or **deleted**.\n\nThe payload structure is **identical** across all events. Only the `event` field changes.\n\n**Security**: Every request includes an `x-webhook-signature` header. You **must** verify this signature using Afriex's public key before processing. See the [Webhooks Overview & Security](https://docs.afriex.com/api-reference/endpoint/webhooks/introduction) section for verification instructions.",
				"tags": [
					"Webhooks"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"properties": {
									"event": {
										"type": "string",
										"enum": [
											"CUSTOMER.CREATED",
											"CUSTOMER.UPDATED",
											"CUSTOMER.DELETED"
										],
										"description": "Identifies which customer event occurred",
										"examples": [
											"CUSTOMER.UPDATED"
										]
									},
									"data": {
										"type": "object",
										"description": "The customer data relevant to this event",
										"properties": {
											"customerId": {
												"type": "string",
												"description": "Unique identifier of the customer",
												"examples": [
													"69516dd0464b2213bd74cfad"
												]
											},
											"name": {
												"type": "string",
												"examples": [
													"John Doe"
												]
											},
											"email": {
												"type": "string",
												"format": "email",
												"examples": [
													"john.doe@example.com"
												]
											},
											"phone": {
												"type": "string",
												"examples": [
													"+2348121123445"
												],
												"description": "Phone number in E.164 international format"
											},
											"countryCode": {
												"type": "string",
												"description": "ISO 3166-1 alpha-2 country code",
												"examples": [
													"NG"
												]
											},
											"meta": {
												"type": "object",
												"description": "Optional metadata attached to the customer.",
												"additionalProperties": true
											},
											"createdAt": {
												"type": "string",
												"description": "The date and time the customer was created."
											},
											"updatedAt": {
												"type": "string",
												"description": "The date and time the customer was last updated."
											}
										},
										"required": [
											"customerId",
											"name",
											"email",
											"phone",
											"countryCode"
										],
										"additionalProperties": false
									}
								},
								"required": [
									"event",
									"data"
								],
								"additionalProperties": false
							},
							"examples": {
								"customerCreated": {
									"summary": "Customer Created",
									"value": {
										"event": "CUSTOMER.CREATED",
										"data": {
											"customerId": "69516dd0464b2213bd74cfad",
											"name": "John Doe",
											"email": "john.doe@example.com",
											"phone": "+2348121123445",
											"countryCode": "NG"
										}
									}
								},
								"customerUpdated": {
									"summary": "Customer Updated",
									"value": {
										"event": "CUSTOMER.UPDATED",
										"data": {
											"customerId": "69516dd0464b2213bd74cfad",
											"name": "John Doe",
											"email": "john.doe@example.com",
											"phone": "+2348121123445",
											"countryCode": "NG"
										}
									}
								},
								"customerDeleted": {
									"summary": "Customer Deleted",
									"value": {
										"event": "CUSTOMER.DELETED",
										"data": {
											"customerId": "69516dd0464b2213bd74cfad",
											"name": "John Doe",
											"email": "john.doe@example.com",
											"phone": "+2348121123445",
											"countryCode": "NG"
										}
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Acknowledge receipt. Return any 2xx status code quickly. Response body is ignored."
					},
					"400": {
						"description": "Bad Request, malformed payload, invalid/missing signature, etc. Afriex will retry delivery."
					},
					"401": {
						"description": "Unauthorized, signature verification failed."
					}
				}
			}
		},
		"payment_method.events": {
			"post": {
				"operationId": "paymentMethodWebhookEvent",
				"summary": "Payment Method Events",
				"description": "Afriex delivers real-time notifications to your configured webhook URL whenever a payment method is **created**, **updated**, or **deleted** for a customer.\n\nThe payload structure is **identical** across all events. Only the `event` field changes.\n\n**Security**: Every request includes an `x-webhook-signature` header. You **must** verify this signature using Afriex's public key before processing. See the [Webhooks Overview & Security](https://docs.afriex.com/api-reference/endpoint/webhooks/introduction) section for verification instructions.",
				"tags": [
					"Webhooks"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"properties": {
									"event": {
										"type": "string",
										"enum": [
											"PAYMENT_METHOD.CREATED",
											"PAYMENT_METHOD.UPDATED",
											"PAYMENT_METHOD.DELETED"
										],
										"description": "Identifies which payment method event occurred",
										"examples": [
											"PAYMENT_METHOD.UPDATED"
										]
									},
									"data": {
										"type": "object",
										"description": "The payment method data relevant to this event. Empty fields are omitted. CARD-channel payment methods omit accountName/accountNumber/institution and instead include card fields (last4, brand, expiration, cardName); dynamic virtual accounts may additionally include expiresInMinutes, amount, and extra.",
										"properties": {
											"paymentMethodId": {
												"type": "string",
												"description": "Unique identifier of the payment method",
												"examples": [
													"69528259ba52c13b669fb241"
												]
											},
											"channel": {
												"type": "string",
												"description": "Type/channel of the payment method",
												"examples": [
													"BANK_ACCOUNT"
												]
											},
											"customerId": {
												"type": "string",
												"description": "ID of the customer this payment method belongs to",
												"examples": [
													"69528240ba52c13b669fb239"
												]
											},
											"institution": {
												"type": "object",
												"properties": {
													"institutionId": {
														"type": "string",
														"examples": [
															""
														]
													},
													"institutionName": {
														"type": "string",
														"examples": [
															"United Bank for Africa"
														]
													},
													"institutionCode": {
														"type": "string",
														"examples": [
															""
														]
													},
													"institutionAddress": {
														"type": "string",
														"examples": [
															""
														]
													}
												},
												"description": "Bank or financial institution details (may be partial)"
											},
											"transaction": {
												"type": "object",
												"properties": {
													"transactionInvoice": {
														"type": "string",
														"examples": [
															""
														]
													},
													"transactionNarration": {
														"type": "string",
														"examples": [
															""
														]
													}
												},
												"description": "Transaction-related metadata (often empty for bank accounts)"
											},
											"recipient": {
												"type": "object",
												"properties": {
													"recipientEmail": {
														"type": "string",
														"examples": [
															""
														]
													},
													"recipientPhone": {
														"type": "string",
														"examples": [
															""
														]
													},
													"recipientAddress": {
														"type": "string",
														"examples": [
															""
														]
													},
													"recipientName": {
														"type": "string",
														"examples": [
															""
														]
													}
												},
												"description": "Recipient details (often empty for bank accounts)"
											},
											"accountName": {
												"type": "string",
												"description": "Name on the account",
												"examples": [
													"Sabasil"
												]
											},
											"accountNumber": {
												"type": "string",
												"description": "Account number or masked identifier",
												"examples": [
													"2133213321"
												]
											},
											"countryCode": {
												"type": "string",
												"description": "ISO 3166-1 alpha-2 country code",
												"examples": [
													"NG"
												]
											},
											"status": {
												"type": "string",
												"description": "Lifecycle status of the payment method.",
												"examples": [
													"active"
												]
											},
											"meta": {
												"type": "object",
												"description": "Additional flexible metadata (empty object if unused)",
												"additionalProperties": true
											}
										},
										"required": [
											"paymentMethodId",
											"channel",
											"customerId",
											"countryCode"
										],
										"additionalProperties": true
									}
								},
								"required": [
									"event",
									"data"
								],
								"additionalProperties": false
							},
							"examples": {
								"paymentMethodCreated": {
									"summary": "Payment Method Created",
									"value": {
										"event": "PAYMENT_METHOD.CREATED",
										"data": {
											"paymentMethodId": "69528259ba52c13b669fb241",
											"channel": "BANK_ACCOUNT",
											"customerId": "69528240ba52c13b669fb239",
											"institution": {
												"institutionId": "",
												"institutionName": "United Bank for Africa",
												"institutionCode": "",
												"institutionAddress": ""
											},
											"transaction": {
												"transactionInvoice": "",
												"transactionNarration": ""
											},
											"recipient": {
												"recipientEmail": "",
												"recipientPhone": "",
												"recipientAddress": "",
												"recipientName": ""
											},
											"accountName": "Sabasil",
											"accountNumber": "2133213321",
											"countryCode": "NG",
											"meta": {}
										}
									}
								},
								"paymentMethodUpdated": {
									"summary": "Payment Method Updated",
									"value": {
										"event": "PAYMENT_METHOD.UPDATED",
										"data": {
											"paymentMethodId": "69528259ba52c13b669fb241",
											"channel": "BANK_ACCOUNT",
											"customerId": "69528240ba52c13b669fb239",
											"institution": {
												"institutionId": "",
												"institutionName": "United Bank for Africa",
												"institutionCode": "",
												"institutionAddress": ""
											},
											"transaction": {
												"transactionInvoice": "",
												"transactionNarration": ""
											},
											"recipient": {
												"recipientEmail": "",
												"recipientPhone": "",
												"recipientAddress": "",
												"recipientName": ""
											},
											"accountName": "Sabasil",
											"accountNumber": "2133213321",
											"countryCode": "NG",
											"meta": {}
										}
									}
								},
								"paymentMethodDeleted": {
									"summary": "Payment Method Deleted",
									"value": {
										"event": "PAYMENT_METHOD.DELETED",
										"data": {
											"paymentMethodId": "69528259ba52c13b669fb241",
											"channel": "BANK_ACCOUNT",
											"customerId": "69528240ba52c13b669fb239",
											"institution": {
												"institutionId": "",
												"institutionName": "United Bank for Africa",
												"institutionCode": "",
												"institutionAddress": ""
											},
											"transaction": {
												"transactionInvoice": "",
												"transactionNarration": ""
											},
											"recipient": {
												"recipientEmail": "",
												"recipientPhone": "",
												"recipientAddress": "",
												"recipientName": ""
											},
											"accountName": "Sabasil",
											"accountNumber": "2133213321",
											"countryCode": "NG",
											"meta": {}
										}
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Acknowledge receipt. Return any 2xx status code quickly. Response body is ignored."
					},
					"400": {
						"description": "Bad Request, malformed payload, invalid/missing signature, etc. Afriex will retry delivery."
					},
					"401": {
						"description": "Unauthorized, signature verification failed."
					}
				}
			}
		},
		"transaction.events": {
			"post": {
				"operationId": "transactionWebhookEvent",
				"summary": "Transaction Events",
				"description": "Afriex sends real-time webhook notifications to your configured URL whenever a transaction is **created** or **updated**.\n\n- `TRANSACTION.CREATED`: Fired when a new transaction is initiated.\n- `TRANSACTION.UPDATED`: Fired when the transaction status or other fields change (most commonly `status` and `updatedAt`).\n\nThe payload structure is **identical** for both events. Only the `event` field and potentially `status` + `updatedAt` differ.\n\n**Security**: Every request includes an `x-webhook-signature` header. You **must** verify this signature using Afriex's public key before processing. See the [Webhooks Overview & Security](https://docs.afriex.com/api-reference/endpoint/webhooks/introduction) section for verification instructions.",
				"tags": [
					"Webhooks"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"properties": {
									"event": {
										"type": "string",
										"enum": [
											"TRANSACTION.CREATED",
											"TRANSACTION.UPDATED"
										],
										"description": "Identifies which transaction event occurred",
										"examples": [
											"TRANSACTION.UPDATED"
										]
									},
									"data": {
										"type": "object",
										"description": "Details of the transaction",
										"properties": {
											"status": {
												"type": "string",
												"description": "Current status of the transaction",
												"enum": [
													"PENDING",
													"PROCESSING",
													"SUCCESS",
													"FAILED",
													"CANCELLED",
													"REFUNDED",
													"RETRY",
													"UNKNOWN",
													"SCHEDULED",
													"CUSTOMER_ACTION_REQUIRED",
													"REJECTED",
													"IN_REVIEW",
													"DISPUTED",
													"DISPUTE_RESOLVED",
													"DISPUTE_WON",
													"DISPUTE_LOST",
													"DISPUTE_EVIDENCE_SUBMITTED"
												],
												"examples": [
													"PENDING"
												]
											},
											"type": {
												"type": "string",
												"description": "Type/direction of the transaction",
												"enum": [
													"DEPOSIT",
													"WITHDRAW",
													"SWAP"
												],
												"examples": [
													"WITHDRAW"
												]
											},
											"channel": {
												"type": "string",
												"enum": [
													"BANK_ACCOUNT",
													"SWIFT",
													"MOBILE_MONEY",
													"UPI",
													"INTERAC",
													"WE_CHAT",
													"CARD",
													"CRYPTO",
													"VIRTUAL_BANK_ACCOUNT",
													"POOL_ACCOUNT",
													"ACH_BANK_ACCOUNT",
													"PAYBILL_TILL",
													"RFP",
													"VIRTUAL_CARD",
													"ALIPAY",
													"WALLET"
												],
												"description": "Payment channel of the transaction.",
												"examples": [
													"BANK_ACCOUNT"
												]
											},
											"sourceAmount": {
												"type": "string",
												"description": "Amount in source currency (string for precision)",
												"examples": [
													"3.316587998"
												]
											},
											"sourceCurrency": {
												"type": "string",
												"description": "ISO 4217 source currency code",
												"examples": [
													"USD"
												]
											},
											"destinationAmount": {
												"type": "string",
												"description": "Amount in destination currency (string)",
												"examples": [
													"5000"
												]
											},
											"destinationCurrency": {
												"type": "string",
												"description": "ISO 4217 destination currency code",
												"examples": [
													"NGN"
												]
											},
											"sourceId": {
												"type": "string",
												"description": "ID of the source payment method (e.g. for deposits)",
												"examples": [
													"695271a3ba52c13b669fad2b"
												]
											},
											"destinationId": {
												"type": "string",
												"description": "ID of the destination (e.g. payment method ID for withdraws)",
												"examples": [
													"695271a3ba52c13b669fad2b"
												]
											},
											"customerId": {
												"type": "string",
												"description": "ID of the customer who owns this transaction",
												"examples": [
													"69528240ba52c13b669fb239"
												]
											},
											"transactionId": {
												"type": "string",
												"description": "Unique identifier of the transaction",
												"examples": [
													"6952826eba52c13b669fb263"
												]
											},
											"merchantReference": {
												"type": "string",
												"description": "The merchant-supplied reference (mirrors meta.reference from the create request).",
												"examples": [
													"order-12345"
												]
											},
											"meta": {
												"type": "object",
												"description": "Additional transaction metadata",
												"properties": {
													"narration": {
														"type": "string",
														"examples": [
															""
														]
													},
													"invoice": {
														"type": "string",
														"examples": [
															""
														]
													},
													"idempotencyKey": {
														"type": "string",
														"examples": [
															""
														]
													},
													"reference": {
														"type": "string",
														"examples": [
															""
														]
													}
												},
												"additionalProperties": true
											},
											"createdAt": {
												"type": "string",
												"format": "date-time",
												"description": "ISO 8601 timestamp when the transaction was created",
												"examples": [
													"2025-12-29T13:30:22.554Z"
												]
											},
											"updatedAt": {
												"type": "string",
												"format": "date-time",
												"description": "ISO 8601 timestamp of the last update",
												"examples": [
													"2025-12-29T13:30:22.554Z"
												]
											}
										},
										"required": [
											"status",
											"type",
											"sourceAmount",
											"sourceCurrency",
											"destinationAmount",
											"destinationCurrency",
											"customerId",
											"transactionId",
											"createdAt",
											"updatedAt"
										],
										"additionalProperties": false
									}
								},
								"required": [
									"event",
									"data"
								],
								"additionalProperties": false
							},
							"examples": {
								"transactionCreated": {
									"summary": "Transaction Created",
									"value": {
										"event": "TRANSACTION.CREATED",
										"data": {
											"status": "PENDING",
											"type": "WITHDRAW",
											"channel": "BANK_ACCOUNT",
											"sourceAmount": "3.316587998",
											"sourceCurrency": "USD",
											"destinationAmount": "5000",
											"destinationCurrency": "NGN",
											"destinationId": "695271a3ba52c13b669fad2b",
											"customerId": "69528240ba52c13b669fb239",
											"transactionId": "6952826eba52c13b669fb263",
											"meta": {
												"narration": "",
												"invoice": "",
												"idempotencyKey": "",
												"reference": ""
											},
											"createdAt": "2025-12-29T13:30:22.554Z",
											"updatedAt": "2025-12-29T13:30:22.554Z"
										}
									}
								},
								"transactionUpdated": {
									"summary": "Transaction Updated (status changed)",
									"value": {
										"event": "TRANSACTION.UPDATED",
										"data": {
											"status": "SUCCESS",
											"type": "WITHDRAW",
											"channel": "BANK_ACCOUNT",
											"sourceAmount": "3.316587998",
											"sourceCurrency": "USD",
											"destinationAmount": "5000",
											"destinationCurrency": "NGN",
											"destinationId": "695271a3ba52c13b669fad2b",
											"customerId": "69528240ba52c13b669fb239",
											"transactionId": "6952826eba52c13b669fb263",
											"meta": {
												"narration": "",
												"invoice": "",
												"idempotencyKey": "",
												"reference": ""
											},
											"createdAt": "2025-12-29T13:30:22.554Z",
											"updatedAt": "2025-12-29T13:45:10.123Z"
										}
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Acknowledge receipt. Return any 2xx status code quickly. Response body is ignored."
					},
					"400": {
						"description": "Bad Request, malformed payload, invalid/missing signature, etc. Afriex will retry delivery."
					},
					"401": {
						"description": "Unauthorized, signature verification failed."
					}
				}
			}
		},
		"checkout_session.events": {
			"post": {
				"operationId": "checkoutSessionWebhookEvent",
				"summary": "Checkout Session Events",
				"description": "Afriex delivers a webhook to your configured URL when a hosted checkout session is created. Checkout sessions are currently available in the sandbox/staging environment only.\n\n**Security**: Every request includes an `x-webhook-signature` header. You **must** verify this signature using Afriex's public key before processing. See the [Webhooks Overview & Security](https://docs.afriex.com/api-reference/endpoint/webhooks/introduction) section for verification instructions.",
				"tags": [
					"Webhooks"
				],
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"type": "object",
								"properties": {
									"event": {
										"type": "string",
										"enum": [
											"CHECKOUT_SESSION.CREATED"
										],
										"description": "Identifies which checkout session event occurred",
										"examples": [
											"CHECKOUT_SESSION.CREATED"
										]
									},
									"data": {
										"type": "object",
										"description": "Details of the checkout session",
										"properties": {
											"sessionId": {
												"type": "string",
												"description": "Unique identifier of the checkout session",
												"examples": [
													"69528240ba52c13b669fb239"
												]
											},
											"merchantReference": {
												"type": "string",
												"description": "The merchant-supplied reference for the session",
												"examples": [
													"order-12345"
												]
											},
											"amount": {
												"type": "integer",
												"description": "The session amount",
												"examples": [
													5000
												]
											},
											"currency": {
												"type": "string",
												"description": "ISO 4217 currency code",
												"examples": [
													"NGN"
												]
											},
											"afriexTransactionId": {
												"type": "string",
												"description": "The Afriex transaction id once the session is paid",
												"examples": [
													"6952826eba52c13b669fb263"
												]
											},
											"paidAt": {
												"type": "string",
												"format": "date-time",
												"description": "Timestamp when the session was paid"
											},
											"expiresAt": {
												"type": "string",
												"format": "date-time",
												"description": "Timestamp when the session expires",
												"examples": [
													"2025-12-29T13:45:10.123Z"
												]
											},
											"createdAt": {
												"type": "string",
												"format": "date-time",
												"description": "Timestamp when the session was created",
												"examples": [
													"2025-12-29T13:30:22.554Z"
												]
											},
											"metadata": {
												"type": "object",
												"description": "Merchant-supplied metadata attached to the session",
												"additionalProperties": {
													"type": "string"
												}
											},
											"customer": {
												"type": "object",
												"description": "The customer associated with the session",
												"properties": {
													"name": {
														"type": "string"
													},
													"email": {
														"type": "string",
														"format": "email"
													},
													"phone": {
														"type": "string"
													},
													"countryCode": {
														"type": "string"
													}
												},
												"additionalProperties": true
											}
										},
										"required": [
											"sessionId",
											"merchantReference",
											"amount",
											"currency",
											"expiresAt"
										]
									}
								},
								"required": [
									"event",
									"data"
								]
							},
							"examples": {
								"checkoutSessionCreated": {
									"summary": "Checkout Session Created",
									"value": {
										"event": "CHECKOUT_SESSION.CREATED",
										"data": {
											"sessionId": "69528240ba52c13b669fb239",
											"merchantReference": "order-12345",
											"amount": 5000,
											"currency": "NGN",
											"expiresAt": "2025-12-29T13:45:10.123Z",
											"createdAt": "2025-12-29T13:30:22.554Z",
											"metadata": {},
											"customer": {
												"name": "John Doe",
												"email": "john.doe@example.com",
												"phone": "+2348192837465",
												"countryCode": "NG"
											}
										}
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Acknowledge receipt. Return any 2xx status code quickly. Response body is ignored."
					},
					"400": {
						"description": "Bad Request, malformed payload, invalid/missing signature, etc. Afriex will retry delivery."
					},
					"401": {
						"description": "Unauthorized, signature verification failed."
					}
				}
			}
		}
	},
	"tags": [
		{
			"name": "Customers",
			"description": "Create and manage your customers."
		},
		{
			"name": "Payment Methods",
			"description": "Register and resolve customer payout and collection methods."
		},
		{
			"name": "Transactions",
			"description": "Create and track deposits, withdrawals, and swaps."
		},
		{
			"name": "Balance",
			"description": "View and top up your business wallet balances."
		},
		{
			"name": "Rates",
			"description": "Fetch real-time exchange rates."
		},
		{
			"name": "Checkout Sessions",
			"description": "Create hosted checkout sessions."
		},
		{
			"name": "Webhooks",
			"description": "Webhook event payloads and sandbox webhook testing."
		},
		{
			"name": "Media",
			"description": "Generate presigned URLs for secure file uploads."
		}
	]
}
