Argentina: QR and bank transfer

Accept ARS with an interoperable QR or a bank transfer to a CVU, and pay out to a CBU, CVU or alias, through the Direct API.

Accept payments in Argentina in ARS over the country's instant, 24/7 BCRA-regulated rails, with no card chargebacks. Two pay-in methods and one payout rail run through the same /process/ endpoint as the rest of the Direct API:

CapabilityMethodpayment_method.typeBest for
Pay-inQR payment (interoperable QR, Transferencias 3.0)qrWallet and bank-app users — Mercado Pago, Ualá, MODO and bank apps. Small, frequent deposits, confirmed in seconds.
Pay-inBank transfer to a CVUtransferBank users and larger amounts. Each customer gets a fixed CVU and alias.
PayoutTransfer to CBU, CVU or aliasoperation_type: "withdrawal"Cash-outs to your end users, from a pre-funded balance.

Every wallet scans the same interoperable QR: there is no per-wallet or per-bank parameter.

Before you start

  • Your Tonder business is set to country Argentina and currency ARS.
  • The methods you'll use are enabled for your business. A method that isn't enabled returns 403 payment_method_not_enabled.
  • Requests use the Direct API base URLs and headers — Authorization: Token YOUR_API_KEY, Content-Type: application/json and a UUID v4 in X-Request-Id. See Authentication.

Request rules

FieldRule
currency"ARS", matching your business currency. If you omit it, it defaults to "MXN" and the request is rejected with 400 currency_mismatch.
countryOptional. "AR" sets the currency to "ARS".
amountDecimal with a dot and at most 2 decimals. More precision returns 400 invalid_amount_precision.
customer.name, customer.emailRequired.
customer.tax_idOptional, recommended: the customer's CUIT/CUIL, 11 digits without dashes.
client_referenceYour order reference, used to correlate webhooks. Required for transfer and recommended for qr.
payment_method.apm_config.expires_inSeconds until the QR or the transfer details expire. Default 1800 (30 minutes).

expires_in goes inside payment_method.apm_config. Sent directly on payment_method, it is ignored without an error and the default applies.

QR payment

Create the payment with payment_method.type: "qr":

curl -X POST https://stage.tonder.io/api/v1/process/ \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Request-Id: 550e8400-e29b-41d4-a716-446655440000" \
  -d '{
    "operation_type": "payment",
    "amount": 15000.00,
    "currency": "ARS",
    "customer": { "name": "Juan Pérez", "email": "juan.perez@email.com", "tax_id": "20123456789" },
    "payment_method": { "type": "qr", "apm_config": { "expires_in": 1800 } },
    "client_reference": "ORD-001",
    "metadata": { "external_id": "ORD-001" }
  }'
curl -X POST https://app.tonder.io/api/v1/process/ \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Request-Id: 550e8400-e29b-41d4-a716-446655440000" \
  -d '{
    "operation_type": "payment",
    "amount": 15000.00,
    "currency": "ARS",
    "customer": { "name": "Juan Pérez", "email": "juan.perez@email.com", "tax_id": "20123456789" },
    "payment_method": { "type": "qr", "apm_config": { "expires_in": 1800 } },
    "client_reference": "ORD-001",
    "metadata": { "external_id": "ORD-001" }
  }'

The response is 201 with status: "Pending" and the QR in next_action.display_qr_code:

{
  "id": "6f1c2c0e-2b7a-4a6e-9c2d-0a4c3b9f1e21",
  "status": "Pending",
  "amount": 15000.00,
  "currency": "ARS",
  "payment_method_type": "qr",
  "client_reference": "ORD-001",
  "created_at": "2026-10-26T18:02:11.120Z",
  "next_action": {
    "display_qr_code": {
      "qr_string": "000201010212...6304ABCD",
      "amount": 15000.00,
      "currency": "ARS",
      "expires_at": "2026-10-26T18:32:11Z",
      "verify_transaction_status_url": "/transactions/6f1c2c0e-2b7a-4a6e-9c2d-0a4c3b9f1e21/"
    }
  }
}
  • qr_string is the EMVCo payload: render it as a QR with any QR library.
  • Show the QR and its expiry. After expires_at the payment becomes Expired.
  • While the payment is Pending, GET /api/v1/transactions/{id}/ returns the same next_action, so you can render the QR again.

Bank transfer (CVU)

Send the same request with payment_method.type: "transfer". client_reference is required and can't be empty. The response is 201 with status: "Pending" and the transfer details in next_action.display_bank_transfer:

{
  "id": "1c9e6a42-7d3b-4f0e-8a51-2b6d9c0e7f13",
  "status": "Pending",
  "amount": 250000.00,
  "currency": "ARS",
  "payment_method_type": "transfer",
  "client_reference": "ORD-001",
  "created_at": "2026-10-26T18:02:11.120Z",
  "next_action": {
    "display_bank_transfer": {
      "account_type": "CVU",
      "account_number": "0000000000000000000000",
      "alias": "CLIENTE.JUAN.4411",
      "holder_name": "ACCOUNT HOLDER NAME",
      "holder_tax_id": "30-00000000-0",
      "amount": 250000.00,
      "currency": "ARS",
      "reference": "ORD-001",
      "expires_at": "2026-10-26T18:32:11Z",
      "verify_transaction_status_url": "/transactions/1c9e6a42-7d3b-4f0e-8a51-2b6d9c0e7f13/"
    }
  }
}
  • Show the CVU and the alias with a copy button, and holder_name as the recipient.
  • The CVU and alias are fixed per customer: the same customer.email always gets the same account.
  • reference is informational. In Argentina the transfer's description isn't reliable, so Tonder attributes a deposit by the account (the customer) and the pending payment, not by reference.
  • If the amount received differs from the one expected, the payment still settles as Success with the received amount, and metadata gains mismatched_deposit: "True" and original_expected_amount.

Refunds

MethodRefundHow
QR payment (qr)In full, oncePOST /api/v1/process/ with operation_type: "refund", the same amount as the original, currency: "ARS" and original_transaction_id. The original must be Success; a different amount returns 400 partial_refund_not_supported.
Bank transfer (transfer)Not through the APIReturns 400 refund_not_supported_for_method. Ask support to return the funds.

The request and response follow Refunds.

Payouts to CBU, CVU or alias

Send a withdrawal through the same endpoint with transfer_method: "BANK_TRANSFER":

curl -X POST https://stage.tonder.io/api/v1/process/ \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Request-Id: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \
  -d '{
    "operation_type": "withdrawal",
    "amount": 80000.00,
    "currency": "ARS",
    "transfer_method": "BANK_TRANSFER",
    "description": "Balance withdrawal",
    "client_reference": "payout-001",
    "beneficiary": {
      "account_type": "CBU",
      "account": "0000000000000000000000",
      "name": "María López",
      "tax_id": "27234567891",
      "email": "maria.lopez@email.com"
    },
    "metadata": { "external_id": "payout-001" }
  }'
curl -X POST https://app.tonder.io/api/v1/process/ \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Request-Id: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \
  -d '{
    "operation_type": "withdrawal",
    "amount": 80000.00,
    "currency": "ARS",
    "transfer_method": "BANK_TRANSFER",
    "description": "Balance withdrawal",
    "client_reference": "payout-001",
    "beneficiary": {
      "account_type": "CBU",
      "account": "0000000000000000000000",
      "name": "María López",
      "tax_id": "27234567891",
      "email": "maria.lopez@email.com"
    },
    "metadata": { "external_id": "payout-001" }
  }'
FieldRule
transfer_method"BANK_TRANSFER", the only value in Argentina. "SPEI" or "DEBIT_CARD" returns 400 transfer_method_not_available_for_business.
beneficiary.account_typeCVU, CBU or ALIAS.
beneficiary.accountThe 22-digit CBU or CVU. Omit it when account_type is ALIAS.
beneficiary.aliasThe destination alias, when account_type is ALIAS.
beneficiary.tax_idRecommended: the beneficiary's CUIT/CUIL. Tonder validates the beneficiary with it.
  • Payouts debit your pre-funded balance. A payout above it is rejected with 400 insufficient_balance before it is sent. Check the balance with GET /api/v1/withdrawals/balance.
  • If tax_id doesn't match the account's holders, the payout ends Declined with beneficiary_tax_id_mismatch; an inactive account ends Declined with beneficiary_account_inactive.
StatusMeaningWebhook
PendingReceived, being approved and routed.withdrawal_Pending
ProcessingSent for execution.—
SuccessThe funds reached the beneficiary.withdrawal_Success
DeclinedRejected. decline_code is one of insufficient_balance, beneficiary_account_inactive, beneficiary_tax_id_mismatch, beneficiary_currency_mismatch or provider_rejected.withdrawal_Declined
FailedA technical error; Tonder's team steps in.withdrawal_Failed

The full status vocabulary is in Withdrawals › Statuses.

Web SDK and Hosted Checkout

With the Web SDK, both methods appear in tonder.getPaymentMethods() once they're enabled — qr with the label "QR" and transfer with "Transferencia". Pay with the method's type and render the same next_action from the transaction it returns:

const result = await tonder.pay({
  amount: 15000,
  currency: 'ARS',
  return_url: 'https://your-store.com/checkout/complete',
  client_reference: 'ORD-001',
  payment_method: { type: 'qr' }, // or 'transfer'
});

For Hosted Checkout in Argentina, ask your Tonder contact.

Statuses and webhooks

StatusMeaningTerminalWebhook
PendingThe QR or the CVU was issued; waiting for the payer.Nopayment_Pending
SuccessThe funds were credited and confirmed. Credit your user.Yespayment_Success
Expiredexpires_at passed without a payment.Yespayment_Expired
CancelledCancelled by Tonder before the payment.Yespayment_Cancelled

Webhooks use the Short format, as in Mexico, with payment_method_type "qr" or "transfer" and currency "ARS". A payment_Success adds the payer's details at the root: sender_name, sender_tax_id, sender_account (masked), sender_bank and provider_transaction_id — the last one identifies the transaction at the processing institution, so don't build logic on it. A QR refund sends refund_Pending, then refund_Success or refund_Failed. Delivery and retries follow Delivery and retries.

Errors

CodeHTTPWhen
payment_method_not_enabled403The method isn't enabled for your business.
currency_mismatch400currency isn't "ARS", or it was omitted.
invalid_amount_precision400The amount has more than 2 decimals.
amount_below_minimum, amount_above_maximum400The amount is outside the method's limits.
customer_tax_id_invalid400customer.tax_id isn't a valid CUIT/CUIL.
partial_refund_not_supported400A QR refund for an amount different from the original.
refund_not_supported_for_method400A refund of a bank transfer.
refund_window_expired400The original payment is too old to refund.
transfer_method_not_available_for_business400A payout with a transfer_method other than "BANK_TRANSFER".
invalid_beneficiary_account400The CBU, CVU or alias isn't valid.
insufficient_balance400, or DeclinedThe payout is larger than your balance.
beneficiary_account_inactiveDeclinedThe destination account is inactive.
beneficiary_tax_id_mismatchDeclinedbeneficiary.tax_id doesn't match the account's holders.
beneficiary_currency_mismatchDeclinedThe destination account doesn't match the payout currency.
provider_unavailable503The service is temporarily unavailable. Retry later.

Testing

Sandbox test data for Argentina comes from your Tonder contact. The rest of the sandbox setup is in Testing environment.

Amounts and local time

  • Amounts are in ARS with 2 decimals. In your UI, render them the Argentine way: $ 1.234,56.
  • The dashboard and reports show Argentine time, America/Argentina/Buenos_Aires (UTC-3, no daylight saving).

Not available yet

Cards, installments and 3DS in Argentina · USD or currency conversion · partial refunds · refunds of bank transfers through the API · Payment Links in ARS.

Next steps

Was this page helpful?

On this page