OpenPoly logo
Operator Api

Wallet adapter

Read, update, and validate operator wallet adapter settings.

Wallet adapter

Manage the REST v1 wallet adapter configuration used by Mini App balance reads and wallet mutations.

Paths

GET /api/operator/wallet-adapter
PUT /api/operator/wallet-adapter
POST /api/operator/wallet-adapter/test

Required scopes

  • wallet_adapter:read for GET
  • wallet_adapter:write for PUT and POST /test

GET response

The response is masked. Secrets are never returned.

GET has no query parameters or body; only the bearer header and wallet_adapter:read scope are required.

Fields:

  • balance_adapter_type
  • auth_mode: env_var, encrypted, or none
  • base_url
  • timeout_ms
  • balance_path
  • debit_path
  • credit_path
  • debit_reversal_path
  • has_bearer_token
  • has_signature_secret
  • currency_code
  • updated_at

PUT body

Typical body:

{
  "base_url": "https://wallet.operator.example",
  "bearer_token": "operator-wallet-token",
  "signature_secret": "optional-signing-secret",
  "timeout_ms": 10000,
  "balance_path": "/balance",
  "debit_path": "/debit",
  "credit_path": "/credit",
  "debit_reversal_path": "/debit-reversal"
}

A configured secret may be omitted when updating non-secret fields. Sending a new secret replaces the stored encrypted value.

FieldTypeRequirementValues/default
base_urlstringRequired on first setupMay be omitted on later updates to keep the current URL. HTTPS required except localhost/127.0.0.1.
bearer_tokenstringRequired on first setupMay be omitted later to keep the encrypted credential.
signature_secretstringOptionalEnables request signing. Omit to keep an existing secret; an empty value does not clear it.
timeout_msintegerOptionalDefault 10000; clamped to 1000–30000.
balance_pathstringOptionalDefault /balance. A leading / is added when missing.
debit_pathstringOptionalDefault /debit.
credit_pathstringOptionalDefault /credit.
debit_reversal_pathstringOptionalDefault /debit-reversal.
credit_reversal_pathstringOptionalAccepted by the API, default /credit-reversal; not used by current production trade/redemption flows.

Current dashboard-managed production paths are balance, debit, credit, and debit reversal. The backend config parser also accepts credit_reversal_path for compatibility with the shared direction enum, but the current trade/redemption processor does not call credit reversal in production flows and the masked GET response does not expose that field.

The current API supports REST v1 only for IDR operators. Unsupported currency returns 400 REST_V1_UNSUPPORTED_CURRENCY.

Test body

Common and mode-specific fields:

FieldTypeRequirementValues/default
external_user_idstringRequiredDedicated operator-side test user.
modestringOptionalconnection (default) or full_contract.
amount_minorpositive integerRequired for full_contractSmall real mutation amount in operator currency minor units.
confirmationbooleanRequired for full_contractMust be exactly true.
Adapter config fieldsmixedOptionalMay temporarily override or complete the saved config for this test. The resulting config must contain base_url and a bearer token.
productstringOptionalopinion (default) or polyflight for a Polyflight full-contract drill.
dedicated_test_user_confirmationbooleanRequired for Polyflight full_contractMust be exactly true; confirms the external user is isolated test infrastructure.
scenariostringOptional for Polyflightnormal, debit_applied_then_timeout, credit_applied_then_timeout, definite_rejection, duplicate_same, or duplicate_conflict.

Connection test:

{
  "mode": "connection",
  "external_user_id": "operator-user-123",
  "base_url": "https://wallet.operator.example",
  "bearer_token": "operator-wallet-token"
}

Full contract test:

{
  "mode": "full_contract",
  "external_user_id": "operator-user-123",
  "amount_minor": 1000,
  "confirmation": true
}

Polyflight full-contract drill:

{
  "mode": "full_contract",
  "product": "polyflight",
  "external_user_id": "dedicated-polyflight-test-user",
  "amount_minor": 1000,
  "confirmation": true,
  "dedicated_test_user_confirmation": true,
  "scenario": "debit_applied_then_timeout"
}

Polyflight test amounts must be a 1,000-IDR step and no more than 10,000 IDR. These drills use production Polyflight reasons, keys, and metadata plus dedicated-test context; the normal sequence also uses a test-only cleanup debit. Use only dedicated staging/test wallet infrastructure. The API is not a simulator-only endpoint: submitted configuration overrides can direct real HTTP mutations, and the safety confirmation is not an environment lock.

The full contract test performs real wallet mutations against the configured or submitted adapter config. Use a dedicated test user and a small amount.

The Opinion full-contract sequence is: balance, debit, debit reversal, credit, second debit, final balance. A successful sequence must return to its initial balance; a mismatch requires manual review.

All mutation test requests include external_user_id, amount_minor, currency_code, idempotency_key, reason, and metadata. They do not include direction; the path selected for the step is the direction.

Polyflight scenario behavior

The receiving test wallet must implement the requested fault. Merely selecting a scenario does not make an arbitrary operator wallet reject or time out.

ScenarioExpected behavior
normalPurchase debit and compensation; separate setup debit and full refund; win credit and test cleanup debit; zero-amount loss credit and its identical duplicate; final balance equals initial balance.
duplicate_sameRepeat the purchase key/payload successfully without a second debit, compensate, then verify final balance.
duplicate_conflictRepeat the purchase key with a different amount and expect HTTP 409, compensate the original debit, then verify final balance.
definite_rejectionExpect HTTP 422; no automatic compensation/final-balance sequence.
debit_applied_then_timeoutExpect HTTP 504 after debit; manual review, no blind compensation or final-balance check.
credit_applied_then_timeoutExpect HTTP 504 after win credit; manual review, no cleanup or final-balance check.

Polyflight test mutations include top-level dedicated_test_user_confirmation: true, in addition to metadata test context. Generated purchase/ticket IDs are contract-test correlations, not admitted product records. A simulator-only result does not certify the real HTTP wallet contract.

Non-null mutation receipt echoes of external_user_id, idempotency_key, amount_minor, and currency_code must match the request; identity conflicts fail the step. Production processing treats conflicting receipts as unknown. Inspect actual steps and ledger evidence even if a test result is labelled failed rather than unknown; that label alone does not prove a wallet write never happened.

Test response

{
  "mode": "connection",
  "success": true,
  "requires_manual_review": false,
  "steps": [
    {
      "step": "balance",
      "method": "GET",
      "path": "/balance",
      "status": "success",
      "latency_ms": 42,
      "remote_status": "succeeded",
      "external_user_id": "operator-user-123"
    }
  ]
}

Step status can be success, failed, or unknown.

requires_manual_review = true means a mutation or compensation step reached a state that needs operator follow-up before the test user should be reused.

Full-contract responses additionally include product, scenario, test_run_id, nullable contract_expectation_met, and Polyflight safeguards. A deliberate fault can return success: true / contract_expectation_met: true together with requires_manual_review: true: the expected fault was observed, but the applied wallet effect still needs reconciliation. Do not reuse that user or repeat the whole test to “clear” it.

In the dashboard, Wallet Settings saves configuration, Integration UAT exposes saved-config connection checks, and API Playground → Wallet Adapter exposes the test API where a confirmed full-contract body can be submitted.

Copyright © 2026