Inyo

Sandbox Testing

The sandbox lets you drive a transaction through its entire lifecycle without real money movement. Two tools make this possible: test data that triggers specific compliance behaviors, and a force-event endpoint that simulates the external callbacks (gateway webhooks, payout-network notifications) that normally advance a transaction.


Forcing Status Transitions

Endpoint: POST /organizations/{tenant}/fx/transactions/{transactionId}/events
Authentication: Agent-level
Availability: Sandbox/staging only β€” this endpoint does not exist in production.

curl --request POST \
  --url https://{FQDN}/organizations/$TENANT/fx/transactions/$TRANSACTION_ID/events \
  --header 'Content-Type: application/json' \
  --header "x-api-key: $API_KEY" \
  --header "x-agent-id: $AGENT_ID" \
  --header "x-agent-api-key: $AGENT_KEY" \
  --data '{
  "event": "payment_authorized",
  "message": "Optional description"
}'

Available Events

EventValid from stateWhat it simulates
payment_authorizedWaitingChallenge3dsThe gateway 3DS callback. Resumes the flow β€” dispatches payout integration. Use when the transaction is stuck waiting for 3DS.
ach_settledWaitingSettlementThe ACH settlement callback. Moves the transaction through PaymentSettled β†’ PaymentCaptured and triggers payout confirmation.
payment_capturedReviewApprovedA card capture confirmation. Triggers payout confirmation.
payout_paidPayoutAccepted, PayoutReleased, WaitingPayoutThe payout network confirming the beneficiary received funds. Moves the transaction to Paid β†’ Completed.
payout_voidPayoutAccepted, PayoutHold, PayoutReleased, WaitingPayoutThe payout network voiding the transaction. Depending on tenant configuration, auto-reverses or parks at PendingReversalApproval.
hold_releasedPayoutHoldThe payout network releasing a compliance hold. Resumes the flow.
cancelledAny cancellable stateClient-initiated cancellation (voids the payment and cancels the payout).
refundedRefundable statesMarks the transaction as refunded.

If the transaction is not in a valid state for the event, the endpoint returns an error explaining the current state.

Typical Test Flow (Card + 3DS)

  1. Create the transaction β†’ status WaitingChallenge3ds, paymentStatus: ActionRequired
  2. Force 3DS: { "event": "payment_authorized" }
  3. Transaction auto-progresses β†’ PayoutAccepted β†’ ManualReview β†’ ReviewApproved β†’ PaymentCaptured β†’ WaitingPayout
  4. Force delivery: { "event": "payout_paid" }
  5. Transaction reaches Completed

Typical Test Flow (ACH)

  1. Create the transaction β†’ progresses to WaitingSettlement
  2. Force settlement: { "event": "ach_settled" }
  3. Transaction auto-progresses β†’ PaymentSettled β†’ PaymentCaptured β†’ WaitingPayout
  4. Force delivery: { "event": "payout_paid" }
  5. Transaction reaches Completed

Compliance Test Scenarios

Certain sender data values trigger specific compliance behaviors in the sandbox:

ParameterValueResultCompliance StatusPayout Status
address.zipcode99999Transaction REJECTEDRejectedCancelled
phoneNumber+14155550000Transaction REJECTEDRejectedCancelled
firstName + lastNameBLOCK LIST MATCHTransaction REJECTEDRejectedCancelled
firstName + lastNameOFAC MATCHTransaction held for verificationPendingPending (status PayoutHold)

Payout-Network Hold

Use sender name JULIO SOLANO to trigger a compliance hold at the payout network:

{ "firstName": "JULIO", "lastName": "SOLANO", "...": "..." }

The transaction reaches PayoutHold after payout integration. Release it with the hold_released force event (or it is released by the network/backoffice).

Expected flow:

... β†’ ProcessingPayout β†’ PayoutHold β†’ [hold released] β†’ PayoutReleased β†’ ...

Payout-Network Rejection (Missing Receiver Data)

Use zipcode 96738 on the sender's billing address to trigger receiver-data validation failure at the payout network:

{ "address": { "zipcode": "96738", "...": "..." } }

The rejection depends on missing beneficiary data (country, city, state). If the recipient has complete address data, the transaction is accepted regardless of zipcode.

Payment Decline

Use a card token that the gateway sandbox rejects, or an expired token. The transaction reaches PaymentDeclined β†’ Cancelled.

3DS Decline

When redirected to the 3DS challenge page, choose "Decline" (where the sandbox offers it). The gateway reports the failure and the transaction moves to PaymentDeclined β†’ Cancelled.


Test Cards

Use sandbox test cards to simulate 3DS scenarios. The full list is in Payments Gateway test cards. Common ones:

Card NumberScheme3DS Behavior
4462030000000000VISA3DS Challenge
4035874000424977VISAFrictionless (no challenge)
5425230000004415Mastercard3DS Challenge
4000000000000002VISADeclined

Tokenize these via the gateway SDK, then pass the token as paymentMethod.token when creating a funding account.


Polling for Status

After creating a transaction, poll GET /organizations/{tenant}/fx/transactions/{transactionId} and watch:

FieldWhat to expect
complianceStatusPending β†’ Approved (after payout integration)
payoutStatusPending β†’ Processing β†’ Completed
paymentStatusActionRequired β†’ null (after 3DS completes)
receiptRegulatory disclosures (available from creation)

For the full transition audit trail, use GET /fx/transactions/{transactionId}/status β€” see Transaction. In production, prefer webhooks over polling.