Documentation menu
Docs / Build
Money movement
Loads, QR payment requests, payments, merchant-to-merchant payments, withdrawals, refunds, disputes, statements and reconciliation.
Every movement of money follows the same pattern: your server creates the record, the customer confirms it on the hosted screen with confirmation_session.token, and a webhook reports the final status.
Loads (add funds)#
curl -X POST https://sandbox.a2ainstapay.com/v1/loads -H "Authorization: Bearer $A2A_ACCESS_TOKEN" -H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" -d '{"customer_id":"cus_...","amount":10000}'| Status | Meaning |
|---|---|
requires_confirmation | Waiting for the customer on the hosted screen |
processing | The Request for Payment is at the customer's bank; they approve it in their banking app |
settled | The funds are in the Digital Account (load.settled) |
failed | failure_code: declined_by_customer, request_expired, rejected_by_bank, confirmation_expired, limit_exceeded or account_restricted |
Payment requests (QR codes)#
A merchant shows a QR code; the customer's app scans it and pays it.
| Type | Use | Fields |
|---|---|---|
dynamic | One order, one amount | amount, optional order_reference, expires_in (60 seconds to 7 days) |
static | A code printed at a counter or till; the customer enters the amount | collection_point.reference and collection_point.name |
The response carries qr_payload, signed by A2A InstaPay. Render it as a QR code. A dynamic request becomes paid or expired; a static request stays open.
Payments#
curl -X POST https://sandbox.a2ainstapay.com/v1/payments -H "Authorization: Bearer $A2A_ACCESS_TOKEN" -H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" -d '{"payer_customer_id":"cus_...","source":"balance","qr_payload":"A2AQR1...."}'| Kind | How | Notes |
|---|---|---|
| From balance | source: balance | Final as soon as the customer confirms (payment.completed) |
| Pay by bank | source: bank_account | payment.processing, then payment.completed when the payer's bank pays the Request for Payment |
| To a merchant without a QR code | payee_customer_id and amount | For example an online checkout |
| Merchant to merchant | A merchant pays another merchant | From balance only, with invoice_reference |
A payment can be canceled with POST /v1/payments/{id}/cancel only while it waits for confirmation. Completed payments are final; they can be returned only by a merchant refund.
Withdrawals#
POST /v1/withdrawals with customer_id and amount sends an RTP credit transfer to the verified linked account. The amount is reserved when the customer confirms. withdrawal.settled or withdrawal.failed follows.
Refunds#
curl -X POST https://sandbox.a2ainstapay.com/v1/refund-requests -H "Authorization: Bearer $A2A_ACCESS_TOKEN" -H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" -d '{"payment_id":"pay_...","amount":1000,"reason":"requested_by_customer"}'The merchant's authorized user confirms the refund on the hosted screen. If the merchant's balance is short, the refund waits as pending_funds and continues when funds arrive. A refund goes back the way the payment came: to the payer's balance, or by RTP to the payer's bank. refund.updated reports each step, and payment.partially_refunded or payment.refunded follows. Refunds are possible within your program's refund window (30 days in the sandbox), and never for more than the original amount less earlier refunds.
Disputes#
Record a customer's notice with POST /v1/disputes: type is error, unauthorized_transfer or purchase_dispute, with notice_received_at. Consumer disputes about errors and unauthorized transfers are handled under Regulation E, with provisional credit while the investigation runs. dispute.updated reports each step: received, investigating, provisional_credit, resolved, closed.
Limits and fees#
Limits apply per transaction and per day and month, by amount and by count. An amount over a limit returns limit_exceeded with details.limit. Fees appear in fees on each payment, with net_amount for the merchant. Your program's limits and fees are agreed with FINAP USA LLC; in the sandbox you can change them in the portal settings to test.
Statements and reconciliation#
GET /v1/accounts/{id}/statementslists monthly statements;download_urlis valid for 15 minutes.statement.availableannounces each one.GET /v1/reports/reconciliation?date=YYYY-MM-DDgives the totals of a business date (US Eastern Time) and a CSV with every posting, to reconcile your records with A2A InstaPay's ledger.
Questions about this page? Contact developer support.