Skip to content

POST Create Cashier Deposit

Endpoint

POST /cashier/deposit

Command

CreateCashierDeposit

Authorization

Requires SESSION_CUSTOMER.

Description

Creates a deposit transaction for a customer-owned trading account. For an automatic method, Cashier calls the configured payment provider module. For a manual method, it creates a request for review and returns the configured receiving instructions without calling a payment module or crediting the account.

The server validates that login belongs to the authenticated customer and that the account and account group are enabled. It also rechecks Cashier payment method eligibility for the resolved brand/account currency/customer country before creating the transaction. This protects the submit endpoint even if the client did not call GetCashierMethods first.

Customer-level deposit_allowed is a hard gate. If it is 0, the endpoint returns DEPOSIT_NOT_ALLOWED before provider eligibility is checked.

The transaction is persisted in bases/cashier.db before it is exposed in the Cashier runtime cache. A returned created transaction is therefore backed by a completed durable write.

For an automatic method, if the provider returns a redirect URL, the response contains next_action = REDIRECT. Otherwise the client should wait for provider-side completion. If the provider confirms the deposit synchronously, Cashier submits a durable balance operation immediately; the transaction may already be in processing_ledger, credited, or credit_failed when the response is returned. A matching trade visible in memory is not sufficient to finalize the Cashier transaction; the matching result must be confirmed committed in the separate trading database. The Cashier and trading databases do not share one atomic transaction. next_action remains based on whether the provider returned a redirect URL, so clients should use transaction.status to detect this immediate confirmation/ledger path. A manual deposit has status = 9 (manual_review) and next_action = WAIT_MANUAL_REVIEW; a manager must process it before the trading account is credited.

The endpoint does not accept owner_manager_id. The Owner of the created transaction is the manager the customer is assigned to at that moment, and it is returned in the transaction object. Only the manual BackOffice commands let a manager choose it explicitly; see Transaction Ownership.

Request Parameters

Name Type Required Description
login int Yes Customer-owned trading account login
provider string Yes Configured provider route code, 1–64 characters
amount double Yes Deposit amount, must be at least 0.01
currency string Yes Payment currency, 1–8 characters. Currently must match the account group currency
method string No Provider method marker, max 64 characters, for example card or bank_transfer
provider_config_id int No 1 or greater; selects this exact eligible provider config, useful when multiple methods share provider/method values
details object No Manual-method customer fields validated against its form_schema; omitted details are treated as {}. Automatic methods do not consume this field
idempotency_key string No Customer-scoped duplicate detection key, max 128 characters; duplicate requests are rejected rather than replaying the prior response
success_url string No URL passed to provider for successful payment redirects, max 2048 characters
failure_url string No URL passed to provider for failed/cancelled payment redirects, max 2048 characters
comment string No Customer-visible or audit comment, max 512 characters
metadata_json string No Additional metadata JSON string. For manual deposits it must encode a JSON object and is stored inside the transaction snapshot as client_metadata

Request Example

{
  "login": 2000009,
  "provider": "stripe",
  "provider_config_id": 1,
  "method": "card",
  "amount": 250.0,
  "currency": "USD",
  "idempotency_key": "0f9bb0e7-642d-4b70-b458-62e3993c7d2d",
  "success_url": "https://terminal.example.com/cashier/success",
  "failure_url": "https://terminal.example.com/cashier/failure"
}

Manual deposit request example

Select the config returned by GET /cashier/methods?type=deposit using its provider_config_id. provider and method must match that eligible config; details must satisfy its form_schema.

POST /cashier/deposit
Authorization: <CUSTOMER_JWT>
Content-Type: application/json

{
  "login": 2000009,
  "provider": "manual",
  "method": "bank_transfer",
  "provider_config_id": 7,
  "amount": 100.0,
  "currency": "USD",
  "details": {
    "payer_name": "Ada Example",
    "payment_reference": "dep-manual-001"
  },
  "idempotency_key": "dep-manual-001",
  "comment": "Bank deposit"
}

Response Parameters

Name Type Description
transaction object Created/updated Cashier transaction
payment object Provider payment creation result, or manual deposit instructions
next_action string REDIRECT, WAIT_PROVIDER_PAYMENT, or WAIT_MANUAL_REVIEW

transaction

Name Type Description
id int Cashier transaction id
customer_id int Customer id
login int Target trading account login
type int 0 for deposit
provider string Provider code
method string Provider method
provider_config_id int Selected brand-level provider config id
provider_payment_id string External payment id returned by provider
amount double Original payment amount
currency string Payment currency
account_currency string Trading account currency used by Cashier
converted_amount double Amount in account currency
conversion_rate double Conversion rate used by Cashier
status int Cashier transaction status
failure_reason string Failure reason when status is failed
idempotency_key string Request retry key
comment string Comment
metadata_json string Additional metadata string, or for manual deposits a JSON snapshot of the selected config, submitted details, instructions, and optional client metadata
source int 0 for automatic provider flow, 1 for manual flow
approved_by int Approving manager id; 0 before approval
approved_time int64 Approval timestamp; 0 before approval
processed_by int Processing manager id; 0 before processing
processed_time int64 Processing timestamp; 0 before processing
reject_reason string Rejection reason; empty when not rejected
created_time int64 Creation timestamp
updated_time int64 Last update timestamp
attributed_manager_id int Manager the customer was assigned to when the transaction was created
owner_manager_id int Manager assigned as transaction owner

payment

Name Type Description
provider_payment_id string External payment id
redirect_url string URL where the client should redirect the customer
instructions_json string Provider instructions JSON string; for manual deposits, the configured public settings_json object serialized as a string
raw_response_json string Raw provider response JSON string; {} for manual deposits
status int Normalized provider status; 1 in the manual-review response
failure_reason string Provider failure reason; empty for manual deposits

Response Example

{
  "transaction": {
    "id": 15,
    "customer_id": 5,
    "login": 2000009,
    "type": 0,
    "provider": "stripe",
    "method": "card",
    "provider_config_id": 1,
    "provider_payment_id": "pi_123",
    "amount": 250.0,
    "currency": "USD",
    "account_currency": "USD",
    "converted_amount": 250.0,
    "conversion_rate": 1.0,
    "status": 1,
    "failure_reason": "",
    "idempotency_key": "0f9bb0e7-642d-4b70-b458-62e3993c7d2d",
    "comment": "",
    "metadata_json": "{}",
    "source": 0,
    "approved_by": 0,
    "approved_time": 0,
    "processed_by": 0,
    "processed_time": 0,
    "reject_reason": "",
    "created_time": 1779270000,
    "updated_time": 1779270000,
    "attributed_manager_id": 12,
    "owner_manager_id": 12
  },
  "payment": {
    "provider_payment_id": "pi_123",
    "redirect_url": "https://provider.example/pay/pi_123",
    "instructions_json": "{}",
    "raw_response_json": "{}",
    "status": 1,
    "failure_reason": ""
  },
  "next_action": "REDIRECT"
}

Manual deposit response example

With execution_mode = 1, the request creates a manual review transaction and does not call a provider module. The payment instructions are the public settings_json object from the selected config, serialized as a JSON string in payment.instructions_json.

{
  "transaction": {
    "id": 31,
    "customer_id": 5,
    "login": 2000009,
    "type": 0,
    "provider": "manual",
    "method": "bank_transfer",
    "provider_config_id": 7,
    "provider_payment_id": "",
    "amount": 100.0,
    "currency": "USD",
    "account_currency": "USD",
    "converted_amount": 100.0,
    "conversion_rate": 1.0,
    "status": 9,
    "failure_reason": "",
    "idempotency_key": "dep-manual-001",
    "comment": "Bank deposit",
    "metadata_json": "{\"provider_config_id\":7,\"method\":\"bank_transfer\",\"display_name\":\"Bank transfer\",\"details\":{\"payer_name\":\"Ada Example\",\"payment_reference\":\"dep-manual-001\"},\"instructions\":{\"beneficiary\":\"Example Trading Ltd\",\"iban\":\"GB00EXAMPLE00000000000000\",\"bank_name\":\"Example Bank\",\"reference\":\"Use the reference returned with your request\"}}",
    "source": 1,
    "approved_by": 0,
    "approved_time": 0,
    "processed_by": 0,
    "processed_time": 0,
    "reject_reason": "",
    "created_time": 1779270000,
    "updated_time": 1779270000,
    "attributed_manager_id": 12,
    "owner_manager_id": 12
  },
  "payment": {
    "provider_payment_id": "",
    "redirect_url": "",
    "instructions_json": "{\"beneficiary\":\"Example Trading Ltd\",\"iban\":\"GB00EXAMPLE00000000000000\",\"bank_name\":\"Example Bank\",\"reference\":\"Use the reference returned with your request\"}",
    "raw_response_json": "{}",
    "status": 1,
    "failure_reason": ""
  },
  "next_action": "WAIT_MANUAL_REVIEW"
}

Errors

HTTP Error Description
400 INVALID_DATA Request validation failed
400 ACCOUNT_NOT_AVAILABLE Account does not exist or is disabled
400 GROUP_NOT_AVAILABLE Account group does not exist or is disabled
400 CURRENCY_CONVERSION_REQUIRED Requested currency differs from account currency and conversion is not supported yet
400 INVALID_DEPOSIT_DETAILS details does not match the selected manual method's form_schema
400 INVALID_PAYMENT_INSTRUCTIONS Manual method settings_json is unavailable or is not a JSON object
400 INVALID_METADATA Manual-flow metadata_json is not a JSON object
403 DEPOSIT_NOT_ALLOWED Deposits are disabled for this customer
403 PAYMENT_METHOD_NOT_AVAILABLE Provider/method is not eligible for this account/customer
403 PERMISSION_DENIED Account does not belong to the customer
404 CUSTOMER_NOT_FOUND Customer record was not found
409 RET_ERR_DUPLICATE Duplicate idempotency_key for the same customer; the prior transaction is not replayed
5xx RET_ERR_NOSERVICE Payment provider is not loaded or unavailable
5xx RET_TECH_PROBLEM Durable transaction or finance-operation state could not be written; inspect any returned transaction and query by idempotency key before retrying

An automatic provider-call error can be returned after the transaction has already been created; such error responses include transaction. If an error arrives after status 11 (processing_ledger) was durably stored, never retry the request with a new key. Query transaction history using the same idempotency_key; duplicate keys are rejected rather than replaying the original response.