> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xentfi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create an order

> Creates a collection order and returns the payment instructions.

`customer.name` must be the **payer's full name** — the provider matches it against the sending bank account / mobile-money wallet and rejects mismatches. Mobile money requires `mobileMoney.{phoneNumber, networkProvider}`; the prompt is sent immediately.

**Idempotent:** same `reference` + `sessionId` returns the same order; a quote is single-use. **Rate guard:** if the rate worsened more than the tolerance since the quote, the call fails with 409 and nothing is created at the provider for payment.

Orders expire after `validityTimeMinutes` (30–1440, default 30). The provider has no cancel/expire call, so **a payment that still arrives after expiry or cancellation is honoured** (`metadata.latePayment: true`).

**Webhook events:** `onramp.created`, `onramp.paid`, `onramp.processing`, `onramp.completed`, `onramp.expired`, `onramp.failed`, `onramp.cancelled`.

**Flow:** `GET /currencies` → `GET /assets?walletId&currency` → `GET /rails?currency` → `POST /quotes` (rate session) → `POST /orders` → show `paymentInstructions` to your payer → track via `onramp.*` webhooks or `GET /orders/{id}` → stablecoin is credited to your wallet.

**Rails:** `bank_transfer` — a one-time bank account is generated per order (NGN; GHS bank unverified). `mobile_money` — GHS; the payer approves a prompt on their phone (`nextStep: PIN`) or, when the provider asks, you submit an OTP via `POST /orders/{id}/verify-otp` (`status: awaiting_otp`). USD/EUR are collected through customer virtual accounts, not this API.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/onramp/orders
openapi: 3.0.3
info:
  title: XentFi API
  version: 1.0.0
  description: >-
    API documentation for XentFi.The XentFi API gives you access to pretty much
    all the features you can use on our dashboard and lets you extend them for
    use in your application. It strives to be RESTful and is organized around
    the main resources you would be interacting with - with a few notable
    exceptions.
servers:
  - url: https://api.xentfi.com
    description: Production server
security: []
tags: []
paths:
  /v1/onramp/orders:
    post:
      tags:
        - On-ramp
      summary: Create an order
      description: >-
        Creates a collection order and returns the payment instructions.


        `customer.name` must be the **payer's full name** — the provider matches
        it against the sending bank account / mobile-money wallet and rejects
        mismatches. Mobile money requires `mobileMoney.{phoneNumber,
        networkProvider}`; the prompt is sent immediately.


        **Idempotent:** same `reference` + `sessionId` returns the same order; a
        quote is single-use. **Rate guard:** if the rate worsened more than the
        tolerance since the quote, the call fails with 409 and nothing is
        created at the provider for payment.


        Orders expire after `validityTimeMinutes` (30–1440, default 30). The
        provider has no cancel/expire call, so **a payment that still arrives
        after expiry or cancellation is honoured** (`metadata.latePayment:
        true`).


        **Webhook events:** `onramp.created`, `onramp.paid`,
        `onramp.processing`, `onramp.completed`, `onramp.expired`,
        `onramp.failed`, `onramp.cancelled`.


        **Flow:** `GET /currencies` → `GET /assets?walletId&currency` → `GET
        /rails?currency` → `POST /quotes` (rate session) → `POST /orders` → show
        `paymentInstructions` to your payer → track via `onramp.*` webhooks or
        `GET /orders/{id}` → stablecoin is credited to your wallet.


        **Rails:** `bank_transfer` — a one-time bank account is generated per
        order (NGN; GHS bank unverified). `mobile_money` — GHS; the payer
        approves a prompt on their phone (`nextStep: PIN`) or, when the provider
        asks, you submit an OTP via `POST /orders/{id}/verify-otp` (`status:
        awaiting_otp`). USD/EUR are collected through customer virtual accounts,
        not this API.
      operationId: createOnrampOrder
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - sessionId
                - reference
                - rail
                - customer
              properties:
                sessionId:
                  type: string
                  format: uuid
                reference:
                  type: string
                  pattern: ^[A-Za-z0-9_-]{8,64}$
                rail:
                  type: string
                  enum:
                    - bank_transfer
                    - mobile_money
                customer:
                  type: object
                  required:
                    - name
                  properties:
                    name:
                      type: string
                      example: Ada Obi
                      description: Payer's full name — must match the paying account
                    email:
                      type: string
                      format: email
                mobileMoney:
                  type: object
                  description: Required for rail mobile_money
                  required:
                    - phoneNumber
                    - networkProvider
                  properties:
                    phoneNumber:
                      type: string
                      example: 244007778
                    networkProvider:
                      type: string
                      enum:
                        - MTN
                        - AIRTEL
                        - VODAFONE
                validityTimeMinutes:
                  type: integer
                  minimum: 30
                  maximum: 1440
                  default: 30
                metadata:
                  type: object
      responses:
        '201':
          description: Order created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      reference:
                        type: string
                      rail:
                        type: string
                        enum:
                          - bank_transfer
                          - mobile_money
                      status:
                        type: string
                        enum:
                          - initiated
                          - pending
                          - awaiting_otp
                          - paid
                          - processing
                          - completed
                          - expired
                          - cancelled
                          - failed
                      walletId:
                        type: string
                      assetId:
                        type: string
                      currency:
                        type: string
                      amount:
                        type: string
                        description: Stablecoin the wallet receives
                      amountFiat:
                        type: string
                      feeFiat:
                        type: string
                      amountFiatPayable:
                        type: string
                        nullable: true
                        description: Total the payer must send
                      amountFiatReceived:
                        type: string
                        nullable: true
                      rate:
                        type: string
                      paymentInstructions:
                        type: object
                        nullable: true
                        properties:
                          type:
                            type: string
                            enum:
                              - bank_transfer
                              - mobile_money
                          bank:
                            type: object
                            properties:
                              name:
                                type: string
                              accountName:
                                type: string
                              accountNumber:
                                type: string
                          mobileMoney:
                            type: object
                            properties:
                              phoneNumber:
                                type: string
                                description: Masked
                              networkProvider:
                                type: string
                              nextStep:
                                type: string
                                enum:
                                  - PIN
                                  - OTP
                              prompt:
                                type: string
                          amountToPay:
                            type: string
                          currency:
                            type: string
                          expiresAt:
                            type: string
                            format: date-time
                      customer:
                        type: object
                        properties:
                          name:
                            type: string
                          email:
                            type: string
                      transactionHash:
                        type: string
                        nullable: true
                        description: >-
                          On-chain hash of the delivery to your wallet, when
                          reported
                      failureReason:
                        type: string
                        nullable: true
                      failureStage:
                        type: string
                        nullable: true
                        enum:
                          - provider_setup
                          - rate_moved
                          - provider
                          - abandoned
                      requiresOtp:
                        type: boolean
                      expiresAt:
                        type: string
                        format: date-time
                      metadata:
                        type: object
                        nullable: true
                      createdAt:
                        type: string
                        format: date-time
                      updatedAt:
                        type: string
                        format: date-time
                      completedAt:
                        type: string
                        format: date-time
                        nullable: true
        '400':
          description: Validation or provider rejection (e.g. mobile money failed)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        example: NOT_FOUND
                      message:
                        type: string
                        example: Wallet not found
                      timestamp:
                        type: string
                        format: date-time
                      requestId:
                        type: string
        '404':
          description: Quote session not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        example: NOT_FOUND
                      message:
                        type: string
                        example: Wallet not found
                      timestamp:
                        type: string
                        format: date-time
                      requestId:
                        type: string
        '409':
          description: Quote used/expired, rate moved, or reference conflict
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        example: NOT_FOUND
                      message:
                        type: string
                        example: Wallet not found
                      timestamp:
                        type: string
                        format: date-time
                      requestId:
                        type: string
      security:
        - ApiKeyAuth: []
          OrgIdAuth: []
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: apiKey
    OrgIdAuth:
      type: apiKey
      in: header
      name: orgId

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.