Outgoing Transaction Flow
Your customer/platform sends funds to an external recipient.Create Quote
Lock in exchange rate and fees:Response:
- Quote ID
- Locked exchange rate
- Expiration time (typically ~5 minutes or greater, depending on corridor)
Execute Quote
Initiate the payment:Result:
- Transaction created with status
PENDING - Source account debited immediately
OUTGOING_PAYMENT.PENDINGwebhook sent
Processing
Grid handles:
- Currency conversion (if applicable)
- Routing to appropriate payment rail
- Settlement with destination bank/wallet
PROCESSINGCompletion or Failure
Success Path:
- Funds delivered to recipient
- Status:
COMPLETED settledAttimestamp populatedOUTGOING_PAYMENT.COMPLETEDwebhook sent
- Delivery failed (invalid account, etc.)
- Status:
FAILED failureReasonpopulatedOUTGOING_PAYMENT.FAILEDwebhook sent- Refund initiated automatically — track via the
refundobject andOUTGOING_PAYMENT.REFUND_*webhooks
Same-Currency Transfers
For same-currency transfers without quotes:Transfer-Out (Internal → External)
Transfer-In (External → Internal)
Outgoing Payment Status
A singlestatus field represents whether the transaction reached its destination:
| Status | Description |
|---|---|
| PENDING | Quote is pending confirmation |
| EXPIRED | Quote wasn’t executed before the expiry window |
| PROCESSING | Executing the quote after receiving funds (checking internal balances, or push/pull to/from external account) |
| COMPLETED | Payout successfully reached the destination account |
| FAILED | Something went wrong — accompanied by a failureReason |
State Diagram
Refund Object
When a payment fails or is cancelled, refunds are tracked in a dedicated object on the transaction, decoupled from the payment status:| Field | Description |
|---|---|
reference | Refund reference ID |
initiatedAt | Timestamp when refund was initiated |
settledAt | Timestamp when refund settled |
status | PENDING, COMPLETED, or FAILED |
reason | Why the refund occurred — TRANSACTION_FAILED, USER_CANCELLATION, or TIMEOUT |
Webhooks
Outgoing payment webhooks use the formatOUTGOING_PAYMENT.<STATUS>. The webhook request body contains the full transaction resource.
Event Types
| Event | Description |
|---|---|
OUTGOING_PAYMENT.PENDING | Transaction created, quote pending confirmation |
OUTGOING_PAYMENT.PROCESSING | Quote confirmed, payout in progress |
OUTGOING_PAYMENT.COMPLETED | Payout reached destination |
OUTGOING_PAYMENT.FAILED | Payout failed |
OUTGOING_PAYMENT.EXPIRED | Quote expired before execution |
OUTGOING_PAYMENT.REFUND_PENDING | Refund initiated |
OUTGOING_PAYMENT.REFUND_COMPLETED | Refund settled |
OUTGOING_PAYMENT.REFUND_FAILED | Refund failed |
Example Payloads
- PENDING
- COMPLETED
- FAILED
- REFUND_COMPLETED
Handling Webhooks
Scenarios
- Happy Path
- Failure with Refund
- Failure with Failed Refund
- Bank Return
- Manual Cancellation
The standard successful payment flow:
OUTGOING_PAYMENT.PENDINGOUTGOING_PAYMENT.PROCESSINGOUTGOING_PAYMENT.COMPLETED
Receipt Delivery Confirmation
Some platforms are contractually required to send a receipt to their customer after a transaction completes. Use the receipt confirmation endpoint to record when the receipt was delivered:receiptDeliveryConfirmedAt populated.
If you omit receiptDeliveryConfirmedAt from the request body, Grid uses the current server time. Calling this endpoint again updates the stored confirmation time.
This endpoint is only necessary if your platform agreement requires receipt confirmation. Most integrations do not need this step.
Listing Transactions
Query all transactions for a customer or date range:Failure Handling
Common Failure Reasons
| Failure Reason | Description | Recovery |
|---|---|---|
QUOTE_EXPIRED | Quote expired before execution | Create new quote |
QUOTE_EXECUTION_FAILED | Error executing the quote | Create new quote |
INSUFFICIENT_BALANCE | Source account lacks funds | Fund account, retry |
LIGHTNING_PAYMENT_FAILED | Lightning network payment could not be routed | Retry or use alternative rail |
FUNDING_AMOUNT_MISMATCH | Funding amount doesn’t match expected amount | Verify amounts and retry |
COUNTERPARTY_POST_TX_FAILED | Post-transaction processing at counterparty failed | Contact support |
refund object on the transaction and OUTGOING_PAYMENT.REFUND_* webhook events. See Refund Object above.
Best Practices
Store transaction IDs for reconciliation
Store transaction IDs for reconciliation
Save transaction IDs to your database:
Handle idempotency
Handle idempotency
Use the
Idempotency-Key HTTP header for safe retries:Provide clear status messages to users
Provide clear status messages to users
Translate technical statuses to user-friendly messages: