Payin

Reverse (close) a payin by payin token

Changed on

This POST endpoint reverses, or closes, a pay-in transaction for the user and payin token provided. <br> Both the effect and the conditions depend on how the pay-in was funded: <ul><li><b>Temporary bank account (ACH/wire) or issued crypto deposit wallet:</b> reversing <i>closes the deposit account</i> so that it accepts no further deposits. This is permitted even after deposits have already settled — deposits already received are unaffected and remain recorded.</li><li><b>Card authorization:</b> reversing <i>releases the card authorization</i>. This is only permitted while the authorization has <i>not</i> been captured. A captured authorization represents settled funds and cannot be reversed; use the refund flow instead.</li></ul> A pay-in that has already been reversed, or that is in a non-reversible state for its funding type, returns a 400. <br> On success the pay-in transitions to CANCELLED and the updated pay-in object is returned.

post/payin/{user_token}/{payin_token}/reverse

Request

Headers

Idempotency-Keystring

Unique key to prevent duplicate processing

Request body

reasonstring

Optional free-text reason for the reversal, stored for audit purposes

Example request

{
  "reason": "Customer requested cancellation before depositing funds"
}

Response

OK

payin_tokenstring nullable

Token representing the initiated pay-in transaction. Use this for subsequent commit/status calls.

funding_codestring nullable

Funding code for tracking the payment source (e.g. cash deposit reference shown to the user).

client_transfer_idstring

A client defined transfer identifier. This is the unique ID assigned to the transfer on your system. Max 50 characters. A value another payout of yours already carries is rejected with 400 Bad request and Duplicate client id. Existing payout token: payout_<uuid> in error.details. By default a value becomes reusable once the earlier payout is ERROR or EXPIRED (or is a PENDING quote past its expiration); any other status, including CANCELLED, keeps it reserved. Accounts configured for strict uniqueness never allow reuse, whatever the earlier payout's status.

destination_tokenstring

Token representing the destination wallet/account where funds will be deposited.

payment_referencestring nullable

Payment reference identifier from the partner/network.

required_action'CASH_DEPOSIT_AT_STORE' | 'TRANSFER' | 'BANK_AUTHORIZATION' | 'CARD_CAPTURE' | 'NONE'

Additional action required from the user/system to complete the pay-in. NONE means no further action is needed.

instructionsstring

Human-readable instructions for completing the required action.

status'INITIATED' | 'PROCESSING' | 'COMPLETED' | 'ERROR' | 'CANCELLED'

Current status of the pay-in. INITIATED = created and awaiting action; PROCESSING = in flight at partner; COMPLETED = funds settled; ERROR = failed.

requires_commitboolean

Whether a separate commit call is required to finalize the transaction.

source_amountnumber double nullable

Amount in source currency.

destination_amountnumber double nullable

Amount in destination currency (after FX, if applicable).

exchange_ratenumber double nullable

Exchange rate applied between source and destination currencies.

feenumber double nullable

Fee charged for the pay-in, in source currency.

source_currency_codestring nullable

Source currency code (ISO 4217, or asset code for crypto).

destination_currency_codestring nullable

Destination currency code (ISO 4217, or asset code for crypto).

errorstring nullable

Error message when the pay-in fails. Format for partner failures: '<reason> [<action_code>] <network message>'.

error_type'VALIDATION' | 'PARTNER' | 'GENERIC' nullable

Category of the error. VALIDATION = client request issue; PARTNER = upstream partner/network failure; GENERIC = unclassified.

source_tokenstring

Token that represent the rail through which the pay-in will be collected from. I.e. Crypto Deposit, Cash Deposit, Bank Debit, etc. List of available service can be obtained through the catalog pay-ins endpoint

Example response

{
  "payin_token": "payin_ba4275f2-bae1-488d-9d6f-20af1cd83574",
  "funding_code": "CASH-9F2J7L",
  "destination_token": "clnt_wlt_fd407907-4913-4a99-b653-5e868743a692",
  "payment_reference": "REF-2025-04823",
  "instructions": "Commit payin to finalize transaction",
  "source_amount": 100.5,
  "destination_amount": 100.5,
  "fee": 2.99,
  "source_currency_code": "USD",
  "destination_currency_code": "USD",
  "network_response": {
    "action_code": "00",
    "approval_code": "123456",
    "address_verification": "Y",
    "cvv2_result_code": "M",
    "cavv_result_code": "2",
    "ani_result": "MATCH",
    "account_number": "1234567890",
    "routing_number": "021000021",
    "swift_bic": "CSRVUS33XXX",
    "bank_name": "Cross River Bank",
    "bank_address": "885 Teaneck Road, Teaneck, NJ 07666 USA",
    "name_on_account": "Jane Doe",
    "network_id": "VISA",
    "response_reason_code": "00"
  },
  "deposits": [
    {
      "token": "payin_dep_1f7c9a2e-3b41-4c8d-9e5f-8a6b2c4d7e90",
      "deposit_amount": 0.0025,
      "deposit_currency": "BTC",
      "fiat_amount": 100.5,
      "fiat_currency": "USD",
      "metadata": {
        "method": "wire",
        "account": "5500312884",
        "routing": "123456780",
        "name": "MARIA RIVERA",
        "imad": "20260914L1B7761R001532",
        "omad": "20260914FTB2007301846209141412FT01",
        "sender_reference": "8812045371XK",
        "beneficiary_reference": "INV 2026-0914-17",
        "originator_to_beneficiary": [
          "ORDER 48213 ACME WIDGETS"
        ]
      },
      "return_reason_code": "REFUSED_BY_BENEFICIARY",
      "network_return_code": "R23",
      "return_fee": 15
    }
  ],
  "error": "Insufficient funds or limit exceeded [51] Not sufficient funds"
}

Changes