---
title: "Initiate a payin transaction"
method: POST
path: "/payin/{user_token}"
tags: ["Payin"]
---

# Initiate a payin transaction

`POST /payin/{user_token}`

## Request

- Base URL: `https://api.masspay.io/v1.0.0`
- URL: `https://api.masspay.io/v1.0.0/payin/{user_token}`
- Auth: one of:
  - API key in header `Authorization`
  - API key in header `x-api-key`
- TypeScript: <https://skmtc.dev/masspay/apis/masspay-api/docs/payin/:user_token/post.ts> (a function with typed inputs; its response is checked against the schema)

This **POST** endpoint initiates a pay-in transaction from a user to your account.
<br> Use this endpoint to collect funds from users - for example, deposits, payments, or wallet top-ups.
<br> Provide the payer's user_token in the URL path, and include in the request body the source of funds (`source_token`), deposit destination (`destination_token`), and the currency of the pay-in (`source_currency_code`).
<br> The response returns complete details of the pay-in transaction, including status, amounts, partner network response, and any required follow-up action.
<br><br> **Important:** A `201` response indicates the request was accepted and processed. Inspect the response body's `status` and `error` fields to determine the actual outcome. A pay-in may be `INITIATED` (awaiting user action), `PROCESSING` (in flight), `COMPLETED` (funds delivered), or `ERROR` (declined by partner or validation failure).

## Path parameters

- `user_token` string, required

## Headers

- `Idempotency-Key` string

## Request body

- PayinTxn
  - `value_added_services` ValueAddedServices: Optional value-added verification services to run alongside the pay-in. Any field omitted defaults to no action (checks default to SKIP).
    - `cvv` string: Card verification value to validate with the network. Omit to skip CVV validation.
    - `account_updater` boolean: Whether to run Account Updater (VAU/ABU) to refresh stored card details before authorization. Defaults to false (skip) when omitted.
    - `avs` 'SKIP' | 'RUN' | 'RUN_AND_VALIDATE': Controls how a verification check is applied. - `SKIP`: do not run the check. - `RUN`: run the check and return the result, but never decline the transaction based on it. - `RUN_AND_VALIDATE`: run the check and decline the transaction if it does not match.
    - `ani` 'SKIP' | 'RUN' | 'RUN_AND_VALIDATE': Controls how a verification check is applied. - `SKIP`: do not run the check. - `RUN`: run the check and return the result, but never decline the transaction based on it. - `RUN_AND_VALIDATE`: run the check and decline the transaction if it does not match.
    - `three_ds` ThreeDs: 3-D Secure authentication artifacts passed through to the network for authorization and liability shift. Omit the entire object to authorize without 3DS data.
      - `cavv` string, required: Cardholder Authentication Verification Value produced during 3DS authentication.
      - `eci` string, required: Electronic Commerce Indicator returned by the 3DS authentication, indicating the authentication outcome and resulting liability.
      - `ds_transaction_id` string, uuid: Directory Server transaction ID assigned during 3DS authentication. Required by some networks for 3DS 2.x.
  - `client_transfer_id` string: 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.
  - `source_currency_code` string, required: Currency from which the pay-in originates — the currency in which funds are collected ([ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) for fiat, e.g. USD; may include network suffix for crypto, e.g. USDT_ERC20; for cards, this is the currency charged to the payer’s card).
  - `destination_currency_code` string: The currency that will be loaded into your MassPay wallet. In [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) format. It needs to match the currency of the `destination_token`
  - `destination_token` string, uuid: Token representing the destination wallet - where the pay-in funds will be credited, either into the user's wallet or the client's wallet. If none is provided, it will deposit into the client wallet with `destination_currency`. If such wallet does not already exist, it will be auto-created.
  - `source_token` string, uuid, required: 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
  - `attr_set_token` string, uuid: Token that represent the funding account that will be used for the pay-in transaction. Only required for pull transactions. For push transactions, like Cash Deposit or Crypto Deposit, this is an optional field. For Crypto Deposits, if `attr_set_token` is provided, deposits will only be accepted if they originated from the provided wallet address.
  - `source_amount` number, float: The amount to be collected from the `source_token` in `source_currency`. i.e USDT. Must be provided if `destination_amount` is empty
  - `destination_amount` number, float: The amount to be deposited into the `destination_token` in `destination_currency`. i.e USD. Must be provided if `source_amount` is empty
  - `metadata` object: Optional JSON object with attributes that can later be searched to locate this pay-in. Do not include PII as this object is not encrypted. There are two special attributes that can be provided in the metadata field: `batch_identifier` and `batch_name`. Either of those values, would group transactions in the ledger under the same description.
    - `group_id` integer
  - `statement_description` string: Optional descriptive line item that appears on the pay-in statement, providing details about the transaction. This field is intended to help identify the purpose or source of each pay-in by displaying a brief summary or itemized description. Commonly includes information such as transaction type, merchant name, or payin reason. Note: Not all countries and banks support displaying this field.

## Response `201`

Pay-in request accepted. Inspect the body's `status` and `error` fields to determine the actual outcome (approved, processing, awaiting user action, or declined).

- InitiatePayinResp: Response returned when initiating a pay-in transaction.
  - `payin_token` string, nullable: Token representing the initiated pay-in transaction. Use this for subsequent commit/status calls.
  - `funding_code` string, nullable: Funding code for tracking the payment source (e.g. cash deposit reference shown to the user).
  - `client_transfer_id` string: 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_token` string: Token representing the destination wallet/account where funds will be deposited.
  - `payment_reference` string, 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.
  - `instructions` string: 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_commit` boolean: Whether a separate commit call is required to finalize the transaction.
  - `source_amount` number, double, nullable: Amount in source currency.
  - `destination_amount` number, double, nullable: Amount in destination currency (after FX, if applicable).
  - `exchange_rate` number, double, nullable: Exchange rate applied between source and destination currencies.
  - `fee` number, double, nullable: Fee charged for the pay-in, in source currency.
  - `source_currency_code` string, nullable: Source currency code (ISO 4217, or asset code for crypto).
  - `destination_currency_code` string, nullable: Destination currency code (ISO 4217, or asset code for crypto).
  - `network_response` NetworkResponse: Network-level response details from the underlying card/network partner. Fields populated vary by partner and by which value-added checks were requested.
    - `action_code` string: Network action/response code. '00' indicates approval; non-zero values indicate decline or error reasons.
    - `approval_code` string, nullable: Authorization/approval code returned by the network on a successful authorization.
    - `address_verification` string, nullable: AVS result code returned when AVS was set to RUN or RUN_AND_VALIDATE. Typical values include Y (full match), A (address only), Z (postal only), N (no match), U (unavailable).
    - `cvv2_result_code` string, nullable: CVV2 result code returned when a CVV was supplied. Typical values: M (match), N (no match), P (not processed), U (unavailable), S (should be present).
    - `cavv_result_code` string, nullable: CAVV verification result code returned by the network when 3DS authentication data was supplied.
    - `ani_result` 'MATCH' | 'PARTIAL_MATCH' | 'NO_MATCH' | 'NOT_CHECKED' | 'UNAVAILABLE', nullable: Outcome of the Account Name Information match, populated when ANI was set to RUN or RUN_AND_VALIDATE. Absent when ANI was skipped.
    - `account_number` string, nullable: Account number of the bank account created for this transaction.
    - `routing_number` string, nullable: Bank routing number (ABA) of the account created for this transaction.
    - `swift_bic` string, nullable: Bank swift BIC code of the account created for this transaction.
    - `bank_name` string, nullable: Bank name of the account created for this transaction.
    - `bank_address` string, nullable: Bank address of the account created for this transaction.
    - `name_on_account` string, nullable: Name on the bank account created for this transaction.
    - `network_id` string, nullable: Identifier of the card network/partner that processed the transaction.
    - `response_reason_code` string, nullable: Network reason code providing additional detail about the response.
    - `exemption_reason_code` string, nullable: Code indicating any SCA (Strong Customer Authentication) exemption applied to the transaction.
  - `deposits` PayinDeposit[]: Deposits made toward this pay-in. A pay-in may be funded by multiple deposits.
    - `token` string: Token representing the deposit.
    - `external_id` string, nullable: External identifier of the deposit at the partner/network.
    - `status` 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'EXPIRED' | 'RETURNED': Current status of the deposit. PENDING = deposit expected but not yet received; PROCESSING = deposit received and being processed; COMPLETED = deposit settled; FAILED = deposit failed; EXPIRED = deposit window elapsed without receiving funds; RETURNED = settled deposit returned to the sender through the originating network. ACH and wire deposits auto-fund on receipt and move directly to COMPLETED.
    - `deposit_amount` number, double, nullable: Amount deposited, in the deposit currency.
    - `deposit_currency` string, nullable: Currency/asset code of the deposit (ISO 4217, or asset code for crypto).
    - `fiat_amount` number, double, nullable: Equivalent fiat amount of the deposit.
    - `fiat_currency` string, nullable: Fiat currency code of the equivalent amount (ISO 4217).
    - `fee` string: Fee that was applied to the deposit in fiat currency
    - `transaction_reference` string, nullable: Reference for the deposit transaction (e.g. blockchain tx hash or bank reference).
    - `metadata` object, nullable: Details MassPay captured about how the deposit arrived. `method` says which rail delivered it; the other fields are present only when the rail supplied them. For bank deposits (`ach`, `wire`, `rtp`) the sender's account, routing number and name are included. For a `wire` deposit the reference messages carried on the Fedwire are included as well, so the deposit can be reconciled against an invoice or order: the IMAD/OMAD identifiers, the sender's and the beneficiary's reference, the payment purpose, and the originator-to-beneficiary information lines in the order they were sent.
      - `method` string: Rail the deposit arrived on, e.g. `ach`, `wire` or `rtp`.
      - `account` string: Sender's account number as reported by the network.
      - `routing` string: Sender's bank routing number.
      - `name` string: Sender's name as reported by the network.
      - `imad` string: Fedwire Input Message Accountability Data of the wire. Wire deposits only.
      - `omad` string: Fedwire Output Message Accountability Data of the wire. Wire deposits only.
      - `sender_reference` string: Reference assigned by the sending bank. Wire deposits only.
      - `beneficiary_reference` string: Reference the sender addressed to the beneficiary. Wire deposits only.
      - `purpose` string: Payment purpose stated on the wire, when the sender provided one. Wire deposits only.
      - `originator_to_beneficiary` string[]: Originator-to-beneficiary information lines, in the order they appeared on the wire; empty lines are omitted. Wire deposits only.
    - `return_reason_code` string, nullable: Normalized reason the deposit was returned (see `DepositReturnReason` for values). Null unless the deposit status is RETURNED.
    - `network_return_code` string, nullable: Network-specific return code transmitted on the rail the deposit was received on (e.g. ACH `R23`, wire `CUST`), translated from `return_reason_code`. Null unless the deposit status is RETURNED.
    - `return_reason` string, nullable: Free-text reason supplied when the deposit was returned. Null unless the deposit status is RETURNED.
    - `return_fee` number, nullable: Fee charged for returning the deposit; see `fee_payer` for whether it was debited from the destination wallet or withheld from the returned funds. Null unless the deposit status is RETURNED.
    - `fee_payer` 'CLIENT' | 'DEPOSITOR', nullable: Who absorbed the return fee. `CLIENT`: the wallet was debited `fiat_amount` plus the fee and the sender received the full deposit. `DEPOSITOR` (wire deposits only): the fee was withheld from the returned funds. Null unless the deposit status is RETURNED.
    - `returned_at` string, date-time, nullable: Timestamp when the deposit was returned.
    - `created_at` string, date-time: Timestamp when the deposit was created.
    - `completed_at` string, date-time, nullable: Timestamp when the deposit was completed.
    - `updated_at` string, date-time, nullable: Timestamp when the deposit was last updated.
  - `error` string, 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_token` string: 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

## Other responses

- `400`: Bad request.
- `401`: Unauthorized.
- `403`: Forbidden.
- `404`: Not found.
- `405`: Method Not Allowed.
- `500`: Internal server error.
- `504`: Gateway Time-out.

## Changes

- **2026-11-03** `f9fa41b7c45c`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/masspay/apis/masspay-api/changes/payin/:user_token/post.md)

---

[API](https://skmtc.dev/masspay/apis/masspay-api.md) - [All operations](https://skmtc.dev/masspay/apis/masspay-api/llms.txt) - [OpenAPI document](https://skmtc.dev/masspay/apis/masspay-api/revisions/f9fa41b7c45c?raw)
