Wallet API Integration Guide

Panduan Integrasi Wallet API

Use this guide to connect an operator to the backend using either a backend-managed transfer wallet or an operator-managed seamless wallet.

Gunakan panduan ini untuk menghubungkan operator ke backend dengan transfer wallet yang dikelola backend atau seamless wallet yang dikelola operator.

Overview

Gambaran Umum

The wallet API authenticates an operator, resolves its stored wallet type, validates the player and currency, and records financial activity in a provider-neutral ledger.

Wallet API mengautentikasi operator, membaca tipe wallet yang tersimpan, memvalidasi pemain dan mata uang, lalu mencatat aktivitas finansial pada ledger yang netral terhadap provider.

Transfer wallet is used when this backend owns the playable balance. Use deposit and withdraw to move funds, and use balance, rollback, and transaction history for operations and audit.

Transfer wallet digunakan ketika backend ini menjadi pemilik saldo bermain. Gunakan deposit dan withdraw untuk memindahkan dana, serta balance, rollback, dan riwayat transaksi untuk operasi dan audit.

Seamless wallet is used when the operator keeps the authoritative balance. The backend sends signed requests to the operator's wallet service for balance, debit, credit, rollback, and transaction-status checks.

Seamless wallet digunakan ketika operator tetap menjadi pemilik saldo utama. Backend mengirim request bertanda tangan ke layanan wallet operator untuk balance, debit, credit, rollback, dan pemeriksaan status transaksi.

Authentication

Autentikasi

All public /api/v1/wallet/* routes require the active operator API token as a bearer token. POST requests also require JSON content type.

Semua route publik /api/v1/wallet/* memerlukan API token operator aktif sebagai bearer token. Request POST juga wajib menggunakan content type JSON.

If the operator has an IP allowlist, the request must come from one of those exact IP addresses. Proxy headers are trusted only when the backend is configured with trusted proxy CIDRs.

Jika operator memiliki daftar IP yang diizinkan, request harus berasal dari salah satu IP tersebut. Header proxy hanya dipercaya jika backend dikonfigurasi dengan CIDR proxy tepercaya.

Public wallet requests are not HMAC-signed. HMAC signing applies only to outbound seamless wallet callbacks.

Request wallet publik tidak menggunakan HMAC. HMAC hanya digunakan untuk callback seamless wallet yang dikirim keluar oleh backend.

Required public API headersHeader wajib API publik
Authorization: Bearer <operator_api_token>
Content-Type: application/json
X-Request-ID: request-unique-id

X-Request-ID is optional. When omitted or invalid, the backend creates one and returns it in the response header.

X-Request-ID bersifat opsional. Jika tidak dikirim atau tidak valid, backend akan membuatnya dan mengembalikannya pada header respons.

Common Response Format

Format Respons Umum

Every application outcome uses HTTP 200 OK. Always check the JSON status and code. Success contains data only; failure contains error only.

Semua hasil aplikasi menggunakan HTTP 200 OK. Selalu periksa status dan code pada JSON. Respons sukses hanya memiliki data; respons gagal hanya memiliki error.

SuccessSukses
{
  "status": true,
  "code": "SUCCESS",
  "data": {}
}
Error
{
  "status": false,
  "code": "VALIDATION_ERROR",
  "error": {}
}

Decimal Money Rules

Aturan Nominal Desimal

Money is decimal 1:1 with a maximum of two decimal places. Do not convert to cents, sen, or other minor units. Amounts must be greater than zero and no greater than 1000000000000.00.

Nominal uang menggunakan desimal 1:1 dengan maksimal dua angka di belakang koma. Jangan mengubah nominal menjadi cents, sen, atau minor unit lainnya. Amount harus lebih besar dari nol dan tidak lebih dari 1000000000000.00.

  • IDR 100000.00 is sent as "100000.00".
  • USD 1.00 is sent as "1.00".
  • "1.001", zero, and negative values are rejected.
  • IDR 100000.00 dikirim sebagai "100000.00".
  • USD 1.00 dikirim sebagai "1.00".
  • "1.001", nol, dan nilai negatif akan ditolak.

The current API serializes decimal response fields as JSON strings and may omit trailing zeros, for example "100000". Treat that value as the same decimal amount as 100000.00.

API saat ini menulis field desimal pada respons sebagai string JSON dan dapat menghilangkan nol di belakang, misalnya "100000". Nilai tersebut tetap sama dengan desimal 100000.00.

Idempotency

reference_id is the idempotency key for debit, deposit, and withdraw. rollback_reference_id is the idempotency key for rollback. Keys are unique per operator.

reference_id adalah idempotency key untuk debit, deposit, dan withdraw. rollback_reference_id adalah idempotency key untuk rollback. Key harus unik per operator.

For seamless callbacks, request_id is a per-call correlation UUID generated by the backend. It can change between calls and must not be used as the financial idempotency key. Deduplicate mutations by reference_id.

Pada callback seamless, request_id adalah UUID korelasi per pemanggilan yang dibuat oleh backend. Nilainya dapat berubah antar pemanggilan dan tidak boleh digunakan sebagai idempotency key finansial. Deduplicate mutasi berdasarkan reference_id.

  • Retry the same financial intent with the same reference and identical fields.
  • An identical completed duplicate returns the original successful result without changing the balance again.
  • Reusing a reference with different user, amount, currency, or operation returns IDEMPOTENCY_CONFLICT.
  • After TRANSACTION_STATUS_UNKNOWN, never create a new reference for the same intent.
  • Ulangi transaksi yang sama dengan reference dan field yang sama.
  • Duplikat identik yang sudah selesai mengembalikan hasil awal tanpa mengubah saldo lagi.
  • Penggunaan ulang reference dengan user, amount, currency, atau operasi berbeda menghasilkan IDEMPOTENCY_CONFLICT.
  • Setelah TRANSACTION_STATUS_UNKNOWN, jangan membuat reference baru untuk transaksi yang sama.

Transfer Wallet

Transfer mode stores the authoritative playable balance in this backend. A common integration flow is: check balance, deposit funds, withdraw funds when required, and use rollback only to reverse one completed transaction.

Mode transfer menyimpan saldo bermain utama di backend ini. Alur integrasi umumnya: periksa saldo, lakukan deposit, lakukan withdraw bila diperlukan, dan gunakan rollback hanya untuk membalik satu transaksi yang sudah selesai.

https://api-nlc.ohmybet.online/api/v1

Replace the example host with the base URL assigned to your environment.

Ganti host contoh dengan base URL yang diberikan untuk environment Anda.

Balance

Returns the current local balance for an active transfer-wallet player. This endpoint does not create a ledger transaction.

Mengembalikan saldo lokal saat ini untuk pemain transfer wallet yang aktif. Endpoint ini tidak membuat transaksi ledger.

GET/api/v1/wallet/balance

Headers: Authorization: Bearer <operator_api_token>

Request body: None. Send the fields as query parameters.

Body request: Tidak ada. Kirim field sebagai query parameter.

Query fields

Field query

Field             Type    Requirement  Description                         Example
external_user_id  string  Required     Player ID owned by the operator.    player-1001
currency          string  Required     Exact uppercase 3-letter currency.  IDR
Field             Tipe    Kebutuhan  Deskripsi                            Contoh
external_user_id  string  Wajib      ID pemain milik operator.            player-1001
currency          string  Wajib      Mata uang 3 huruf kapital persis.    IDR

Notes: Currency must match the player currency. Unknown users return USER_NOT_FOUND.

Catatan: Currency harus sama dengan currency pemain. User yang tidak ditemukan menghasilkan USER_NOT_FOUND.

RequestRequest
GET /api/v1/wallet/balance?external_user_id=player-1001&currency=IDR
Authorization: Bearer <operator_api_token>
Success responseRespons sukses
{
  "status": true,
  "code": "SUCCESS",
  "data": {
    "balance_amount": "100000",
    "currency": "IDR",
    "timestamp": "2026-06-12T00:00:00Z"
  }
}
Error responseRespons error
{
  "status": false,
  "code": "CURRENCY_MISMATCH",
  "error": {}
}

Deposit

Credits the transfer-wallet player's local balance and writes one completed ledger row.

Menambah saldo lokal pemain transfer wallet dan menulis satu row ledger berstatus completed.

POST/api/v1/wallet/deposit

Headers: Authorization: Bearer <operator_api_token>, Content-Type: application/json

Request fields

Field request

Field             Type     Requirement  Description                              Example
operator_id       string   Required     Must equal the authenticated operator.   7fe0...2b1
external_user_id  string   Required     Active player external ID.               player-1001
reference_id      string   Required     Unique idempotency key per operator.      deposit-0001
amount            decimal  Required     Positive, max 2 decimals.                100000.00
currency          string   Required     Exact player currency.                   IDR
Field             Tipe     Kebutuhan  Deskripsi                                  Contoh
operator_id       string   Wajib      Harus sama dengan operator terautentikasi. 7fe0...2b1
external_user_id  string   Wajib      External ID pemain aktif.                  player-1001
reference_id      string   Wajib      Idempotency key unik per operator.         deposit-0001
amount            decimal  Wajib      Positif, maksimal 2 desimal.               100000.00
currency          string   Wajib      Harus sama dengan currency pemain.         IDR

Notes: Unknown JSON fields are rejected. A different operator_id returns FORBIDDEN.

Catatan: Field JSON yang tidak dikenal akan ditolak. operator_id yang berbeda menghasilkan FORBIDDEN.

Request bodyBody request
{
  "operator_id": "7fe0c978-3eb2-4e19-bc69-e2cdb74a12b1",
  "external_user_id": "player-1001",
  "reference_id": "deposit-0001",
  "amount": "100000.00",
  "currency": "IDR"
}
Success responseRespons sukses
{
  "status": true,
  "code": "SUCCESS",
  "data": {
    "id": "c2ea59c1-d143-46d1-bff4-6e302038849b",
    "operator_id": "7fe0c978-3eb2-4e19-bc69-e2cdb74a12b1",
    "user_id": "2ff15b51-a20a-4694-a01a-f1ad77ec34d7",
    "external_user_id": "player-1001",
    "wallet_type": "transfer",
    "type": "credit",
    "amount": "100000",
    "currency": "IDR",
    "balance_before": "0",
    "balance_after": "100000",
    "reference_id": "deposit-0001",
    "status": "completed",
    "failure_code": null,
    "metadata": {},
    "created_at": "2026-06-12T00:00:00Z",
    "completed_at": "2026-06-12T00:00:00Z"
  }
}
Error responseRespons error
{
  "status": false,
  "code": "IDEMPOTENCY_CONFLICT",
  "error": {}
}

Withdraw

Debits the transfer-wallet player's local balance. The operation fails without changing the balance when funds are insufficient.

Mengurangi saldo lokal pemain transfer wallet. Operasi gagal tanpa mengubah saldo jika saldo tidak mencukupi.

POST/api/v1/wallet/withdraw

Headers: Authorization: Bearer <operator_api_token>, Content-Type: application/json

Request fields

Field request

Field             Type     Requirement  Description                              Example
operator_id       string   Required     Must equal the authenticated operator.   7fe0...2b1
external_user_id  string   Required     Active player external ID.               player-1001
reference_id      string   Required     Unique idempotency key per operator.      withdraw-0001
amount            decimal  Required     Positive, max 2 decimals.                25000.00
currency          string   Required     Exact player currency.                   IDR
Field             Tipe     Kebutuhan  Deskripsi                                  Contoh
operator_id       string   Wajib      Harus sama dengan operator terautentikasi. 7fe0...2b1
external_user_id  string   Wajib      External ID pemain aktif.                  player-1001
reference_id      string   Wajib      Idempotency key unik per operator.         withdraw-0001
amount            decimal  Wajib      Positif, maksimal 2 desimal.               25000.00
currency          string   Wajib      Harus sama dengan currency pemain.         IDR

Notes: An insufficient attempt is recorded as a failed debit and returns INSUFFICIENT_BALANCE.

Catatan: Percobaan dengan saldo tidak cukup dicatat sebagai debit gagal dan menghasilkan INSUFFICIENT_BALANCE.

Request bodyBody request
{
  "operator_id": "7fe0c978-3eb2-4e19-bc69-e2cdb74a12b1",
  "external_user_id": "player-1001",
  "reference_id": "withdraw-0001",
  "amount": "25000.00",
  "currency": "IDR"
}
Success responseRespons sukses
{
  "status": true,
  "code": "SUCCESS",
  "data": {
    "id": "52406740-b02d-4ffc-955f-598cc7f013d7",
    "operator_id": "7fe0c978-3eb2-4e19-bc69-e2cdb74a12b1",
    "user_id": "2ff15b51-a20a-4694-a01a-f1ad77ec34d7",
    "external_user_id": "player-1001",
    "wallet_type": "transfer",
    "type": "debit",
    "amount": "25000",
    "currency": "IDR",
    "balance_before": "100000",
    "balance_after": "75000",
    "reference_id": "withdraw-0001",
    "status": "completed",
    "failure_code": null,
    "metadata": {},
    "created_at": "2026-06-12T00:01:00Z",
    "completed_at": "2026-06-12T00:01:00Z"
  }
}
Error responseRespons error
{
  "status": false,
  "code": "INSUFFICIENT_BALANCE",
  "error": {}
}

Rollback

Reverses one completed credit or debit. The amount and currency are loaded from the original ledger row and must not be sent by the client.

Membalik satu credit atau debit yang sudah completed. Amount dan currency dibaca dari ledger transaksi awal dan tidak boleh dikirim oleh client.

POST/api/v1/wallet/rollback

Headers: Authorization: Bearer <operator_api_token>, Content-Type: application/json

Request fields

Field request

Field                  Type    Requirement  Description                              Example
external_user_id       string  Required     Owner of the original transaction.       player-1001
original_reference_id  string  Required     Reference of completed credit/debit.     withdraw-0001
rollback_reference_id  string  Required     Unique idempotency key for rollback.     rollback-0001
Field                  Tipe    Kebutuhan  Deskripsi                                 Contoh
external_user_id       string  Wajib      Pemilik transaksi awal.                  player-1001
original_reference_id  string  Wajib      Reference credit/debit yang completed.   withdraw-0001
rollback_reference_id  string  Wajib      Idempotency key unik untuk rollback.     rollback-0001

Notes: Only one rollback is allowed per original transaction. A completed rollback marks the original transaction as reversed.

Catatan: Hanya satu rollback diperbolehkan untuk setiap transaksi awal. Rollback yang selesai mengubah status transaksi awal menjadi reversed.

Request bodyBody request
{
  "external_user_id": "player-1001",
  "original_reference_id": "withdraw-0001",
  "rollback_reference_id": "rollback-0001"
}
Success responseRespons sukses
{
  "status": true,
  "code": "SUCCESS",
  "data": {
    "transaction_id": "bbd69c4f-7bc6-46d2-b6ce-3bdbf927d75a",
    "balance_after": "99000",
    "currency": "IDR",
    "timestamp": "2026-06-12T00:03:00Z"
  }
}
Error responseRespons error
{
  "status": false,
  "code": "TRANSACTION_ALREADY_ROLLED_BACK",
  "error": {}
}

Transactions

Returns ledger rows owned by the authenticated operator. Results are ordered newest first.

Mengembalikan row ledger milik operator terautentikasi. Hasil diurutkan dari yang terbaru.

GET/api/v1/wallet/transactions

Headers: Authorization: Bearer <operator_api_token>

Request body: None. All filters are query parameters.

Body request: Tidak ada. Semua filter dikirim sebagai query parameter.

Query fields

Field query

Field             Type     Requirement  Description                                      Example
external_user_id  string   Optional     Filter by player external ID.                    player-1001
type              string   Optional     credit, debit, or rollback.                      debit
status            string   Optional     pending, completed, failed, reversed, mismatch.  completed
reference_id      string   Optional     Exact reference filter.                          withdraw-0001
limit             integer  Optional     Default 20; minimum 1; maximum 100.               20
offset            integer  Optional     Default 0; range 0 through 10000.                 0
Field             Tipe     Kebutuhan  Deskripsi                                         Contoh
external_user_id  string   Opsional   Filter berdasarkan external ID pemain.            player-1001
type              string   Opsional   credit, debit, atau rollback.                     debit
status            string   Opsional   pending, completed, failed, reversed, mismatch.   completed
reference_id      string   Opsional   Filter reference persis.                          withdraw-0001
limit             integer  Opsional   Default 20; minimum 1; maksimum 100.               20
offset            integer  Opsional   Default 0; rentang 0 sampai 10000.                 0

Notes: This is ledger history, not a single-purpose transaction-status endpoint.

Catatan: Endpoint ini adalah riwayat ledger, bukan endpoint khusus status satu transaksi.

RequestRequest
GET /api/v1/wallet/transactions?external_user_id=player-1001&limit=20&offset=0
Authorization: Bearer <operator_api_token>
Success responseRespons sukses
{
  "status": true,
  "code": "SUCCESS",
  "data": {
    "items": [
      {
        "id": "52406740-b02d-4ffc-955f-598cc7f013d7",
        "operator_id": "7fe0c978-3eb2-4e19-bc69-e2cdb74a12b1",
        "user_id": "2ff15b51-a20a-4694-a01a-f1ad77ec34d7",
        "external_user_id": "player-1001",
        "wallet_type": "transfer",
        "type": "debit",
        "amount": "25000",
        "currency": "IDR",
        "balance_before": "100000",
        "balance_after": "75000",
        "reference_id": "withdraw-0001",
        "status": "completed",
        "failure_code": null,
        "metadata": {},
        "created_at": "2026-06-12T00:01:00Z",
        "completed_at": "2026-06-12T00:01:00Z"
      }
    ],
    "limit": 20,
    "offset": 0
  }
}
Error responseRespons error
{
  "status": false,
  "code": "INVALID_TRANSACTION_STATUS",
  "error": {}
}

Testing Transfer Wallet

Pengujian Transfer Wallet

  1. Start with a player balance of 0.00.
  2. Deposit 100000.00. Expected balance: 100000.00.
  3. Withdraw 25000.00. Expected balance: 75000.00.
  4. Rollback the withdraw. Expected balance: 100000.00.
  5. Repeat the same request with the same reference. The balance must not change twice.
  1. Mulai dengan saldo pemain 0.00.
  2. Deposit 100000.00. Saldo yang diharapkan: 100000.00.
  3. Withdraw 25000.00. Saldo yang diharapkan: 75000.00.
  4. Rollback withdraw. Saldo yang diharapkan: 100000.00.
  5. Ulangi request yang sama dengan reference yang sama. Saldo tidak boleh berubah dua kali.
curl
BASE_URL="https://api.example.com"
TOKEN="replace-with-operator-token"
OPERATOR_ID="7fe0c978-3eb2-4e19-bc69-e2cdb74a12b1"

curl -sS -X POST "$BASE_URL/api/v1/wallet/deposit" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"operator_id\":\"$OPERATOR_ID\",\"external_user_id\":\"player-1001\",\"reference_id\":\"test-deposit-1\",\"amount\":\"100000.00\",\"currency\":\"IDR\"}"

curl -sS -X POST "$BASE_URL/api/v1/wallet/withdraw" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"operator_id\":\"$OPERATOR_ID\",\"external_user_id\":\"player-1001\",\"reference_id\":\"test-withdraw-1\",\"amount\":\"25000.00\",\"currency\":\"IDR\"}"

curl -sS -X POST "$BASE_URL/api/v1/wallet/rollback" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"external_user_id":"player-1001","original_reference_id":"test-withdraw-1","rollback_reference_id":"test-rollback-1"}'

curl -sS "$BASE_URL/api/v1/wallet/balance?external_user_id=player-1001&currency=IDR" \
  -H "Authorization: Bearer $TOKEN"

Known Error Codes

Kode Error yang Dikenal

The codes below are returned by the public wallet handlers or accepted from the seamless operator wallet service.

Kode berikut dikembalikan oleh handler wallet publik atau diterima dari layanan seamless wallet operator.

Code                                 Meaning
SUCCESS                              Request completed successfully.
VALIDATION_ERROR                     Missing field, invalid JSON, wrong content type, or unknown field.
UNAUTHORIZED                         Bearer token is missing, invalid, expired, revoked, or operator is inactive.
FORBIDDEN                            Client IP or request operator identity is not allowed.
RATE_LIMITED                         Request rate limit was exceeded.
USER_NOT_FOUND                       Player was not found for the authenticated operator.
USER_INACTIVE                        Player status is not active.
INVALID_CURRENCY                     Currency is not exactly three uppercase ASCII letters.
CURRENCY_MISMATCH                    Request currency differs from player or upstream currency.
INVALID_AMOUNT                       Amount is zero, negative, or has more than two decimal places.
AMOUNT_LIMIT_EXCEEDED                Amount is greater than 1000000000000.00.
BALANCE_OVERFLOW                     Balance mutation failed its safety checks.
INSUFFICIENT_BALANCE                 Wallet cannot cover the debit.
WALLET_TYPE_NOT_SUPPORTED            Route cannot run for the authenticated wallet type.
IDEMPOTENCY_CONFLICT                 Reference was reused with different immutable fields.
TRANSACTION_NOT_FOUND                Original transaction or requested transaction does not exist.
TRANSACTION_NOT_ROLLBACKABLE         Original transaction is not completed or cannot be reversed.
TRANSACTION_ALREADY_ROLLED_BACK      Original transaction was already reversed.
INVALID_TRANSACTION_TYPE             Transaction list type filter is invalid.
INVALID_TRANSACTION_STATUS           Transaction list status filter is invalid.
INVALID_PAGINATION                   limit or offset is outside the accepted range.
PROVIDER_UNAVAILABLE                 Seamless wallet provider is unavailable.
UPSTREAM_TIMEOUT                     Seamless balance or status request timed out.
TRANSACTION_STATUS_UNKNOWN           Mutation result is uncertain and requires reconciliation.
UNSUPPORTED_OPERATION                Wallet strategy does not support the requested operation.
INTERNAL_ERROR                       Unexpected internal or configuration failure.
Code                                 Arti
SUCCESS                              Request berhasil.
VALIDATION_ERROR                     Field kurang, JSON invalid, content type salah, atau field tidak dikenal.
UNAUTHORIZED                         Bearer token tidak ada/tidak valid, credential kedaluwarsa/dicabut, atau operator tidak aktif.
FORBIDDEN                            IP client atau identitas operator pada request tidak diizinkan.
RATE_LIMITED                         Batas jumlah request terlampaui.
USER_NOT_FOUND                       Pemain tidak ditemukan untuk operator terautentikasi.
USER_INACTIVE                        Status pemain tidak aktif.
INVALID_CURRENCY                     Currency bukan tiga huruf ASCII kapital.
CURRENCY_MISMATCH                    Currency request berbeda dari pemain atau upstream.
INVALID_AMOUNT                       Amount nol, negatif, atau lebih dari dua desimal.
AMOUNT_LIMIT_EXCEEDED                Amount lebih besar dari 1000000000000.00.
BALANCE_OVERFLOW                     Mutasi saldo gagal pada pemeriksaan keamanan.
INSUFFICIENT_BALANCE                 Saldo tidak cukup untuk debit.
WALLET_TYPE_NOT_SUPPORTED            Route tidak dapat dijalankan untuk tipe wallet operator.
IDEMPOTENCY_CONFLICT                 Reference digunakan ulang dengan field penting yang berbeda.
TRANSACTION_NOT_FOUND                Transaksi awal atau transaksi yang diminta tidak ditemukan.
TRANSACTION_NOT_ROLLBACKABLE         Transaksi awal belum completed atau tidak dapat dibalik.
TRANSACTION_ALREADY_ROLLED_BACK      Transaksi awal sudah dibalik.
INVALID_TRANSACTION_TYPE             Filter type pada daftar transaksi tidak valid.
INVALID_TRANSACTION_STATUS           Filter status pada daftar transaksi tidak valid.
INVALID_PAGINATION                   limit atau offset di luar rentang.
PROVIDER_UNAVAILABLE                 Provider seamless wallet tidak tersedia.
UPSTREAM_TIMEOUT                     Request balance atau status seamless mengalami timeout.
TRANSACTION_STATUS_UNKNOWN           Hasil mutasi belum pasti dan memerlukan rekonsiliasi.
UNSUPPORTED_OPERATION                Strategi wallet tidak mendukung operasi.
INTERNAL_ERROR                       Kegagalan internal atau konfigurasi yang tidak terduga.

Seamless upstream code mapping

Pemetaan kode upstream seamless

The operator wallet may also return DUPLICATE_TRANSACTION (mapped to IDEMPOTENCY_CONFLICT), OPERATOR_SUSPENDED (mapped to provider unavailable), and INVALID_SIGNATURE or INVALID_TIMESTAMP (mapped to INTERNAL_ERROR). A mutation response with INTERNAL_ERROR is treated as an unknown outcome.

Wallet operator juga dapat mengembalikan DUPLICATE_TRANSACTION (dipetakan ke IDEMPOTENCY_CONFLICT), OPERATOR_SUSPENDED (dipetakan ke provider unavailable), serta INVALID_SIGNATURE atau INVALID_TIMESTAMP (dipetakan ke INTERNAL_ERROR). Respons mutasi dengan INTERNAL_ERROR dianggap sebagai hasil belum pasti.