{
  "_meta": {
    "api": "MojoPay Omni API",
    "version": "1.0",
    "note": "Illustrative samples only. Replace credentials, IDs, and URLs. When served from this app, https://omni.mojo-pay.com/v1 and https://omni.mojo-pay.com in URLs are replaced with the live host. Amounts are strings. When collection fees apply, API responses include fee_amount and amount_payable (amount is merchant principal); webhooks do not duplicate fee line-item breakdown fields such as amount_breakdown, order_amount, or net_amount. GET /v1/balance returns collection_wallet (available after T+1), collection_wallet_actual, collection_wallet_held, payout_wallet, pending, and optional provider_float. request_id uses REQ_ + 12 uppercase characters; webhook event id uses EVT_ + 24 uppercase characters. Country is resolved from merchant profile in portal; do not send country in request payloads. Collection, checkout, mandate, and payout requests use flat fields: top-level mobile and provider (and routing fields) instead of nested customer or beneficiary objects. collections omit type (defaults to mobile_money). checkout_sessions support amount_mode fixed|open; hosted pay page is mobile money only in v1.0; expires_at is typically one hour after create. Payout requests omit transaction/expiry windows unless you need overrides; defaults are applied server-side. Do not send beneficiary display names or account titles. Do not send payer or sender metadata; merchants map that locally (for example using merchant_reference). Do not send customer name or email on collection, checkout, or mandate creates unless plan_id is set; map those locally. checkout_sessions.request_sample_portal_customer_choice mirrors portal pay links (null payment_rail; customer enters wallet on the hosted /pay/{id} page). Webhook events (v1.0): collection.processing|succeeded|failed, checkout_session.processing|succeeded|failed, payout.processing|succeeded|failed, mandate.processing|succeeded|cancelled, mandate_debit.processing|succeeded|failed, and subscription lifecycle events (subscription.created, subscription.active, subscription.cancelled, subscription.failed, subscription.charge_failed) when linked to plans. Merchant API responses and webhooks do not include internal gateway transaction references (mojopay_reference); use merchant_reference and public id (CL_, CS_, PO_, MD_) for integration. Testing mode: money-in amounts are capped per country until Go Live; amount_mode open is not allowed while Testing (see /doc#testing-mode).",
    "vocabulary": {
      "collections": "Money in — collections (wallet) and checkout_sessions (hosted page).",
      "payouts": "Money out — POST /v1/payouts (type mobile_money or bank).",
      "direct_debit": "Mandates + mandate debits (section 8.7); not the same as one-time Collections."
    },
    "audit": "See MojoPay-Unified-Merchant-API.md for the Omni API integration quick start, Testing mode, and checklist. Live docs: /doc, /doc/openapi, /doc/openapi.yaml, /doc/samples.json, /api-tester/. Portal Mojo Ai can help with payloads/errors. OpenAPI source: docs/openapi/mojopay-v1.openapi.yaml."
  },
  "authentication": {
    "post_v1_oauth_token_request": {
      "grant_type": "client_credentials",
      "client_id": "issued_by_mojopay",
      "client_secret": "issued_by_mojopay"
    },
    "post_v1_oauth_token_response_200": {
      "access_token": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2",
      "token_type": "Bearer",
      "expires_in": 1200
    },
    "post_v1_oauth_token_request_minimal": {
      "client_id": "issued_by_mojopay",
      "client_secret": "issued_by_mojopay"
    }
  },
  "errors": {
    "response_400_invalid_parameter": {
      "error": {
        "code": "invalid_parameter",
        "message": "Provider is required for mobile money payouts.",
        "doc_url": "https://docs.mojopay.com/errors/invalid_parameter",
        "request_id": "REQ_8F3A2C1B9D0E"
      }
    },
    "response_429_rate_limited": {
      "error": {
        "code": "rate_limited",
        "message": "Too many requests. Retry after a short delay.",
        "doc_url": "https://docs.mojopay.com/errors/rate_limited",
        "request_id": "REQ_9A1B2C3D4E5F"
      }
    }
  },
  "webhooks": {
    "collection_processing": {
      "id": "EVT_CL_PROCESSING001ABCDEFGHIJK",
      "type": "collection.processing",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:00:00Z",
      "data": {
        "object": {
          "id": "CL_9K2ML0ABCDEF",
          "object": "collection",
          "status": "processing",
          "currency": "GHS",
          "amount": "200.00",
          "merchant_reference": "ORD-2026-001"
        }
      }
    },
    "collection_succeeded": {
      "id": "EVT_CL_SUCCEEDED001ABCDEFGHIJ",
      "type": "collection.succeeded",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:02:00Z",
      "data": {
        "object": {
          "id": "CL_9K2ML0ABCDEF",
          "object": "collection",
          "status": "succeeded",
          "currency": "GHS",
          "amount": "200.00",
          "merchant_reference": "ORD-2026-001",
          "mobile": "233544338841",
          "payment_rail": "mobile_money",
          "provider": "MTN"
        }
      }
    },
    "collection_failed": {
      "id": "EVT_CL_FAILED001ABCDEFGHIJKLM",
      "type": "collection.failed",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:03:00Z",
      "data": {
        "object": {
          "id": "CL_9K2ML1ABCDEF",
          "object": "collection",
          "status": "failed",
          "currency": "GHS",
          "amount": "200.00",
          "merchant_reference": "ORD-2026-002",
          "status_detail": "Insufficient balance"
        }
      }
    },
    "checkout_session_processing": {
      "id": "EVT_CS_PROCESSING001ABCDEFGHIJ",
      "type": "checkout_session.processing",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:04:30Z",
      "data": {
        "object": {
          "id": "CS_4NQP81ABCDEF",
          "object": "checkout_session",
          "status": "processing",
          "currency": "GHS",
          "amount_mode": "fixed",
          "amount": "1.00",
          "fee_amount": "0.00",
          "amount_payable": "1.00",
          "merchant_reference": "KLCTMXOAIS",
          "mobile": "233555515326",
          "payment_rail": "mobile_money",
          "provider": "MTN"
        }
      }
    },
    "checkout_session_succeeded": {
      "id": "EVT_CS_SUCCEEDED001ABCDEFGHIJK",
      "type": "checkout_session.succeeded",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:05:00Z",
      "data": {
        "object": {
          "id": "CS_4NQP81ABCDEF",
          "object": "checkout_session",
          "status": "succeeded",
          "currency": "GHS",
          "amount_mode": "fixed",
          "amount": "1.00",
          "fee_amount": "0.00",
          "amount_payable": "1.00",
          "merchant_reference": "KLCTMXOAIS",
          "mobile": "233555515326",
          "payment_rail": "mobile_money",
          "provider": "MTN"
        }
      }
    },
    "checkout_session_failed": {
      "id": "EVT_CS_FAILED001ABCDEFGHIJKLMN",
      "type": "checkout_session.failed",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:06:00Z",
      "data": {
        "object": {
          "id": "CS_4NQP82ABCDEF",
          "object": "checkout_session",
          "status": "failed",
          "currency": "GHS",
          "amount_mode": "fixed",
          "amount": "1.00",
          "fee_amount": "0.00",
          "amount_payable": "1.00",
          "merchant_reference": "KLCTMXOAIS2",
          "mobile": "233555515326",
          "payment_rail": "mobile_money",
          "provider": "MTN",
          "status_detail": "Customer declined"
        }
      }
    },
    "payout_processing": {
      "id": "EVT_PO_PROCESSING001ABCDEFGHIJ",
      "type": "payout.processing",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:00:00Z",
      "data": {
        "object": {
          "id": "PO_7XR2ABCDEF",
          "object": "payout",
          "status": "processing",
          "currency": "GHS",
          "amount": "1.11",
          "merchant_reference": "PO-7788"
        }
      }
    },
    "payout_succeeded": {
      "id": "EVT_PO_SUCCEEDED001ABCDEFGHIJ",
      "type": "payout.succeeded",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:04:00Z",
      "data": {
        "object": {
          "id": "PO_7XR2ABCDEF",
          "object": "payout",
          "status": "succeeded",
          "currency": "GHS",
          "amount": "1.11",
          "merchant_reference": "PO-7788"
        }
      }
    },
    "payout_failed": {
      "id": "EVT_PO_FAILED001ABCDEFGHIJKL",
      "type": "payout.failed",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:06:00Z",
      "data": {
        "object": {
          "id": "PO_7XR3ABCDEF",
          "object": "payout",
          "status": "failed",
          "currency": "GHS",
          "amount": "500.00",
          "merchant_reference": "PO-7790",
          "status_detail": "Invalid account"
        }
      }
    },
    "mandate_processing": {
      "id": "EVT_MD_PROCESSING01ABCDEFGHIJ",
      "type": "mandate.processing",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:07:00Z",
      "data": {
        "object": {
          "object": "mandate",
          "mandate_id": "MD_ABCDEF123456",
          "status": "processing",
          "merchant_reference": "mandate-monthly-001",
          "currency": "GHS",
          "amount": "50.00",
          "frequency": "MONTHLY",
          "mobile": "233544338841",
          "provider": "MTN"
        }
      }
    },
    "mandate_succeeded": {
      "id": "EVT_MD_SUCCEEDED01ABCDEFGHIJ",
      "type": "mandate.succeeded",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:08:00Z",
      "data": {
        "object": {
          "object": "mandate",
          "mandate_id": "MD_ABCDEF123456",
          "status": "succeeded",
          "merchant_reference": "mandate-monthly-001",
          "currency": "GHS",
          "amount": "50.00",
          "frequency": "MONTHLY",
          "mobile": "233544338841",
          "provider": "MTN"
        }
      }
    },
    "mandate_cancelled": {
      "id": "EVT_MD_CANCELLED01ABCDEFGH",
      "type": "mandate.cancelled",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:08:30Z",
      "data": {
        "object": {
          "object": "mandate",
          "mandate_id": "MD_ABCDEF123456",
          "status": "cancelled",
          "merchant_reference": "mandate-monthly-001",
          "currency": "GHS",
          "amount": "50.00",
          "frequency": "MONTHLY",
          "mobile": "233544338841",
          "provider": "MTN",
          "cancelled_at": "2026-04-15T10:08:30Z",
          "cancel_reason": "Customer requested cancellation"
        }
      }
    },
    "mandate_debit_processing": {
      "id": "EVT_MDD_PROCESSING01ABCDEFG",
      "type": "mandate_debit.processing",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:08:45Z",
      "data": {
        "object": {
          "object": "mandate_debit",
          "debit_id": "MDD_DEBIT001ABCDEF",
          "status": "processing",
          "mandate_id": "MD_ABCDEF123456",
          "merchant_reference": "debit-ref-001",
          "currency": "GHS",
          "amount": "50.00",
          "provider": "MTN"
        }
      }
    },
    "mandate_debit_succeeded": {
      "id": "EVT_MDD_SUCCEEDED01ABCDEFGH",
      "type": "mandate_debit.succeeded",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:09:00Z",
      "data": {
        "object": {
          "object": "mandate_debit",
          "debit_id": "MDD_DEBIT001ABCDEF",
          "status": "succeeded",
          "mandate_id": "MD_ABCDEF123456",
          "merchant_reference": "debit-ref-001",
          "currency": "GHS",
          "amount": "50.00",
          "provider": "MTN"
        }
      }
    },
    "mandate_debit_failed": {
      "id": "EVT_MDD_FAILED01ABCDEFGHIJK",
      "type": "mandate_debit.failed",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:10:00Z",
      "data": {
        "object": {
          "object": "mandate_debit",
          "debit_id": "MDD_DEBIT002ABCDEF",
          "status": "failed",
          "mandate_id": "MD_ABCDEF123456",
          "merchant_reference": "debit-ref-002",
          "currency": "GHS",
          "amount": "50.00",
          "provider": "MTN"
        }
      }
    },
    "subscription_created": {
      "id": "EVT_SUB_CREATED01ABCDEFGHIJ",
      "type": "subscription.created",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:11:00Z",
      "data": {
        "object": {
          "object": "subscription",
          "subscription_id": "SUB_ABCDEF123456",
          "status": "pending",
          "merchant_reference": "sub-monthly-001",
          "customer_name": "Jane Doe",
          "customer_email": "jane@example.com",
          "plan_id": "PLN_ABCDEF123456",
          "plan_name": "Monthly plan",
          "mandate_id": "MD_ABCDEF123456",
          "mobile": "233544338841",
          "provider": "MTN"
        }
      }
    },
    "subscription_active": {
      "id": "EVT_SUB_ACTIVE01ABCDEFGHIJK",
      "type": "subscription.active",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:12:00Z",
      "data": {
        "object": {
          "object": "subscription",
          "subscription_id": "SUB_ABCDEF123456",
          "status": "active",
          "merchant_reference": "sub-monthly-001",
          "customer_name": "Jane Doe",
          "customer_email": "jane@example.com",
          "plan_id": "PLN_ABCDEF123456",
          "plan_name": "Monthly plan",
          "mandate_id": "MD_ABCDEF123456",
          "mobile": "233544338841",
          "provider": "MTN"
        }
      }
    },
    "subscription_charge_failed": {
      "id": "EVT_SUB_CHARGE_FAILED01ABCD",
      "type": "subscription.charge_failed",
      "api_version": "2026-04-15",
      "created": "2026-04-15T10:13:00Z",
      "data": {
        "object": {
          "object": "subscription",
          "subscription_id": "SUB_ABCDEF123456",
          "status": "active",
          "merchant_reference": "sub-monthly-001",
          "customer_name": "Jane Doe",
          "customer_email": "jane@example.com",
          "plan_id": "PLN_ABCDEF123456",
          "plan_name": "Monthly plan",
          "mandate_id": "MD_ABCDEF123456",
          "mobile": "233544338841",
          "provider": "MTN",
          "debit_id": "MDD_DEBIT002ABCDEF",
          "debit_merchant_reference": "debit-ref-002"
        }
      }
    }
  },
  "collections": {
    "post_v1_collections_request_headers": {
      "Authorization": "Bearer <access_token>",
      "Content-Type": "application/json",
      "Idempotency-Key": "<new-uuid-for-this-payment-attempt>"
    },
    "post_v1_collections_full_request": {
      "method": "POST",
      "url": "https://omni.mojo-pay.com/v1/collections",
      "note": "Use https://omni.mojo-pay.com/v1 from /doc/samples.json on this host, or your deployment APP_URL/v1.",
      "headers": {
        "Authorization": "Bearer a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2",
        "Content-Type": "application/json",
        "Idempotency-Key": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
      },
      "body": {
        "currency": "GHS",
        "amount": "200.00",
        "merchant_reference": "ORD-2026-001",
        "description": "Invoice 42",
        "mobile": "233544338841",
        "provider": "MTN"
      }
    },
    "post_v1_collections_request_type_mobile_money_minimum": {
      "currency": "GHS",
      "amount": "200.00",
      "merchant_reference": "ORD-2026-001",
      "mobile": "233544338841",
      "provider": "MTN"
    },
    "post_v1_collections_response_201": {
      "id": "CL_9K2ML0ABCDEF",
      "object": "collection",
      "status": "processing",
      "currency": "GHS",
      "amount": "200.00",
      "merchant_reference": "ORD-2026-001"
    },
    "get_v1_collections_response_200": {
      "id": "CL_9K2ML0ABCDEF",
      "object": "collection",
      "status": "succeeded",
      "currency": "GHS",
      "amount": "200.00",
      "merchant_reference": "ORD-2026-001",
      "mobile": "233544338841",
      "payment_rail": "mobile_money",
      "provider": "MTN"
    }
  },
  "checkout_sessions": {
    "post_v1_checkout_sessions_request": {
      "amount_mode": "fixed",
      "currency": "GHS",
      "amount": "1.00",
      "merchant_reference": "KLCTMXOAIS",
      "description": "Goods payment",
      "success_url": "https://merchant.example.com/pay/return?ref=KLCTMXOAIS",
      "cancel_url": "https://merchant.example.com/pay/cancel?ref=KLCTMXOAIS",
      "mobile": "233555515326",
      "payment_rail": "mobile_money",
      "provider": "MTN"
    },
    "post_v1_checkout_sessions_request_customer_minimum": {
      "amount_mode": "fixed",
      "currency": "GHS",
      "amount": "1.00",
      "merchant_reference": "KLCTMXOAIS",
      "success_url": "https://merchant.example.com/pay/return?ref=KLCTMXOAIS",
      "cancel_url": "https://merchant.example.com/pay/cancel?ref=KLCTMXOAIS"
    },
    "post_v1_checkout_sessions_request_open_amount": {
      "amount_mode": "open",
      "currency": "GHS",
      "merchant_reference": "DONATION-2026-001",
      "description": "Pay what you want",
      "success_url": "https://merchant.example.com/pay/return",
      "cancel_url": "https://merchant.example.com/pay/cancel"
    },
    "post_v1_checkout_sessions_request_portal_customer_choice": {
      "amount_mode": "fixed",
      "currency": "GHS",
      "amount": "2.56",
      "merchant_reference": "SLUG-RANDOMTOKEN",
      "description": "Pay link",
      "success_url": "https://merchant.example.com/pay/ok",
      "cancel_url": "https://merchant.example.com/pay/cancel",
      "payment_rail": null,
      "mobile": null,
      "provider": null
    },
    "post_v1_checkout_sessions_response_201": {
      "id": "CS_4NQP81ABCDEF",
      "object": "checkout_session",
      "status": "processing",
      "url": "https://checkout.example.com/pay/CS_4NQP81ABCDEF",
      "expires_at": "2026-04-15T11:00:00Z"
    },
    "get_v1_checkout_sessions_id_response_200_mobile_money": {
      "id": "CS_4NQP81ABCDEF",
      "object": "checkout_session",
      "status": "succeeded",
      "currency": "GHS",
      "amount_mode": "fixed",
      "amount": "1.00",
      "fee_amount": "0.00",
      "amount_payable": "1.00",
      "merchant_reference": "KLCTMXOAIS",
      "mobile": "233555515326",
      "payment_rail": "mobile_money",
      "provider": "MTN"
    },
    "get_v1_checkout_sessions_id_response_200_open_amount": {
      "id": "CS_4NQP83ABCDEF",
      "object": "checkout_session",
      "status": "succeeded",
      "currency": "GHS",
      "amount_mode": "open",
      "amount": "25.00",
      "fee_amount": "0.50",
      "amount_payable": "25.50",
      "merchant_reference": "DONATION-2026-001",
      "mobile": "233555515326",
      "payment_rail": "mobile_money",
      "provider": "MTN"
    }
  },
  "payouts": {
    "post_v1_payouts_request_type_mobile_money": {
      "type": "mobile_money",
      "currency": "GHS",
      "amount": "1.11",
      "merchant_reference": "PO-7788",
      "mobile": "233241000000",
      "provider": "MTN"
    },
    "post_v1_payouts_request_type_bank": {
      "type": "bank",
      "currency": "GHS",
      "amount": "500.00",
      "merchant_reference": "PO-7789",
      "account_number": "0123456789",
      "bank_code": "300304"
    },
    "post_v1_payouts_response_201_type_mobile_money": {
      "id": "PO_7XR2ABCDEF",
      "object": "payout",
      "status": "processing",
      "merchant_reference": "PO-7788"
    },
    "post_v1_payouts_response_201_type_bank": {
      "id": "PO_7XR3ABCDEF",
      "object": "payout",
      "status": "processing",
      "merchant_reference": "PO-7789"
    },
    "get_v1_payouts_merchant_reference_response_200": {
      "id": "PO_7XR2ABCDEF",
      "object": "payout",
      "status": "succeeded",
      "currency": "GHS",
      "amount": "1.11",
      "merchant_reference": "PO-7788",
      "status_detail": null
    }
  },
  "verifications": {
    "post_v1_verifications_msisdn_request": {
      "mobile": "233123456789",
      "provider": "MTN"
    },
    "post_v1_verifications_msisdn_response_200_verified": {
      "status": "verified",
      "profile": {
        "first_name": "Jane",
        "last_name": "Doe"
      }
    },
    "post_v1_verifications_msisdn_response_200_invalid": {
      "status": "invalid",
      "profile": null
    },
    "post_v1_verifications_bank_accounts_request": {
      "bank_code": "300312",
      "account_number": "0123456789"
    },
    "post_v1_verifications_bank_accounts_response_200_verified": {
      "status": "verified",
      "profile": {
        "first_name": "Jane",
        "last_name": "Doe"
      }
    },
    "post_v1_verifications_bank_accounts_response_200_invalid": {
      "status": "invalid",
      "profile": null
    }
  },
  "mandates": {
    "post_v1_mandates_request_frequency_daily": {
      "currency": "GHS",
      "amount": "1.00",
      "frequency": "DAILY",
      "starts_at": "2026-01-11T00:00:00Z",
      "ends_at": "2026-12-30T23:59:59Z",
      "merchant_reference": "mandateTest010912026003",
      "description": "daily subscription payment",
      "mobile": "233597225334",
      "provider": "MTN"
    },
    "post_v1_mandates_request_frequency_weekly": {
      "currency": "GHS",
      "amount": "10.00",
      "frequency": "WEEKLY",
      "starts_at": "2026-01-11T00:00:00Z",
      "ends_at": "2026-12-30T23:59:59Z",
      "merchant_reference": "mandate-weekly-001",
      "description": "Weekly subscription",
      "mobile": "233597225334",
      "provider": "MTN"
    },
    "post_v1_mandates_request_frequency_monthly": {
      "currency": "GHS",
      "amount": "50.00",
      "frequency": "MONTHLY",
      "starts_at": "2026-02-01T00:00:00Z",
      "ends_at": "2027-01-31T23:59:59Z",
      "merchant_reference": "mandate-monthly-001",
      "description": "Monthly plan",
      "mobile": "233597225335",
      "provider": "VODAFONE"
    },
    "post_v1_mandates_response_201": {
      "object": "mandate",
      "status": "processing",
      "merchant_reference": "mandateTest010912026003",
      "message_id": "5d3cc227-329f-41e8-a6b4-8eb637bed8b5"
    },
    "get_v1_mandates_response_200": {
      "object": "mandate",
      "mandate_id": "20189719",
      "status": "succeeded",
      "merchant_reference": "mandateTest010912026003",
      "frequency": "DAILY",
      "description": "daily subscription payment",
      "mobile": "233597225334",
      "provider": "MTN"
    },
    "post_v1_mandates_mandate_id_cancel_request": {
      "mobile": "233597225334",
      "reason": "Customer requested cancellation"
    },
    "post_v1_mandates_mandate_id_cancel_response_200": {
      "object": "mandate_cancellation",
      "status": "processing",
      "mandate_id": "20146915",
      "message_id": "eca0ddea-f572-4526-bb62-2c1fa64f15fa"
    },
    "post_v1_mandates_mandate_id_debits_request": {
      "amount": "1.00",
      "currency": "GHS",
      "merchant_reference": "43654565xxx01001",
      "provider": "MTN"
    },
    "post_v1_mandates_mandate_id_debits_response_201": {
      "object": "mandate_debit",
      "status": "processing",
      "merchant_reference": "43654565xxx01001",
      "message_id": "311c2f3e-ad50-406a-91a2-ee55a8dc7066"
    },
    "get_v1_mandate_debits_status_response_200": {
      "status": "succeeded",
      "mandate_id": "20189719",
      "merchant_reference": "43654565xxx01001",
      "currency": "GHS",
      "amount": "1.00"
    }
  },
  "metadata_and_balance": {
    "get_v1_metadata_banks_response_200": {
      "object": "list",
      "data": [
        {
          "bank_name": "STANDARD CHARTERED BANK (GH) LTD",
          "bank_code": "300302"
        },
        {
          "bank_name": "ABSA BANK (GH) LTD.",
          "bank_code": "300303"
        },
        {
          "bank_name": "GCB BANK",
          "bank_code": "300304"
        },
        {
          "bank_name": "NATIONAL INVESTMENT BANK LTD",
          "bank_code": "300305"
        },
        {
          "bank_name": "UNITED BANK FOR AFRICA (GH) LTD",
          "bank_code": "300325"
        },
        {
          "bank_name": "ARP APEX BANK LTD",
          "bank_code": "300306"
        },
        {
          "bank_name": "SG GHANA LTD",
          "bank_code": "300308"
        },
        {
          "bank_name": "UNIVERSAL MERCHANT BANK",
          "bank_code": "300309"
        },
        {
          "bank_name": "REPUBLIC BANK",
          "bank_code": "300310"
        },
        {
          "bank_name": "ZENITH BANK (GH) LTD",
          "bank_code": "300311"
        },
        {
          "bank_name": "ECOBANK (GH) LTD",
          "bank_code": "300312"
        },
        {
          "bank_name": "CAL BANK LTD",
          "bank_code": "300313"
        },
        {
          "bank_name": "FIRST ATLANTIC MERCHANT BANK LTD",
          "bank_code": "300316"
        },
        {
          "bank_name": "PRUDENTIAL BANK LTD",
          "bank_code": "300317"
        },
        {
          "bank_name": "STANBIC BANK GHANA LTD",
          "bank_code": "300318"
        },
        {
          "bank_name": "BANK OF AFRICA LTD",
          "bank_code": "300320"
        },
        {
          "bank_name": "FIDELITY BANK GHANA LTD",
          "bank_code": "300323"
        },
        {
          "bank_name": "GUARANTY TRUST BANK",
          "bank_code": "300322"
        },
        {
          "bank_name": "OMNIBSIC GHANA",
          "bank_code": "300324"
        },
        {
          "bank_name": "ACCESS BANK (GH) LTD",
          "bank_code": "300329"
        },
        {
          "bank_name": "FIRST NATIONAL BANK",
          "bank_code": "300334"
        },
        {
          "bank_name": "CONSOLIDATED BANK GHANA",
          "bank_code": "300331"
        },
        {
          "bank_name": "AGRICULTURAL DEVELOPMENT BANK",
          "bank_code": "300307"
        },
        {
          "bank_name": "FBN BANK LTD",
          "bank_code": "300319"
        }
      ]
    },
    "get_v1_balance_response_200": {
      "currency": "GHS",
      "available": "125000.50",
      "collection_wallet": "100000.00",
      "collection_wallet_actual": "105000.00",
      "collection_wallet_held": "5000.00",
      "payout_wallet": "25000.50",
      "pending": "0.00"
    },
    "get_v1_metadata_mobile_providers_response_200": {
      "object": "list",
      "data": [
        {
          "provider": "MTN"
        },
        {
          "provider": "VODAFONE"
        },
        {
          "provider": "AIRTELTIGO"
        }
      ]
    }
  },
  "transactions": {
    "get_v1_transactions_verify_merchant_reference_response_200_collection": {
      "merchant_reference": "ORD-2026-001",
      "object": "collection",
      "id": "CL_9K2ML0ABCDEF",
      "status": "succeeded",
      "currency": "GHS",
      "amount": "200.00",
      "mobile": "233544338841",
      "payment_rail": "mobile_money",
      "provider": "MTN"
    },
    "get_v1_transactions_verify_merchant_reference_response_200_checkout": {
      "merchant_reference": "KLCTMXOAIS",
      "object": "checkout_session",
      "id": "CS_4NQP81ABCDEF",
      "status": "succeeded",
      "currency": "GHS",
      "amount_mode": "fixed",
      "amount": "1.00",
      "fee_amount": "0.00",
      "amount_payable": "1.00",
      "mobile": "233555515326",
      "payment_rail": "mobile_money",
      "provider": "MTN"
    },
    "get_v1_transactions_verify_merchant_reference_response_200_payout": {
      "merchant_reference": "PO-7788",
      "object": "payout",
      "id": "PO_7XR2ABCDEF",
      "status": "succeeded",
      "currency": "GHS",
      "amount": "1.11"
    }
  },
  "common": {
    "authenticated_request_headers": {
      "Authorization": "Bearer <access_token>",
      "Content-Type": "application/json"
    },
    "idempotent_post_headers": {
      "Authorization": "Bearer <access_token>",
      "Content-Type": "application/json",
      "Idempotency-Key": "<new-uuid>"
    },
    "sub_account_request_headers": {
      "Authorization": "Bearer <access_token>",
      "Content-Type": "application/json",
      "X-Mojo-Account-Ref": "accra-branch"
    },
    "sub_account_idempotent_post_headers": {
      "Authorization": "Bearer <access_token>",
      "Content-Type": "application/json",
      "X-Mojo-Account-Ref": "accra-branch",
      "Idempotency-Key": "<new-uuid>"
    }
  },
  "merchant_accounts": {
    "get_v1_account_response_200": {
      "object": "account_context",
      "merchant": {
        "id": 42,
        "name": "Acme Ltd",
        "sub_accounts_enabled": true
      },
      "account": {
        "id": "MAC_ABCDEF123456",
        "object": "merchant_account",
        "account_ref": "accra-branch",
        "name": "Accra Branch",
        "status": "active"
      }
    }
  },
  "subscriptions": {
    "get_v1_subscription_plans_response_200": {
      "object": "list",
      "data": [
        {
          "object": "subscription_plan",
          "plan_id": "PLN_ABCDEF123456",
          "name": "Gold Monthly",
          "description": "Full access, billed monthly",
          "currency": "GHS",
          "amount": "50.00",
          "frequency": "MONTHLY",
          "duration_type": "ongoing",
          "duration_months": null,
          "status": "active"
        }
      ]
    },
    "post_v1_subscriptions_request": {
      "plan_id": "PLN_ABCDEF123456",
      "merchant_reference": "SUB-1042",
      "customer_name": "Jane Doe",
      "customer_email": "jane@example.com",
      "mobile": "233544338841",
      "provider": "MTN",
      "notes": "Signed up from marketing campaign"
    },
    "post_v1_subscriptions_response_201": {
      "object": "subscription",
      "subscription_id": "SUB_ABCDEF123456",
      "status": "pending_approval",
      "merchant_reference": "SUB-1042",
      "customer_name": "Jane Doe",
      "customer_email": "jane@example.com",
      "plan_id": "PLN_ABCDEF123456",
      "plan_name": "Gold Monthly",
      "mandate_id": "MD_ABCDEF123456",
      "mobile": "233544338841",
      "provider": "MTN",
      "starts_at": "2026-07-07",
      "ends_at": "2036-07-07"
    },
    "get_v1_subscriptions_response_200": {
      "object": "subscription",
      "subscription_id": "SUB_ABCDEF123456",
      "status": "active",
      "merchant_reference": "SUB-1042",
      "customer_name": "Jane Doe",
      "customer_email": "jane@example.com",
      "plan_id": "PLN_ABCDEF123456",
      "plan_name": "Gold Monthly",
      "mandate_id": "MD_ABCDEF123456",
      "mobile": "233544338841",
      "provider": "MTN",
      "starts_at": "2026-07-07",
      "ends_at": "2036-07-07"
    }
  },
  "contract_matrix": {
    "_note": "Maps each endpoint to its request and response sample keys in this file. Use for QA and integration verification. Request bodies use flat fields (mobile, provider) instead of nested customer/beneficiary where applicable. GET /v1/balance accepts optional ?currency=; omit to use the merchant default from the portal. Subscription endpoints require the subscriptions product (api_subscriptions_enabled). When sub-accounts are enabled, send X-Mojo-Account-Ref on authenticated routes except metadata and balance.",
    "endpoints": [
      {
        "method": "POST",
        "path": "/v1/oauth/token",
        "idempotency_key": false,
        "request_sample": "authentication.post_v1_oauth_token_request",
        "request_sample_minimal": "authentication.post_v1_oauth_token_request_minimal",
        "response_sample": "authentication.post_v1_oauth_token_response_200"
      },
      {
        "method": "GET",
        "path": "/v1/account",
        "idempotency_key": false,
        "headers_sample": "common.sub_account_request_headers",
        "response_sample_200": "merchant_accounts.get_v1_account_response_200"
      },
      {
        "method": "POST",
        "path": "/v1/collections",
        "idempotency_key": true,
        "headers_sample": "common.idempotent_post_headers",
        "request_sample_minimum": "collections.post_v1_collections_request_type_mobile_money_minimum",
        "request_sample_full": "collections.post_v1_collections_full_request",
        "response_sample_201": "collections.post_v1_collections_response_201",
        "webhook_processing": "webhooks.collection_processing",
        "webhook_succeeded": "webhooks.collection_succeeded",
        "webhook_failed": "webhooks.collection_failed"
      },
      {
        "method": "GET",
        "path": "/v1/collections/{id} or ?merchant_reference=",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "response_sample_200": "collections.get_v1_collections_response_200"
      },
      {
        "method": "POST",
        "path": "/v1/checkout/sessions",
        "idempotency_key": true,
        "headers_sample": "common.idempotent_post_headers",
        "request_sample_minimum": "checkout_sessions.post_v1_checkout_sessions_request_customer_minimum",
        "request_sample_full": "checkout_sessions.post_v1_checkout_sessions_request",
        "request_sample_portal_customer_choice": "checkout_sessions.post_v1_checkout_sessions_request_portal_customer_choice",
        "request_sample_open_amount": "checkout_sessions.post_v1_checkout_sessions_request_open_amount",
        "response_sample_201": "checkout_sessions.post_v1_checkout_sessions_response_201",
        "webhook_processing": "webhooks.checkout_session_processing",
        "webhook_succeeded": "webhooks.checkout_session_succeeded",
        "webhook_failed": "webhooks.checkout_session_failed"
      },
      {
        "method": "GET",
        "path": "/v1/checkout/sessions/{id}",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "response_sample_200_mobile_money": "checkout_sessions.get_v1_checkout_sessions_id_response_200_mobile_money",
        "response_sample_200_open_amount": "checkout_sessions.get_v1_checkout_sessions_id_response_200_open_amount"
      },
      {
        "method": "GET",
        "path": "/v1/transactions/verify/{merchant_reference}",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "response_sample_200_collection": "transactions.get_v1_transactions_verify_merchant_reference_response_200_collection",
        "response_sample_200_checkout": "transactions.get_v1_transactions_verify_merchant_reference_response_200_checkout",
        "response_sample_200_payout": "transactions.get_v1_transactions_verify_merchant_reference_response_200_payout"
      },
      {
        "method": "POST",
        "path": "/v1/payouts",
        "idempotency_key": true,
        "headers_sample": "common.idempotent_post_headers",
        "request_sample_mobile_money": "payouts.post_v1_payouts_request_type_mobile_money",
        "request_sample_bank": "payouts.post_v1_payouts_request_type_bank",
        "response_sample_201_mobile_money": "payouts.post_v1_payouts_response_201_type_mobile_money",
        "response_sample_201_bank": "payouts.post_v1_payouts_response_201_type_bank",
        "webhook_processing": "webhooks.payout_processing",
        "webhook_succeeded": "webhooks.payout_succeeded",
        "webhook_failed": "webhooks.payout_failed"
      },
      {
        "method": "GET",
        "path": "/v1/payouts/{merchant_reference}",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "response_sample_200": "payouts.get_v1_payouts_merchant_reference_response_200"
      },
      {
        "method": "POST",
        "path": "/v1/verifications/msisdn",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "request_sample": "verifications.post_v1_verifications_msisdn_request",
        "response_sample_200_verified": "verifications.post_v1_verifications_msisdn_response_200_verified",
        "response_sample_200_invalid": "verifications.post_v1_verifications_msisdn_response_200_invalid"
      },
      {
        "method": "POST",
        "path": "/v1/verifications/bank_accounts",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "request_sample": "verifications.post_v1_verifications_bank_accounts_request",
        "response_sample_200_verified": "verifications.post_v1_verifications_bank_accounts_response_200_verified",
        "response_sample_200_invalid": "verifications.post_v1_verifications_bank_accounts_response_200_invalid"
      },
      {
        "method": "POST",
        "path": "/v1/mandates",
        "idempotency_key": true,
        "headers_sample": "common.idempotent_post_headers",
        "request_sample_daily": "mandates.post_v1_mandates_request_frequency_daily",
        "request_sample_weekly": "mandates.post_v1_mandates_request_frequency_weekly",
        "request_sample_monthly": "mandates.post_v1_mandates_request_frequency_monthly",
        "response_sample_201": "mandates.post_v1_mandates_response_201",
        "webhook_processing": "webhooks.mandate_processing",
        "webhook_succeeded": "webhooks.mandate_succeeded"
      },
      {
        "method": "GET",
        "path": "/v1/mandates?merchant_reference=",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "response_sample_200": "mandates.get_v1_mandates_response_200"
      },
      {
        "method": "POST",
        "path": "/v1/mandates/{mandate_id}/cancel",
        "idempotency_key": true,
        "headers_sample": "common.idempotent_post_headers",
        "request_sample": "mandates.post_v1_mandates_mandate_id_cancel_request",
        "response_sample_200": "mandates.post_v1_mandates_mandate_id_cancel_response_200",
        "webhook_cancelled": "webhooks.mandate_cancelled"
      },
      {
        "method": "POST",
        "path": "/v1/mandates/{mandate_id}/debits",
        "idempotency_key": true,
        "headers_sample": "common.idempotent_post_headers",
        "request_sample": "mandates.post_v1_mandates_mandate_id_debits_request",
        "response_sample_201": "mandates.post_v1_mandates_mandate_id_debits_response_201",
        "webhook_processing": "webhooks.mandate_debit_processing",
        "webhook_succeeded": "webhooks.mandate_debit_succeeded",
        "webhook_failed": "webhooks.mandate_debit_failed"
      },
      {
        "method": "GET",
        "path": "/v1/mandate_debits/status?mandate_id=&merchant_reference=",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "response_sample_200": "mandates.get_v1_mandate_debits_status_response_200"
      },
      {
        "method": "GET",
        "path": "/v1/subscription_plans",
        "idempotency_key": false,
        "requires_product": "api_subscriptions_enabled",
        "headers_sample": "common.authenticated_request_headers",
        "response_sample_200": "subscriptions.get_v1_subscription_plans_response_200"
      },
      {
        "method": "POST",
        "path": "/v1/subscriptions",
        "idempotency_key": true,
        "requires_product": "api_subscriptions_enabled",
        "headers_sample": "common.idempotent_post_headers",
        "request_sample": "subscriptions.post_v1_subscriptions_request",
        "response_sample_201": "subscriptions.post_v1_subscriptions_response_201",
        "webhook_created": "webhooks.subscription_created",
        "webhook_active": "webhooks.subscription_active",
        "webhook_charge_failed": "webhooks.subscription_charge_failed"
      },
      {
        "method": "GET",
        "path": "/v1/subscriptions?merchant_reference=",
        "idempotency_key": false,
        "requires_product": "api_subscriptions_enabled",
        "headers_sample": "common.authenticated_request_headers",
        "response_sample_200": "subscriptions.get_v1_subscriptions_response_200"
      },
      {
        "method": "GET",
        "path": "/v1/metadata/banks",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "response_sample_200": "metadata_and_balance.get_v1_metadata_banks_response_200"
      },
      {
        "method": "GET",
        "path": "/v1/metadata/mobile_providers",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "response_sample_200": "metadata_and_balance.get_v1_metadata_mobile_providers_response_200"
      },
      {
        "method": "GET",
        "path": "/v1/balance",
        "idempotency_key": false,
        "headers_sample": "common.authenticated_request_headers",
        "query_optional": "currency (ISO 4217; defaults from merchant profile when omitted)",
        "response_sample_200": "metadata_and_balance.get_v1_balance_response_200"
      }
    ]
  }
}
