# Smobilpay S3P API — Partner Integration Spec
# Curated subset of s3p_3.2.0_openapi_specs_internal.yml. Documents only
# the endpoints a partner integrator needs (matches the developer page +
# llms brief in this folder). No internal implementation references.

openapi: 3.0.3
info:
  title: Smobilpay S3P API (Partner)
  description: "**Smobilpay Third Party API — Partner Integration Spec.**\n\nThis is the curated, partner-facing\
    \ subset of the S3P API. It documents\nevery endpoint a partner needs to integrate payment collections,\
    \ payouts,\nvalue-added services, and account/service discovery — and nothing else.\n\n## What this\
    \ API does\n\n- **Payment collections.** Take payment from a customer's mobile wallet via a\n  quote-then-confirm\
    \ flow. Works for collections, bill payment, top-up,\n  voucher purchase, product purchase, and subscription\
    \ top-up.\n- **Disbursements.** Send funds out to a recipient's mobile wallet.\n- **Account and service\
    \ discovery.** Retrieve the static catalog of merchants,\n  services, products, and payment items\
    \ needed to drive a payment UI.\n- **Status verification.** Look up the live status of a previously\
    \ issued\n  transaction by PTN or by your own custom transaction reference, and search\n  historical\
    \ activity by date range.\n\n## Authentication\n\nEvery secured endpoint requires an OAuth 2.0 bearer\
    \ minted at\n`POST /oauth/token` using the `client_credentials` grant. Send\n`Authorization: Bearer\
    \ <jwt>` on every request until the bearer expires.\n\n## Conventions\n\n- All requests and responses\
    \ are JSON unless explicitly noted.\n- Monetary amounts are integers in the local currency of the\
    \ payment item\n  (no decimals).\n- Currencies are ISO 4217 codes; countries are ISO 3166-1 alpha-3.\n\
    - Errors follow the standard `Error` envelope (`respCode`, `devMsg`,\n  `usrMsg`, `link`). Match on\
    \ `respCode` for programmatic handling.\n- The `x-api-version` request header is optional but\
    \ recommended; new integrations should send `3.0.0` (omitting it returns the legacy shape on some\
    \ endpoints, e.g. /v2/service and /v2/ping, and is never rejected).\n\n## Onboarding\n\nBase URL, partner credentials\
    \ (`publicKey` / `secretKey`), and callback\nURL registration are issued by Maviance support during\
    \ partner\nonboarding. They are intentionally not published in this spec.\n"
  version: 3.2.0-partner
  contact:
    name: Maviance Developer Relations
    email: support@smobilpay.com
  license:
    name: Proprietary
    url: <issued-during-onboarding>
tags:
- name: Authentication
  description: 'Token issuance for the OAuth 2.0 client_credentials grant. The

    `/oauth/token` endpoint is the only authentication operation

    partners interact with directly — once a bearer is minted, every

    other operation accepts it via the `s3pOAuth2` security scheme.

    '
- name: Masterdata
  description: Static reference data (merchants, services, products) used to populate UIs.
- name: Account Validation
  description: Pre-payment account checks.
- name: Initiate
  description: Lookups and quotes that prepare a payment collection.
- name: Confirm
  description: Endpoints that execute a payment collection against a quote.
- name: Verify
  description: Endpoints that report on existing payment collections.
security:
- s3pOAuth2:
  - s3p
paths:
  /v2/ping:
    get:
      operationId: get-ping
      tags:
      - Verify
      summary: Authenticated round-trip probe.
      description: 'Authenticated probe that echoes server time, server version, and the

        client nonce/key used to authenticate the request. Useful for

        verifying credential setup end to end.

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      responses:
        '200':
          description: Probe succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Ping'
              examples:
                default:
                  $ref: '#/components/examples/PingExample'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /oauth/token:
    post:
      operationId: oauth-token
      tags:
      - Authentication
      summary: Mint an OAuth 2.0 access token (client_credentials grant).
      description: 'Exchanges partner credentials for a JWT access token usable as a

        Bearer on every other operation. Anonymous endpoint — partner

        credentials are carried in the `Authorization: Basic` header

        of the request itself, per OAuth 2.0 RFC 6749 §4.4.


        Tokens minted here can be replayed until `expires_in` runs out.

        Mint a fresh token through this endpoint when the previous one

        expires; tokens obtained outside this endpoint will not be

        accepted on `/v2/*` operations.

        '
      security: []
      requestBody:
        required: true
        description: 'OAuth 2.0 form parameters, sent as `application/x-www-form-urlencoded`
          (RFC 6749 §4.4.2 — JSON is not accepted at the token endpoint).
          `grant_type=client_credentials` is required; an absent body or missing
          `grant_type` is rejected with `invalid_request`, and any other value with
          `unsupported_grant_type`.'
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
              - grant_type
              properties:
                grant_type:
                  type: string
                  enum:
                  - client_credentials
                  example: client_credentials
      parameters:
      - name: Authorization
        in: header
        required: true
        description: 'HTTP Basic credentials — `Basic base64(publicKey:secretKey)`.

          '
        schema:
          type: string
          example: Basic UzNQQUdFTlQ6QkE4NzVGNzAtRDZFRi02MzNELTA3ODMtRDA1MzhGOUJBRjkx
      responses:
        '200':
          description: Token minted. Standard OAuth 2.0 token response.
          content:
            application/json:
              schema:
                type: object
                required:
                - access_token
                - token_type
                - expires_in
                properties:
                  access_token:
                    type: string
                    description: 'Signed JWT. Send as `Authorization: Bearer <access_token>` on subsequent
                      operations.'
                  token_type:
                    type: string
                    example: Bearer
                  expires_in:
                    type: integer
                    description: Lifetime in seconds. The bearer is reusable until then.
                    example: 3600
        '400':
          description: '`invalid_request` — the body was not `application/x-www-form-urlencoded`,
            or `grant_type` was absent; or `unsupported_grant_type` — `grant_type` was
            supplied with a value other than `client_credentials`.'
        '401':
          description: '`invalid_client` — Basic header missing, malformed, or credentials rejected.'
        '502':
          description: Token issuance temporarily unavailable.
        '504':
          description: Token issuance timed out.
  /v2/merchant:
    get:
      operationId: get-merchant-data
      tags:
      - Masterdata
      summary: Retrieve list of merchants supported by the system.
      description: Provides merchants supported by the system. Every service is assigned to a merchant.
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      responses:
        '200':
          description: Merchant response.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Merchant'
              examples:
                default:
                  $ref: '#/components/examples/MerchantList'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/service:
    get:
      operationId: get-all-services-data
      tags:
      - Masterdata
      summary: Retrieve list of services supported by the system.
      description: 'Provides information about the services supported by the system.

        Each service has its own set of required input parameters which need

        to be provided during the collection request — starting with the prefix

        `isReq`. Configure the application UI based on the response values

        provided here. The service response also specifies the type of the

        service and thus details how the related payment items can be

        retrieved and collected.

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      responses:
        '200':
          description: Service response.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Service'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/product:
    get:
      operationId: get-generic-products
      tags:
      - Masterdata
      summary: Retrieve list of available products.
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - $ref: '#/components/parameters/QueryServiceIdOptional'
      responses:
        '200':
          $ref: '#/components/responses/ProductList'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/voucher:
    get:
      operationId: get-voucher-products
      tags:
      - Masterdata
      summary: Retrieve list of available vouchers to purchase.
      description: 'A purchase of a voucher will return a digital code for manual

        redemption. The code is provided in the response object of a

        successful collection (the `pin` field on `CollectionResponse`).

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - $ref: '#/components/parameters/QueryServiceIdOptional'
      responses:
        '200':
          $ref: '#/components/responses/ProductList'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/topup:
    get:
      operationId: get-topup-products
      tags:
      - Masterdata
      summary: Retrieve list of available top-up packages.
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - $ref: '#/components/parameters/QueryServiceIdOptional'
      responses:
        '200':
          description: Topup response.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Topup'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/cashin:
    get:
      operationId: get-cashin-products
      tags:
      - Masterdata
      summary: Retrieve list of available cash-in packages.
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - $ref: '#/components/parameters/QueryServiceIdOptional'
      responses:
        '200':
          description: Cashin response.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Cashin'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/cashout:
    get:
      operationId: get-cashout-products
      tags:
      - Masterdata
      summary: Retrieve list of available cash-out packages.
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - $ref: '#/components/parameters/QueryServiceIdOptional'
      responses:
        '200':
          description: Cashout response.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Cashout'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/bill:
    get:
      operationId: get-bills
      tags:
      - Initiate
      summary: Search for bills (searchable or non-searchable).
      description: 'For services with `type=SEARCHABLE_BILL`, the result set will contain

        all open bills for the provided service number, each with its own

        Payment Item ID.


        For services with `type=NON_SEARCHABLE_BILL`, the result set will

        always contain a single bill item with a Payment Item ID to perform

        the collection for the provided service number.

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - $ref: '#/components/parameters/QueryMerchant'
      - $ref: '#/components/parameters/QueryServiceIdInt'
      - name: serviceNumber
        in: query
        required: true
        description: 'Service number with merchant (e.g. meter number for a utility

          provider) for which to perform the bill payment.

          '
        schema:
          type: string
      responses:
        '200':
          description: Bill response.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Bill'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/account:
    get:
      operationId: get-agent-account
      tags:
      - Verify
      summary: Retrieve the authenticated agent's account details.
      description: 'Returns balance, agent profile, company profile, and remaining

        daily collection limit for the authenticated agent.

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      responses:
        '200':
          description: Account response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/subscription:
    get:
      operationId: search-subscription
      tags:
      - Initiate
      summary: Get subscription payment handler.
      description: 'Looks up subscription records for a service by either service number

        or customer number and retrieves details if available. The result

        set will contain a list of all available subscriptions found under

        the provided search criteria. Each subscription has its own Payment

        Item Identifier.

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - $ref: '#/components/parameters/QueryMerchant'
      - $ref: '#/components/parameters/QueryServiceIdString'
      - name: serviceNumber
        in: query
        required: false
        description: 'Service number with merchant (e.g. policy number with an

          insurance company or tax number for a governmental institution).

          '
        schema:
          type: string
      - name: customerNumber
        in: query
        required: false
        description: 'Customer number with merchant (e.g. customer number with an

          insurance company or account number for a governmental

          institution).

          '
        schema:
          type: string
      responses:
        '200':
          description: Subscription response.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Subscription'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/verify:
    get:
      operationId: verify-service-number
      tags:
      - Account Validation
      summary: Verify that a service number is valid for the selected service.
      description: 'For services that support verification (`isVerifiable: true`), the

        service number can be provided to this endpoint. The system returns

        a boolean indicating whether the service number is valid with the

        selected service.

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - $ref: '#/components/parameters/QueryMerchant'
      - $ref: '#/components/parameters/QueryServiceIdInt'
      - name: serviceNumber
        in: query
        required: true
        description: Service number with merchant.
        schema:
          type: string
      responses:
        '200':
          description: Verification result.
          content:
            application/json:
              schema:
                type: boolean
                example: true
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/validate:
    get:
      operationId: validate-account
      tags:
      - Account Validation
      summary: Resolve account holder details (restricted).
      description: 'Validates an account against the upstream service provider and,

        when available, returns the associated customer name in addition to

        a status flag.


        **Restricted endpoint.** Access is granted only to partners who have

        cleared Maviance''s internal validation and compliance review

        (KYC / data-protection obligations apply to the returned customer

        name). Unauthorized callers receive `401`. Contact your integration

        manager to request enablement.


        Unlike `/v2/verify` (which returns a boolean existence check), this

        endpoint returns personally identifiable information and is

        therefore gated by compliance review.

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - name: destination
        in: query
        required: true
        description: Account destination identifier (e.g. phone, meter, policy number).
        schema:
          type: string
      - name: serviceId
        in: query
        required: true
        description: Unique Smobilpay service identifier.
        schema:
          type: string
      responses:
        '200':
          description: Customer account response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerAccount'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/quotestd:
    post:
      operationId: quote-standard
      tags:
      - Initiate
      summary: Request a price quote for a payment collection.
      description: 'Returns a quote for the payment collection of the selected payment

        item and the specified amount. Quotes expire after a few minutes

        and must be requested fresh before each collection.

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      requestBody:
        required: true
        description: 'Quote Request. Both `application/x-www-form-urlencoded` and

          `application/json` are accepted; partners pick whichever suits

          their toolchain. JSON is the natural choice for OAuth 2.0

          bearer auth.

          '
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/QuoteRequest'
            examples:
              default:
                $ref: '#/components/examples/QuoteRequestExample'
          application/json:
            schema:
              $ref: '#/components/schemas/QuoteRequest'
            examples:
              default:
                $ref: '#/components/examples/QuoteRequestExample'
      responses:
        '200':
          description: Quote response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteResponse'
              examples:
                default:
                  $ref: '#/components/examples/QuoteResponseExample'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/collectstd:
    post:
      operationId: confirm-transaction
      tags:
      - Confirm
      summary: Execute a payment collection.
      description: 'Executes a payment collection. The agent balance is reduced by the

        service amount plus the service fee. Each collection must include

        a reference to a previously requested quote. Whether or not optional

        fields are required depends on the service configuration (the

        `isReq*` flags on the `Service` resource).

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      requestBody:
        required: true
        description: 'Collection Request. Both `application/x-www-form-urlencoded`

          and `application/json` are accepted; partners pick whichever

          suits their toolchain. JSON is the natural choice for OAuth 2.0

          bearer auth.

          '
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CollectionRequest'
            examples:
              default:
                $ref: '#/components/examples/CollectionRequestExample'
          application/json:
            schema:
              $ref: '#/components/schemas/CollectionRequest'
            examples:
              default:
                $ref: '#/components/examples/CollectionRequestExample'
      responses:
        '200':
          description: Collection response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CollectionResponse'
              examples:
                default:
                  $ref: '#/components/examples/CollectionResponseExample'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '498':
          description: Quote has expired.
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/historystd:
    get:
      operationId: payment-history
      tags:
      - Verify
      summary: Retrieve historic payment collection records.
      description: 'Search by **exactly one** of:


        - `ptn` — payment transaction number

        - `trid` — custom transaction reference provided during collection

        - the pair (`timestamp_from`, `timestamp_to`) — date range filter


        Combinations of these (e.g. `ptn` + `timestamp_from`) are rejected.

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - $ref: '#/components/parameters/HistoryQueryPtn'
      - $ref: '#/components/parameters/HistoryQueryTrid'
      - $ref: '#/components/parameters/HistoryQueryFrom'
      - $ref: '#/components/parameters/HistoryQueryTo'
      responses:
        '200':
          description: Payment status response.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaymentStatus'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
  /v2/verifytx:
    get:
      operationId: verify-transaction
      tags:
      - Verify
      summary: Get the current payment collection status.
      description: 'Returns the current payment status by either transaction number

        (`ptn`) or custom transaction reference (`trid`). At least one of

        these parameters must be provided.

        '
      parameters:
      - $ref: '#/components/parameters/XApiVersion'
      - $ref: '#/components/parameters/HistoryQueryPtn'
      - $ref: '#/components/parameters/HistoryQueryTrid'
      responses:
        '200':
          description: Payment status response.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PaymentStatus'
        '401':
          $ref: '#/components/responses/Unauthorized'
        default:
          $ref: '#/components/responses/UnexpectedError'
components:
  securitySchemes:
    s3pOAuth2:
      type: oauth2
      description: '**OAuth 2.0 client_credentials grant.**


        Mint a JWT at `POST /oauth/token` using your `publicKey` /

        `secretKey` pair as HTTP Basic credentials, then send it as

        `Authorization: Bearer <jwt>` on every other operation.


        Tokens are reusable until `exp` per RFC 6749 §1.4 — replay the

        same bearer across requests; mint a fresh one only when the

        previous one expires. Tokens issued outside `/oauth/token` are

        not accepted.


        Allowed JWS algorithms are `RS256` and `ES256`. Symmetric

        algorithms and `alg: none` are rejected.

        '
      flows:
        clientCredentials:
          tokenUrl: '{baseUrl}/oauth/token'
          scopes:
            s3p: Full access to the S3P API.
  parameters:
    XApiVersion:
      name: x-api-version
      in: header
      required: false
      description: >-
        Protocol-shape version flag (optional; recommended for new
        integrations). Send `"3.0.0"` to opt in to the v3 protocol shape.
        The server does not reject requests that omit this header. When it
        is absent, legacy per-endpoint behavior applies, which differs from
        `"3.0.0"` on some endpoints. For example `/v2/ping` reports version
        `"2.2.0"`, `/v2/service` omits CASH_OUT services and labels vouchers
        as topup, and a successful `/v2/collect` or `/v2/collectstd` is not
        rewritten from SUCCESS to PENDING. Endpoints that do not branch on
        the flag (e.g. `/v2/quotestd`, `/v2/account`) are unaffected. New
        integrations should send `"3.0.0"` on every secured request for the
        consistent v3 shape. The spec document version (3.2.0) is
        independent of this flag.
      schema:
        type: string
    QueryMerchant:
      name: merchant
      in: query
      required: true
      description: Unique merchant code.
      schema:
        type: string
    QueryServiceIdInt:
      name: serviceid
      in: query
      required: true
      description: Unique service identifier.
      schema:
        type: integer
    QueryServiceIdString:
      name: serviceid
      in: query
      required: true
      description: Unique service identifier.
      schema:
        type: string
    QueryServiceIdOptional:
      name: serviceid
      in: query
      required: false
      description: Filter results to a specific service.
      schema:
        type: integer
    HistoryQueryPtn:
      name: ptn
      in: query
      required: false
      description: Unique payment collection transaction number.
      schema:
        type: string
    HistoryQueryTrid:
      name: trid
      in: query
      required: false
      description: Custom transaction reference provided during payment collection.
      schema:
        type: string
    HistoryQueryFrom:
      name: timestamp_from
      in: query
      required: false
      description: Start date (inclusive) of result set, ISO 8601.
      schema:
        type: string
        format: date
    HistoryQueryTo:
      name: timestamp_to
      in: query
      required: false
      description: End date (inclusive) of result set, ISO 8601.
      schema:
        type: string
        format: date
  responses:
    Unauthorized:
      description: Request could not be authenticated.
    UnexpectedError:
      description: Unexpected error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ProductList:
      description: Product response.
      content:
        application/json:
          schema:
            type: array
            items:
              $ref: '#/components/schemas/Product'
  schemas:
    CurrencyCode:
      type: string
      minLength: 3
      maxLength: 3
      description: ISO 4217 currency code (e.g. `XAF`, `USD`).
      example: XAF
    CountryCode:
      type: string
      minLength: 3
      maxLength: 3
      description: ISO 3166-1 alpha-3 country code.
      example: CMR
    i18nText:
      type: object
      required:
      - language
      - localText
      properties:
        language:
          type: string
          description: Target language to retrieve the translations for (e.g. 'en', 'fr').
        localText:
          type: string
          description: Localized text.
    Ping:
      type: object
      required:
      - time
      - version
      - nonce
      - key
      properties:
        time:
          type: string
          format: date-time
          description: Current server time + timezone (ISO 8601).
        version:
          type: string
          description: 'Server-emitted protocol version. Returns `"3.0.0"` when the

            request `x-api-version` header is `"3.0.0"`, otherwise

            `"2.2.0"`.

            '
        nonce:
          type: string
          description: Nonce echoed from the request.
        key:
          type: string
          description: Public token of the user that sent the request.
    Merchant:
      type: object
      required:
      - merchant
      - name
      - description
      - country
      - status
      properties:
        merchant:
          type: string
          description: Unique merchant code. Use this value whenever `merchant` is required in request
            parameters.
        name:
          type: string
          description: Name of merchant.
        description:
          type: string
          description: Merchant description.
        category:
          type: string
          description: Deprecated; will be removed in future versions. Use categories on services.
          deprecated: true
        country:
          $ref: '#/components/schemas/CountryCode'
        status:
          type: string
          enum:
          - Active
          - Inactive
          description: Merchant status.
        logo:
          type: string
          format: uri
          description: URL of the merchant logo if available.
        logoHash:
          type: string
          description: MD5 hash of the logo at `logo`. Changes when the logo is updated.
    Service:
      type: object
      required:
      - serviceid
      - merchant
      - title
      - description
      - category
      - country
      - localCur
      - type
      - status
      - isReqCustomerName
      - isReqCustomerAddress
      - isReqCustomerNumber
      - isReqServiceNumber
      - isVerifiable
      properties:
        serviceid:
          type: integer
          description: Unique service identifier. Use this value whenever `serviceid` is required in request
            parameters.
        merchant:
          type: string
          description: Unique merchant code.
        title:
          type: string
          description: Public name of service.
        description:
          type: string
          description: Service description.
        category:
          type: string
          description: Category of service.
        country:
          $ref: '#/components/schemas/CountryCode'
        localCur:
          $ref: '#/components/schemas/CurrencyCode'
        type:
          type: string
          enum:
          - SEARCHABLE_BILL
          - NON_SEARCHABLE_BILL
          - PRODUCT
          - TOPUP
          - SUBSCRIPTION
          - CASHIN
          - CASHOUT
          - VOUCHER
          description: Type of service. Drives which masterdata endpoint produces the corresponding payment
            items.
        status:
          type: string
          enum:
          - Active
          - Inactive
          description: Service availability status.
        isReqCustomerName:
          type: boolean
          description: When true, the customer's full name must be provided in the payment collection
            request.
        isReqCustomerAddress:
          type: boolean
          description: When true, the customer's address must be provided in the payment collection request.
        isReqCustomerNumber:
          type: boolean
          description: When true, a customer number must be provided in the payment collection request.
        isReqServiceNumber:
          type: boolean
          description: When true, a service number must be provided in the payment collection request.
        labelCustomerNumber:
          type: array
          items:
            $ref: '#/components/schemas/i18nText'
          description: Localized labels for the customer-number field.
        labelServiceNumber:
          type: array
          items:
            $ref: '#/components/schemas/i18nText'
          description: Localized labels for the service-number field.
        isVerifiable:
          type: boolean
          description: When true, the service number can be verified via `/v2/verify` before paying.
        validationMask:
          type: string
          description: Optional PCRE regex validation mask for the service number.
        hint:
          type: array
          items:
            $ref: '#/components/schemas/i18nText'
          description: Localized hint texts to display to the customer.
        denomination:
          type: integer
          description: 'Service payment denomination. The payment amount must be a

            multiple of this value. Example: with denomination `50`, an

            amount of `100` is valid but `60` is not.

            '
          example: 50
    PaymentItemBase:
      type: object
      description: Common fields shared by Product, Voucher, Topup, Cashin, Cashout, Subscription, Bill
        payment items.
      required:
      - serviceid
      - merchant
      - payItemId
      - amountType
      - localCur
      - name
      properties:
        serviceid:
          type: integer
          description: Service this item belongs to.
        merchant:
          type: string
          description: Merchant of the service.
        payItemId:
          type: string
          description: Unique payment item id.
        payItemDescr:
          type: string
          description: Optional merchant-provided description.
        amountType:
          type: string
          enum:
          - FIXED
          - CUSTOM
          - PARTIAL
          - OVERPAY
          description: 'How the payment amount is determined for this item:


            - `FIXED` — must be paid in full at `amountLocalCur`.

            - `CUSTOM` — caller chooses the amount.

            - `PARTIAL` — amount may be less than `amountLocalCur`.

            - `OVERPAY` — amount may exceed `amountLocalCur` (subject to country regulation).

            '
        localCur:
          $ref: '#/components/schemas/CurrencyCode'
        name:
          type: string
          description: Customer-friendly name to display.
        amountLocalCur:
          type: number
          format: float
          description: Amount in local currency (only set for `FIXED`; null otherwise).
        description:
          type: string
          description: Optional description.
        optStrg:
          type: string
          description: Optional string field.
        optNmb:
          type: number
          description: Optional number field.
    Product:
      allOf:
      - $ref: '#/components/schemas/PaymentItemBase'
      description: 'A purchasable product. `amountType` is restricted to `FIXED` or

        `CUSTOM`.

        '
    Topup:
      allOf:
      - $ref: '#/components/schemas/PaymentItemBase'
      description: 'A top-up package. `amountType` is restricted to `FIXED` or `CUSTOM`.

        '
    Cashin:
      allOf:
      - $ref: '#/components/schemas/PaymentItemBase'
      description: 'A cash-in (mobile-wallet deposit) item. `amountType` is restricted

        to `FIXED` or `CUSTOM`.

        '
    Cashout:
      allOf:
      - $ref: '#/components/schemas/PaymentItemBase'
      description: 'A cash-out item. `amountType` is restricted to `FIXED` or `CUSTOM`.

        '
    Bill:
      allOf:
      - $ref: '#/components/schemas/PaymentItemBase'
      - type: object
        required:
        - billType
        - penaltyAmount
        - payOrder
        - serviceNumber
        properties:
          billType:
            type: string
            enum:
            - REGULAR
            - OVERDUE
            description: Bill classification.
          penaltyAmount:
            type: number
            format: double
            description: Late-payment penalty amount in local currency.
          payOrder:
            type: integer
            minimum: 0
            maximum: 255
            description: 'Payment order. Bills must be paid in ascending order

              starting from `1`. Bills with `0` impose no order.

              '
          serviceNumber:
            type: string
            description: Service number with merchant.
          billNumber:
            type: string
            description: Unique bill number in the selected merchant service.
          customerNumber:
            type: string
            description: Customer number with merchant.
          billMonth:
            type: string
            pattern: ^[0-9]{2}$
            description: Two-digit month of bill generation, e.g. `03`.
          billYear:
            type: string
            pattern: ^[0-9]{4}$
            description: Four-digit year of bill generation, e.g. `2026`.
          billDate:
            type: string
            format: date
            description: Exact date of bill generation (ISO 8601).
          billDueDate:
            type: string
            format: date
            description: Bill due date (ISO 8601).
    Subscription:
      allOf:
      - $ref: '#/components/schemas/PaymentItemBase'
      - type: object
        required:
        - serviceNumber
        properties:
          serviceNumber:
            type: string
            description: Service number with merchant.
          customerReference:
            type: string
            description: Optional customer reference.
          customerName:
            type: string
            description: Customer name.
          customerNumber:
            type: string
            description: Optional customer number with merchant.
          startDate:
            type: string
            format: date
            description: Optional start date (ISO 8601).
          dueDate:
            type: string
            format: date
            description: Optional due date (ISO 8601).
          endDate:
            type: string
            format: date
            description: Optional end date (ISO 8601).
    Account:
      type: object
      required:
      - balance
      - currency
      - key
      - agentId
      - agentName
      - agentAddress
      - agentPhonenumber
      - companyName
      - companyAddress
      - companyPhonenumber
      - limitMax
      - limitRemaining
      properties:
        balance:
          type: number
          format: float
          description: Remaining amount in account.
        currency:
          $ref: '#/components/schemas/CurrencyCode'
        key:
          type: string
          description: Public access key.
        agentId:
          type: string
          description: Unique agent identifier.
        agentName:
          type: string
          description: Agent full name.
        agentAddress:
          type: string
          description: Agent full address.
        agentPhonenumber:
          type: string
          description: Agent phone number.
        companyName:
          type: string
          description: Collector company name.
        companyAddress:
          type: string
          description: Collector company address.
        companyPhonenumber:
          type: string
          description: Collector company phone number.
        limitMax:
          type: number
          format: float
          description: Daily collection limit — maximum amount collectable per day by this account.
        limitRemaining:
          type: number
          format: float
          description: Collection limit remaining for the day (resets at 00:00 UTC).
    CustomerAccount:
      type: object
      required:
      - destination
      - status
      description: Account of customer if customer was identifiable. Returned by
        the restricted `GET /v2/validate` endpoint.
      properties:
        status:
          type: string
          enum:
          - UNKNOWN
          - VALIDATED
          - VERIFIED
          description: |
            Validation status:

            - `UNKNOWN` — neither verified nor validated
            - `VALIDATED` — internally syntactically valid (e.g. regex)
            - `VERIFIED` — confirmed against the service provider
        name:
          type: string
          description: Customer name if found.
        destination:
          type: string
          description: Account destination identifier used during lookup.
    QuoteRequest:
      type: object
      required:
      - amount
      - payItemId
      properties:
        amount:
          type: integer
          minimum: 1
          description: 'Amount to be collected (full integer value, no decimals, in

            the local currency of the payment item). Subject to the item''s

            `amountType` constraint.

            '
        payItemId:
          type: string
          description: Unique payment item id to quote.
    QuoteResponse:
      type: object
      required:
      - quoteId
      - expiresAt
      - payItemId
      - amountLocalCur
      - localCur
      - systemCur
      - promotion
      properties:
        quoteId:
          type: string
          format: uuid
          description: Unique quote number.
        expiresAt:
          type: string
          format: date-time
          description: Expiration timestamp (ISO 8601).
        payItemId:
          type: string
          description: Unique payment item id this quote was issued for.
        amountLocalCur:
          type: number
          format: float
          description: Service amount in local currency.
        priceLocalCur:
          type: number
          format: float
          description: Total price (amount + fees) in local currency.
        priceSystemCur:
          type: number
          format: float
          description: Total price (amount + fees) in system currency.
        localCur:
          $ref: '#/components/schemas/CurrencyCode'
        systemCur:
          $ref: '#/components/schemas/CurrencyCode'
        promotion:
          type: string
          nullable: true
          description: Optional comma-separated list of current or upcoming promotions on the quoted service.
    CollectionRequest:
      type: object
      required:
      - quoteId
      - customerPhonenumber
      - customerEmailaddress
      properties:
        quoteId:
          type: string
          format: uuid
          description: Quote id from a prior `/v2/quotestd` (or `/v2/agent/topup/initiate`) call.
        customerPhonenumber:
          type: string
          pattern: ^[0-9]+$
          description: 'Customer phone number for regulatory compliance.

            International format with country code, no leading `+`,

            digits only. E.g. `237699999999`.

            '
        customerEmailaddress:
          type: string
          format: email
          description: Customer email address for regulatory compliance.
        customerName:
          type: string
          description: Required only if `service.isReqCustomerName == true`.
        customerAddress:
          type: string
          description: Required only if `service.isReqCustomerAddress == true`.
        customerNumber:
          type: string
          description: Required only if `service.isReqCustomerNumber == true`.
        serviceNumber:
          type: string
          description: Required only if `service.isReqServiceNumber == true`.
        trid:
          type: string
          description: 'Custom external transaction reference. Caller-managed; the API

            does **not** enforce uniqueness — the client is responsible

            for that.

            '
        tag:
          type: string
          maxLength: 50
          description: Optional free-form tag included in payment status responses and reports.
          example: customPaymentTag1
        callbackUrl:
          type: string
          format: uri
          maxLength: 255
          description: Optional webhook URL to be notified about payment status changes.
          example: https://webhook.payment.demo
        cdata:
          type: string
          description: Optional valid JSON string for special-purpose extended payloads.
    CollectionResponse:
      type: object
      required:
      - ptn
      - timestamp
      - agentBalance
      - receiptNumber
      - veriCode
      - priceLocalCur
      - priceSystemCur
      - localCur
      - systemCur
      - status
      properties:
        ptn:
          type: string
          description: Unique payment collection transaction number.
        timestamp:
          type: string
          format: date-time
          description: Timestamp of processing in the system (ISO 8601).
        agentBalance:
          type: number
          format: float
          description: Agent account balance after the collection (in system currency).
        receiptNumber:
          type: string
          description: Receipt number; bound to agent context, NOT globally unique.
        veriCode:
          type: string
          description: Verification code for the receipt number.
        priceLocalCur:
          type: number
          format: float
          description: Price paid in local currency.
        priceSystemCur:
          type: number
          format: float
          description: Price paid in system currency.
        localCur:
          $ref: '#/components/schemas/CurrencyCode'
        systemCur:
          $ref: '#/components/schemas/CurrencyCode'
        trid:
          type: string
          description: Custom external transaction reference echoed from the request.
        pin:
          type: string
          nullable: true
          description: For VOUCHER services — the digital code/PIN. Null otherwise.
        status:
          type: string
          enum:
          - REVERSED
          - PENDING
          - ERRORED
          - SUCCESS
          description: 'Payment processing status. **Note:** when the request header `x-api-version: 3.0.0`
            is

            set, a `SUCCESS` status is rewritten to `PENDING` server-side.

            '
        payItemId:
          type: string
          description: Payment item id (echoed from the quote).
        payItemDescr:
          type: string
          description: Optional human-readable description of the payment item.
        tag:
          type: string
          maxLength: 50
          description: Tag echoed from the request.
          example: customPaymentTag1
    PaymentStatus:
      type: object
      required:
      - ptn
      - serviceid
      - merchant
      - timestamp
      - receiptNumber
      - veriCode
      - clearingDate
      - trid
      - priceLocalCur
      - priceSystemCur
      - localCur
      - systemCur
      - status
      - errorCode
      properties:
        ptn:
          type: string
          description: Unique payment collection transaction number.
        serviceid:
          type: string
          description: Service identifier.
        merchant:
          type: string
          description: Merchant code.
        timestamp:
          type: string
          format: date-time
          description: Timestamp of processing in the system (ISO 8601).
        receiptNumber:
          type: string
          description: Receipt number.
        veriCode:
          type: string
          description: Verification code for the receipt number.
        clearingDate:
          type: string
          format: date
          nullable: true
          description: Date payment information was sent to the merchant (if supported).
        trid:
          type: string
          description: Custom transaction reference provided during collection.
        priceLocalCur:
          type: number
          format: float
          description: Total price paid in local currency.
        priceSystemCur:
          type: number
          format: float
          description: Total price paid in system currency.
        localCur:
          $ref: '#/components/schemas/CurrencyCode'
        systemCur:
          $ref: '#/components/schemas/CurrencyCode'
        pin:
          type: string
          nullable: true
          description: Digital code/PIN to display to the customer (if supplied by the service).
        status:
          type: string
          enum:
          - REVERSED
          - PENDING
          - ERRORED
          - SUCCESS
          description: Payment processing status.
        payItemId:
          type: string
          description: Payment item id.
        payItemDescr:
          type: string
          description: Optional description.
        errorCode:
          type: integer
          description: Service-provider error code (`0` if no error).
        tag:
          type: string
          maxLength: 50
          description: Tag echoed from the original collection request.
          example: customPaymentTag1
        commission:
          type: object
          description: 'Commission earned for this transaction. Present only when the

            commission feature is enabled for the merchant/service.

            '
          required:
          - earnings
          - currency
          properties:
            earnings:
              type: number
              format: float
              description: Commission amount earned for this transaction.
            currency:
              $ref: '#/components/schemas/CurrencyCode'
    Error:
      type: object
      required:
      - respCode
      - devMsg
      - usrMsg
      - link
      description: 'Standard error envelope. The `respCode` is the canonical machine

        identifier — match on this rather than parsing `devMsg`. The full error catalog is provided during
        partner onboarding.

        '
      properties:
        respCode:
          type: integer
          description: 'Unique error response code identifying the issue.

            Recommended for programmatic error handling in your client.

            '
        devMsg:
          type: string
          description: Verbose, plain-language description for the integrator with hints on remediation.
        usrMsg:
          type: string
          description: High-level, user-safe error message.
        link:
          type: string
          format: uri
          description: Link to documentation for this error response code (when available).
  examples:
    PingExample:
      summary: Authenticated probe response.
      value:
        time: '2026-05-02T08:30:00+00:00'
        version: 3.0.0
        nonce: 0fbb3c52e7af4b66
        key: ABCDEF1234567890
    MerchantList:
      summary: Two merchants.
      value:
      - merchant: ENEO
        name: Eneo Cameroon
        description: National electricity utility
        country: CMR
        status: Active
        logo: <issued-during-onboarding>
        logoHash: 9c8b73a0f4d6e5f1
      - merchant: CDE
        name: Camwater
        description: National water utility
        country: CMR
        status: Active
    QuoteRequestExample:
      summary: Standard quote request.
      value:
        amount: 5000
        payItemId: PI-ENEO-PREPAID-001
    QuoteResponseExample:
      summary: Successful quote response.
      value:
        quoteId: 0e1f7f4a-3b2c-4a8d-9d1f-1f5d2c3a4b6e
        expiresAt: '2026-05-02T08:35:00Z'
        payItemId: PI-ENEO-PREPAID-001
        amountLocalCur: 5000
        priceLocalCur: 5050
        priceSystemCur: 8.31
        localCur: XAF
        systemCur: EUR
        promotion: null
    CollectionRequestExample:
      summary: Standard collection request.
      value:
        quoteId: 0e1f7f4a-3b2c-4a8d-9d1f-1f5d2c3a4b6e
        customerPhonenumber: '237699999999'
        customerEmailaddress: customer@example.com
        customerName: Jane Doe
        trid: ORDER-2026-05-02-0001
        tag: retail-front-desk
    CollectionResponseExample:
      summary: Successful collection response.
      value:
        ptn: PTN-202605020800001
        timestamp: '2026-05-02T08:34:12Z'
        agentBalance: 1245.32
        receiptNumber: RCPT-0001-001234
        veriCode: X9F2
        priceLocalCur: 5050
        priceSystemCur: 8.31
        localCur: XAF
        systemCur: EUR
        trid: ORDER-2026-05-02-0001
        pin: null
        status: SUCCESS
        payItemId: PI-ENEO-PREPAID-001
        payItemDescr: Eneo prepaid token
        tag: retail-front-desk
servers:
- url: '{baseUrl}'
  description: Base URL issued by Maviance support during onboarding.
  variables:
    baseUrl:
      default: https://api.example.invalid
      description: Replace with the base URL provided to you on onboarding.
