Skip to content

Topup intents

Issue a top-up reference the customer quotes when paying

POST/api/v1/tenant/topup-intents

Scope topup-intents:write · Write — send Idempotency-Key and X-Request-Id

Creates a topup_c2b operation in state pending_provider with a 12-digit intentReference and an expiresAt; no money moves yet. The payment provider (railCode) must be active and able to receive payments, and the customer and wallet able to receive a credit. The wallet is credited when the payment provider reports a payment carrying the reference and the exact amount before the intent expires (topup.confirmed); a payment that does not match is not credited and is held by Neo Wallet for reconciliation. Without a matching payment the intent fails at expiresAt (topup.expired).

Request body

FieldTypeRequiredDescription
walletUidstringyesThe wallet the top-up credits, as returned by POST /tenant/customers.
amountMinornumberyesPositive integer minor units (e.g. 250000 = ETB 2,500.00); the exact amount the payer must pay in. Min 1.
currencystringyesISO-4217; must equal the wallet's currency.
railCodestringyesThe payment provider's code the payer will pay through; the provider must be active and accept incoming payments. At most 64 characters.
expiresInSecondsobjectnoLifetime of the intent in seconds; defaults to the payment provider's configured lifetime, else one hour. Min 60. Max 86400.
clientReferencestringyesYour own reference; stored and returned verbatim, never interpreted; unique within your account.
Example (generated from the schema)
json
{
  "walletUid": "01J9Z3K5X8QW2R4T6V8Y0B1C3D",
  "amountMinor": 1,
  "currency": "ETB",
  "railCode": "string",
  "clientReference": "string"
}

Response · 201

FieldTypeDescription
uidstring
typestringOperation type, e.g. wallet_credit, wallet_debit, payout_b2c or topup_c2b.
statestringOperation state: created, awaiting_authorization, authorized, held, processing, pending_provider, confirmed, failed, reversed or completed.
amountMinornumberInteger minor units (e.g. 250000 = ETB 2,500.00).
feeMinornumberMinor units.
taxMinornumberMinor units.
currencystringISO-4217.
clientReferencestring | nullYour reference, exactly as you supplied it.
createdAtstring
completedAtstring | nullWhen the operation first reached a final state.
linksobject
links.selfstringAPI-relative path of this operation (GET /tenant/operations/{uid}).
links.receiptstringAPI-relative path of its receipt (GET /tenant/operations/{uid}/receipt).
intentReferencestringThe reference the payer quotes to the provider; 12 digits.
expiresAtstringAfter this instant a payment against the reference is not matched.
railCodestringThe payment provider's code the intent was issued on.
payerInstructionsstring | nullWhat to tell the payer, verbatim from the payment provider's configuration; null when there is none.
Example (generated from the schema)
json
{
  "uid": "01J9Z3K5X8QW2R4T6V8Y0B1C3D",
  "type": "string",
  "state": "string",
  "amountMinor": 0,
  "feeMinor": 0,
  "taxMinor": 0,
  "currency": "ETB",
  "clientReference": "string",
  "createdAt": "2026-09-03T10:15:30.000Z",
  "completedAt": "2026-09-03T10:15:30.000Z",
  "links": {
    "self": "string",
    "receipt": "string"
  },
  "intentReference": "048213775902",
  "expiresAt": "2026-09-03T10:15:30.000Z",
  "railCode": "string",
  "payerInstructions": "string"
}

Errors

400 401 403 404 409 422 429 500 503 — one body shape for all of them, see Errors.

Get one top-up intent's status and state timeline

GET/api/v1/tenant/topup-intents/{uid}

Scope operations:read

The operation detail of GET /tenant/operations/{uid} for a topup_c2b operation, plus its intentReference and expiresAt.

Path parameters

NameTypeRequiredDescription
uidstringyes

Response · 200

FieldTypeDescription
uidstring
typestringOperation type, e.g. wallet_credit, wallet_debit, payout_b2c or topup_c2b.
statestringOperation state: created, awaiting_authorization, authorized, held, processing, pending_provider, confirmed, failed, reversed or completed.
amountMinornumberInteger minor units (e.g. 250000 = ETB 2,500.00).
feeMinornumberMinor units.
taxMinornumberMinor units.
currencystringISO-4217.
clientReferencestring | nullYour reference, exactly as you supplied it.
createdAtstring
completedAtstring | nullWhen the operation first reached a final state.
linksobject
links.selfstringAPI-relative path of this operation (GET /tenant/operations/{uid}).
links.receiptstringAPI-relative path of its receipt (GET /tenant/operations/{uid}/receipt).
timelineobject[]State transitions of the operation, in sequenceNo order.
timeline[].sequenceNonumber0 for the creation event, then monotonically increasing.
timeline[].fromStatestring | nullState the operation moved from; null on the creation event.
timeline[].toStatestring | nullState the operation moved to.
timeline[].occurredAtstring
timeline[].actorTypeenum | nullKind of actor that drove the transition; the actor's identity is never included. One of api_client, admin, system, provider, customer.
providerobject | nullPayment provider status of a top-up or payout; null for operations that involve no payment provider.
provider.statestringStatus at the payment provider: created, initiated, pending, confirmed, failed, reversed, uncertain or reconciled.
provider.referencestring | nullThe provider's own reference, when known.
provider.lastUpdatedAtstringLast provider-side change Neo Wallet recorded.
intentReferencestringThe reference the payer quotes to the provider; 12 digits.
expiresAtstringAfter this instant a payment against the reference is not matched.
Example (generated from the schema)
json
{
  "uid": "01J9Z3K5X8QW2R4T6V8Y0B1C3D",
  "type": "string",
  "state": "string",
  "amountMinor": 0,
  "feeMinor": 0,
  "taxMinor": 0,
  "currency": "ETB",
  "clientReference": "string",
  "createdAt": "2026-09-03T10:15:30.000Z",
  "completedAt": "2026-09-03T10:15:30.000Z",
  "links": {
    "self": "string",
    "receipt": "string"
  },
  "timeline": [
    {
      "sequenceNo": 0,
      "fromState": "string",
      "toState": "string",
      "occurredAt": "2026-09-03T10:15:30.000Z",
      "actorType": "api_client"
    }
  ],
  "provider": {
    "state": "string",
    "reference": "string",
    "lastUpdatedAt": "2026-09-03T10:15:30.000Z"
  },
  "intentReference": "string",
  "expiresAt": "2026-09-03T10:15:30.000Z"
}

Errors

400 401 403 404 429 500 503 — one body shape for all of them, see Errors.