Payouts

Send ACH and real-time payouts in the US

Yaspa's Payouts product enables merchants to send money to consumer Checking / Savings accounts.

Integration follows the convention laid out in the Product Overview. Send Yaspa a payout instruction API call with the payment details and open the URL Yaspa returns to start the hosted payout journey. There, the customer grants Yaspa access to their account information. Yaspa retrieves account, activity and ownership information over open banking APIs, checks it against the customer information you provided to verify ownership, and checks the request against fraud rules and block lists before issuing an approval decision.

At the end of the flow, Yaspa returns the customer to a configurable redirect URL and sends server-side webhook notifications at each status update. Accepted transactions are deducted from the merchant's virtual account immediately and processed as credits over Same Day ACH or RTP/FedNow.

📘

Payouts are not guaranteed. If a payout is returned, the affected funds are returned to the merchant's virtual account.

Configuration

Payouts have mandatory security requirements and additional configuration options.

Signing Payout Instructions

Payout instructions and related requests must be signed for security. See Payout Security.

Closed Loop

Optionally configure payouts as closed loop, where the bank selector is not available and the customer must select an account previously used for pay-ins to receive the payout. Enable it by sending "disableAddingNewBanks": true. Otherwise, or if false, the payout is open loop. Closed loop is strongly recommended because it helps prevent money laundering. Consider open loop only if you already have strong AML and payout controls.

Payout Approvals

Optionally insert a pause between the customer completing the hosted payout flow and the payout being processed so that you can review and approve or reject the payout. See Payout Approvals for details. Payout approvals are strongly recommended, and should only be disabled if you already have other disbursement review processes.

Real-time rails

Yaspa can process payouts over Same Day ACH or real-time RTP / FedNow rails. Control this with paymentGiro:

  • ACH: Same Day ACH
  • INSTANT: RTP or FedNow

If you send INSTANT and the customer's bank doesn't support RTP or FedNow, or if the supported network is down, Yaspa automatically fails over to Same Day ACH and updates paymentGiro to ACHin subsequent webhooks. Pay attention to this failover, and make sure the customer is clearly told the expected settlement speed of their withdrawal.

Integration Guide

Create Hosted Payout API

When the customer selects Yaspa at checkout, use the Create Hosted Payout API to send Yaspa the information required to create a payout session as in the full example provided below:

curl --request POST \
  --url https://api.sandbox.us.yaspa.com/v2/payouts/hosted-payout/generate-link \
  --header 'AuthorizationCitizen: {private API key}' \
  --header 'Signature: {Base 64 encoded signature}' \
  --header 'Expires-at: {UNIX timestamp for signature expiration}' \
  --header 'accept: text/plain' \
  --header 'content-type: application/json' \
  --data '
{
  "customerIdentifier": "xekzyz3lorw9",
  "paymentGiro": "INSTANT",
  "amount": 10.01,
  "currency": "USD",
  "reference": "3pdcj42fpn9t",
  "supportedCountries": ["US"],
  "successRedirectUrl": "http://www.example.com/success",
  "failureRedirectUrl": "http://www.example.com/failure",
  "customerDetails": {
    "firstName": "John",
    "lastName": "Smith",
    "email": "[email protected]",
    "dob": "1970-01-01",
    "mobile": "+15555555555",
    "address": {
      "address1": "123 Any Street",
      "address2": "Apt A",
      "city": "Boston",
      "stateCode": "MA",
      "zipCode": "02134",
      "countryCode": "US"
    }
  },
  "disableAddingNewBanks": true,
  "isQueued": true
}
'

Upon receipt, Yaspa creates a transaction and maps it to a customer profile tied to the merchant. For customers paying the merchant with Yaspa for the first time, Yaspa creates a new customer tied to the the customerIdentifier paired with the customerDetails.email. The response is a link for the hosted payout session including a transaction identifier and a boolean to flag returning customers. Log the transaction-id value from the URL as this will be included in subsequent webhooks as the transactionId and can be used with the reference and customerIdentifier to tie the session and webhooks back to the your payment request and customer profile.

https://banks.sandbox.us.yaspa.com/hosted/payout?transaction-id=d7941707-fe9f-fa8d-2491-3da414&secondTimeUser=false

Redirect Handler

Redirect the customer to the URL in the API response, paying particular attention to container version requirements in native mobile apps. When the customer completes the flow, the hosted page redirects them to the success or failure URL depending on the outcome. Set these as static values in the Admin Dashboard, or per transaction using successRedirectUrl and failureRedirectUrl. The per-transaction approach is strongly recommended, because you can append data such as the reference to identify the result and session when the customer returns:

"successRedirectUrl": "https://www.example.com/success&ref={{ref}}",
"failureRedirectUrl": "https://www.example.com/failure&ref={{ref}}"
⚠️

Business operations must be triggered by webhooks, never by redirects or client-side interactions. A redirect to successRedirectUrl accompanied by a QUEUED or ACCEPTED webhook means the customer has completed their part of the flow, so their balance should be decremented.

Webhooks

Yaspa sends webhooks for status updates throughout the customer journey and processing thereafter. Pay particular attention to QUEUED when using payout approvals. A QUEUED or ACCEPTED webhook means the customer has successfully requested a payout/withdrawal, so decrement their balance by the requested amount. Listen for later updates and credit the funds back if the payout is ultimately unsuccessful.

Webhooks for payouts follow the payment webhook version 3 structure and are sent as HTTPS POST requests. As noted above, several merchant-defined identifiers follow the transaction throughout its lifecycle so that it can be easily mapped to your payment stack. Configure the webhook endpoint and the enabled events in the Admin Dashboard; payouts have a lean status model, so Yaspa recommends enabling all statuses. A typical example of the request body is as follows:

{
  "type": "PAYOUT_ACCEPTED",
  "data": {
    "id": "6ac023e2351a3351401565cf",
    "transactionId": "d7941707-fe9f-fa8d-2491-3da414",
    "version": "3",
    "transactionStatus": "ACCEPTED",
    "createdAt": "2026-10-02T21:36:34.693Z",
    "reference": "3pdcj42fpn9t",
    "language": "en",
    "merchant": {
      "id": "69bbee7367f8982c81665203",
      "tradingName": "example.com",
      "bank": "DWOLLA",
      "withdrawal": false
    },
    "customer": {
      "identifier": "xekzyz3lorw9"
    },
    "account": {
      "financialInstitution": "US Test Bank",
      "holderName": "John Smith",
      "numberLastFour": "7890",
      "routingNumber": "222222226",
      "counterPartyId": "69c15af567f8982c8166524c"
    },
    "payment": {
      "amount": "10.01",
      "currency": "USD",
      "giro": "INSTANT",
      "providerPaymentId": "mock-payout-tx-1790977001487"
    },
    "journey": {
      "type": "HOSTED_PAYOUT",
      "authType": "STANDARD",
      "verified": false
    }
  }
}

Type and Status Definitions

Webhook typeTransaction statusMeaning
PAYOUT_CREATEDCREATEDStarting point for the payout.
PAYOUT_CANCELLEDCANCELLEDTerminal failure. The customer cancelled the flow before completion.
PAYOUT_EXPIREDEXPIREDTerminal failure. The customer did not complete the hosted flow. Typically after 30 minutes of inactivity.
PAYOUT_QUEUEDQUEUEDThe customer completed the hosted journey and the payout awaits merchant approval.
PAYOUT_REJECTEDCANCELLED_BY_MERCHANTTerminal failure. The queued payout was rejected by the merchant.
PAYOUT_ACCEPTEDACCEPTEDApproved by the merchant, Yaspa, and Yaspa's banking partners. Funds are deducted from the merchant's Available Balance at this point.
PAYOUT_SETTLEDSETTLEDFunds should be available in the receiver's account.
PAYOUT_ERRORERRORTerminal failure. Caused by velocity or limits, blocklist, or an ACH return.
PAYOUT_ERRORFAILEDTerminal failure. A risk decline.

Status model

Only failures are truly terminal. SETTLED is not terminal, because returns can be filed after an otherwise successful payout.

Settlement and Reconciliation in the Admin Dashboard

Payouts are processed as credits according to paymentGiro:

  • Same Day ACH: settles the same day if ACCEPTED before 3pm CT on a banking day, otherwise the customer receives funds with the next batch.
  • Real-time (INSTANT): settles within seconds.

In both cases the SETTLED webhook indicates the transaction was submitted and the customer should have received the funds.

Payouts are deducted from the Virtual Account immediately on acceptance, so the Available Balance must hold enough above the minimum to cover all requested payouts. If Yaspa receives a return for a payout, the transaction is marked PAYOUT_ERROR and the funds are returned to the Available Balance.

Top up the balance from the Ledger page of the Admin Dashboard. Click Top up in the Summary box near the top left, as for the initial pre-launch top-up. Top-ups are Same Day ACH debits, so make sure the external business account allows debits. A top-up only appears in the balance once it settles. The cutoff for same-day settlement is 3pm Central Time. Plan ahead for expected increases in payout volume.

The Ledger page has filterable event-level reporting that can be exported as CSV for reconciliation. These actions are restricted to Finance users.

Sequence Diagram

Most payouts go to returning customers who have already used Yaspa for pay-ins to the merchant. Returning customers with accounts in good standing, including those who have only made pay-ins so far, get a streamlined experience. To identify a returning customer, send an established customerIdentifier with the matching customerDetails.email. Speak with your Yaspa Solution Architect if you would like to design fully open loop and/or unlinked payout flows.

Failure handling

The hosted journey shows clear messages so customer can resolve soft declines in-session and understand a failure before being redirected back. While it is not necessary to establish your own messaging for each possible scenario, failure handling may be configured based on the following transaction status and error details provided via webhook notification.

StatuserrorerrorReasonDescriptionRecommendation
EXPIREDn/an/aThe customer did not complete the session in time. Expiry is typically 30 minutes.The customer has most likely abandoned the transaction. They may retry, but may not be on the page to see any notice.
CANCELLEDn/an/aThe customer cancelled the hosted journey.The customer may try again.
ERRORn/an/aThe customer tried to withdraw more than the maximum.The customer may retry with a lower amount as shown on the error screen or return later when velocity has decreased or the limit has reset.
ERRORn/aCustomer has been blacklistedYaspa has blocklisted the customer.Unblocking is a manual process. Contact Yaspa.
CANCELLED_BY_MERCHANTn/an/aThe customer completed the flow, but the merchant rejected the payout.Tell the customer the payout was not successful and give a reason as appropriate. Don't encourage a retry unless approval is substantially more likely.
FAILEDn/an/aDeclined due to elevated risk, such as a blocklisted attribute or high velocity.A second attempt is highly likely to fail for the same reason.
ERRORn/an/aA successful payout later moved to ERROR. Most likely Yaspa received an ACH return and returned the funds to the Available Balance.Payouts are most often returned due to account closure. Ask the customer to choose a different destination account, or pay out with a different method.

Did this page help you?