Send ACH bank withdrawals with the Uphold Payment Widget for account selection, then create the quote and transaction via the REST API to complete payout.
The Payment Widget handles ACH bank account selection and creation. Your backend creates the session, then continues with the REST API to create a quote and transaction once the user has a destination bank account.
The Payment Widget does not create any transaction. Your backend must create the quote and transaction via the REST API after the user selects their bank account.
ACH withdrawals can be sourced from any account. If the selected account is not in USD, the balance will be converted at the time of the transaction using Uphold’s prevailing rate. Make sure the origin asset has the necessary features enabled.Call List accounts to retrieve the user’s accounts and let them pick the one to withdraw from.
When the user completes the selection, the complete event fires with via: "external-account" and a selection containing the chosen external account.
widget.on('complete', (event) => { const { via, selection } = event.detail.value; if (via === 'external-account' && selection.type === 'bank') { // selection is the external account the user selected or just added handleBankWithdrawal(selection); } widget.unmount();});
The event payload:
via — set to external-account when the user selects or adds a bank account.
selection — an external account object with the selected bank details.
selection.network — the network to use for the withdrawal ("ach" or "fednow" if secondaryNetworks includes it). Pass this value in the quote request.
The error event fires when an error occurs during the bank account selection process.
widget.on('error', (event) => { console.error('Widget error:', event.detail.error); widget.unmount(); // Show a user-friendly error message});
The Payment Widget handles most errors internally. For unrecoverable errors, the widget fires an error event. It is the host application’s responsibility to handle these events, present an error message to the user, and unmount the widget.
Create a quote with Create quote. Pass network: "ach" on the destination node to route the transfer via ACH, or leave it out to route via the external account’s default network. If the external account has secondaryNetworks, the user can choose which one to use for the transfer. The quote must be created with the selected network to ensure accurate fees and expiration time.
After the user confirms the withdrawal, call Create transaction with the quote ID to execute the transfer.
POST /core/transactions{ "quoteId": "734111d9-ace0-5b3c-bb4e-7b7b55b8a7b1"}
In a successful ACH withdrawal, the origin is the user’s account and the destination is the external-account representing the user’s bank. The transaction status is initially processing and updates to completed once the transfer settles.