The route_selected callback in the diagram maps to the Widget complete event and returns { via, selection }.The Select for Deposit flow lets users pick a saved card or get bank/crypto transfer details to fund their Uphold account. Refer to the Bank Deposit flow or Crypto Deposit flow for the backend steps needed to monitor and credit incoming funds.
The example code below is for web applications. For native apps using a WebView, you’ll still need a bridge for events, as outlined in Installation & Setup.
Once you have the session, initialize the Payment Widget for the Select for Deposit flow:
Copy
Ask AI
import { PaymentWidget } from '@uphold/enterprise-payment-widget-web-sdk';const initializeDepositWidget = async () => { // Create the session const sessionData = await createDepositSession(); // Initialize the Widget with the session const widget = new PaymentWidget<'select-for-deposit'>(sessionData.session, { debug: true }); // Set up event handlers (see sections below) setupEventHandlers(widget); // Optional: listen for the Widget to be fully loaded widget.on('ready', () => { console.log('Payment Widget is ready'); }); // Mount the Widget in an iframe widget.mountIframe(document.getElementById('payment-container'));};
The complete event is fired when the user successfully selects a deposit method.
Copy
Ask AI
widget.on('complete', (event) => { const result = event.detail.value; console.log('Deposit method selected:', result); // result.via indicates the type of selection const { via, selection } = result; // Process the selected deposit method handleDepositMethodSelected(via, selection); // Clean up the Widget widget.unmount();});
External Account Selection (via: "external-account")
When an external account is selected, the selection property contains an external account object with the saved payment method details.Account Deposit Method Selection (via: "deposit-method")
When an account deposit method is selected, the selection property contains an object with the following structure:
account - The account that will receive the deposited funds
When the via property is deposit-method, the user will complete their deposit through a bank or crypto transfer. The Payment Widget presents the necessary transfer details (bank account information or crypto address with destination tag/memo) to facilitate this transfer, eliminating the need for your application to display them separately. However, the Payment Widget does not monitor for the completion of the transfer.Your application may optionally implement transaction monitoring to detect when the deposit has been processed and provide real-time user feedback. This can be achieved by polling the transactions endpoint to identify when the deposit is received by the account specified in the selection.account.id property of the complete event payload.The following example demonstrates how to poll for incoming transactions:
Monitor deposit transaction
Copy
Ask AI
const monitorForDeposit = async (accountId) => { const checkForDeposit = async () => { try { const response = await fetch('https://api.enterprise.uphold.com/transactions', { headers: { 'Authorization': 'Bearer <API_TOKEN>', 'Content-Type': 'application/json', 'X-On-Behalf-Of': 'user <USER_ID>' } }); const transactions = await response.json(); // Look for a transaction where: // - origin is an external-account node // - destination is the account we're expecting the deposit to const depositTransaction = transactions.find(transaction => { return transaction.origin.type === 'external-account' && transaction.destination.type === 'account' && transaction.destination.id === accountId; }); return depositTransaction; } catch (error) { console.error('Error checking for deposit:', error); return; } }; // Poll every 30 seconds for up to 10 minutes const pollInterval = 30000; // 30 seconds const maxAttempts = 20; // 10 minutes total let attempts = 0; const poll = setInterval(async () => { attempts++; const depositTransaction = await checkForDeposit(); if (depositTransaction || attempts >= maxAttempts) { clearInterval(poll); if (depositTransaction) { handleDepositReceived(depositTransaction); return; } if (!depositTransaction && attempts >= maxAttempts) { console.log('Polling timeout reached without detecting deposit'); handleDepositTimeout(); } } }, pollInterval);};const handleDepositReceived = (transaction) => { console.log('Deposit received:', transaction); // Check transaction status to determine outcome if (transaction.status === 'completed') { // Update UI to show successful deposit showDepositSuccess(transaction); } else if (transaction.status === 'failed') { // Update UI to show failed deposit showDepositFailed(transaction); } else if (transaction.status === 'processing') { // Update UI to show deposit is still being processed showDepositProcessing(transaction); }};const handleDepositTimeout = () => { console.log('Deposit monitoring timed out'); // Show message that deposit is taking longer than expected showDepositPending();};
The cancel event is fired when the user closes the Widget without selecting an external account.
Copy
Ask AI
widget.on('cancel', () => { console.log('User cancelled deposit method selection'); // Handle cancellation handleDepositCancelled(); // Clean up the Widget widget.unmount();});const handleDepositCancelled = () => { // Redirect back to the previous page or main deposit page};
The error event is fired when an error occurs during the external account selection process.
Copy
Ask AI
widget.on('error', (event) => { const error = event.detail.error; console.error('Deposit Widget error:', error); // Handle the error handleDepositError(error); // Clean up the Widget widget.unmount();});const handleDepositError = (error) => { console.error('Error details:', { code: error.code, message: error.message }); // Show user-friendly error message like 'An error occurred. Please try again later.'};
The Payment Widget does not offer user-facing error handling. It’s the responsibility of the host application to present an error message to the user and unmount the Widget.
The following steps are optional. Most applications can simply close the trading screen after the user receives the transfer details (bank account or crypto address), as the deposit will be processed automatically.
Monitor for payment(Optional) - Set up monitoring to detect when the transfer is received and provide real-time feedback to users.
Provide deposit confirmation(Optional) - Notify the user when the deposit has been successfully processed and credited to their account.
Backend flow reference(Optional) - For bank transfers, align monitoring and notifications with the Bank Deposit flow.