Overview
The Devdraft Embed Widget is a customizable, embeddable checkout component that enables your website to accept cryptocurrency and bank transfer payments. It provides a seamless payment experience with built-in support for multiple blockchain networks, stablecoins, and traditional bank payment rails.
Drop-in Integration Add payments to any website with just a few lines of code
Multi-Currency Support Accept USDC and EURC across 9 blockchain networks
Real-time Status Automatic payment verification with configurable timeouts
CDN URLs
The widget is hosted on our CDN and can be loaded directly into any webpage:
JavaScript
https://embed.devdraft.ai/devdraft-embed.js
CSS
https://embed.devdraft.ai/devdraft-widget.css
Quick Start
Basic Installation
Add the widget to your HTML page:
<! DOCTYPE html >
< html >
< head >
<!-- Load the widget styles -->
< link rel = "stylesheet" href = "https://embed.devdraft.ai/devdraft-widget.css" >
</ head >
< body >
<!-- Container for the checkout widget -->
< div id = "checkout-container" ></ div >
<!-- Load the widget script -->
< script src = "https://embed.devdraft.ai/devdraft-embed.js" ></ script >
< script >
// Mount the checkout widget
window . DevdraftWidget . mountDevdraftCheckout ( 'checkout-container' , {
clientKey: 'your-client-key' ,
clientSecret: 'your-client-secret' ,
walletId: 'your-wallet-id' ,
amount: 99.99 ,
currency: 'USDC' ,
merchantName: 'Your Store Name' ,
onSuccess : ( result ) => {
console . log ( 'Payment successful!' , result );
},
onError : ( error ) => {
console . error ( 'Payment error:' , error );
}
});
</ script >
</ body >
</ html >
Data Attribute Auto-Init
For simpler integrations, use data attributes to auto-initialize the widget:
< div
data-devdraft-checkout
data-client-key = "your-client-key"
data-client-secret = "your-client-secret"
data-wallet-id = "your-wallet-id"
data-amount = "99.99"
data-currency = "USDC"
data-merchant-name = "Your Store Name"
></ div >
< script src = "https://embed.devdraft.ai/devdraft-embed.js" ></ script >
The widget automatically initializes on page load when it finds elements with data-devdraft-checkout attribute.
Configuration Options
Mount Options
When using mountDevdraftCheckout(), you can pass the following configuration options:
Option Type Required Default Description clientKeystring Yes - Your Devdraft API client key clientSecretstring Yes - Your Devdraft API client secret walletIdstring Yes - The wallet ID to receive payments amountnumber Yes - Payment amount currencystring No "USDC"Currency code (USDC, EURC) cartItemsCartItem[] No - Array of cart items to display merchantNamestring No - Your merchant/store name allowedTransferTypesTransferType[] No ["wallet"]Enabled payment methods verificationTimeoutTimerDuration No 5Payment verification timeout (minutes) onSuccessfunction No - Callback on successful payment onErrorfunction No - Callback on payment error onClosefunction No - Callback when widget is closed
Data Attributes
When using auto-init, the following data attributes are supported:
Attribute Type Description data-devdraft-checkout- Enables auto-initialization data-client-keystring Your API client key data-client-secretstring Your API client secret data-wallet-idstring Wallet ID to receive payments data-amountnumber Payment amount data-currencystring Currency code data-merchant-namestring Merchant name data-cart-itemsJSON string Serialized cart items array data-allowed-transfer-typesJSON string Serialized array of transfer types data-verification-timeoutnumber Timeout in minutes (5, 10, 15, 20, 25, 30)
API Reference
Global Methods
The widget exposes methods on window.DevdraftWidget:
mountDevdraftCheckout(target, options)
Mounts the checkout widget to a DOM element.
function mountDevdraftCheckout (
target : string | HTMLElement ,
options ?: MountOptions
) : () => void
Parameters:
target - Element ID string or HTMLElement reference
options - Configuration options (see Mount Options above)
Returns: Unmount function
Example:
// Mount using element ID
const unmount = window . DevdraftWidget . mountDevdraftCheckout ( 'checkout-container' , {
clientKey: 'pk_live_xxx' ,
clientSecret: 'sk_live_xxx' ,
walletId: '550e8400-e29b-41d4-a716-446655440000' ,
amount: 150.00 ,
currency: 'USDC' ,
merchantName: 'TechStore' ,
allowedTransferTypes: [ 'wallet' ],
verificationTimeout: 10 ,
onSuccess : ( result ) => {
console . log ( 'Transaction ID:' , result . transactionId );
console . log ( 'Amount:' , result . amount , result . currency );
},
onError : ( error ) => {
console . error ( 'Payment failed:' , error . message );
},
onClose : () => {
console . log ( 'Widget closed' );
}
});
// Later, unmount the widget
unmount ();
unmountDevdraftCheckout(target)
Unmounts a checkout widget from a DOM element.
function unmountDevdraftCheckout ( target : string | HTMLElement ) : void
Parameters:
target - Element ID string or HTMLElement reference (must match what was used in mount)
Example:
window . DevdraftWidget . unmountDevdraftCheckout ( 'checkout-container' );
Legacy Aliases
For backwards compatibility, the following aliases are available:
window . DevdraftWidget . mountCheckout // Alias for mountDevdraftCheckout
window . DevdraftWidget . unmountCheckout // Alias for unmountDevdraftCheckout
Type Definitions
TransactionResult
Returned on successful payment via onSuccess callback:
interface TransactionResult {
transactionId : string // Unique transaction identifier
completionTime : Date // When the transaction completed
amount : number // Payment amount
currency : string // Currency code
transferType ?: TransferType // "wallet" or "bank"
}
CartItem
Structure for cart items:
interface CartItem {
id : string // Unique item identifier
name : string // Item name/description
price : number // Item price
quantity : number // Quantity
image ?: string // Optional image URL or emoji
}
TransferType
type TransferType = "wallet"
TimerDuration
Allowed values for verificationTimeout:
type TimerDuration = 5 | 10 | 15 | 20 | 25 | 30 // Minutes
Supported Networks & Currencies
Blockchain Networks
The widget supports the following blockchain networks for wallet transfers:
Network ID Supported Stablecoins Polygon polygonUSDC Ethereum ethereumUSDC Base baseUSDC, EURC Arbitrum arbitrumUSDC Solana solanaUSDC, EURC Optimism optimismUSDC Avalanche avalancheUSDC Stellar stellarUSDC Tron tronUSDC
Stablecoins
Currency ID Available Networks USD Coin usdcPolygon, Base, Arbitrum, Avalanche, Optimism, Solana, Stellar, Ethereum, Tron Euro Coin eurcSolana, Base
Complete Integration Example
Here’s a complete e-commerce integration example:
<! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > My Store - Checkout </ title >
<!-- Devdraft Widget Styles -->
< link rel = "stylesheet" href = "https://embed.devdraft.ai/devdraft-widget.css" >
< style >
.checkout-modal {
position : fixed ;
inset : 0 ;
background : rgba ( 0 , 0 , 0 , 0.6 );
display : flex ;
align-items : center ;
justify-content : center ;
padding : 20 px ;
z-index : 1000 ;
opacity : 0 ;
visibility : hidden ;
transition : all 0.3 s ;
}
.checkout-modal.open {
opacity : 1 ;
visibility : visible ;
}
.checkout-content {
max-width : 480 px ;
width : 100 % ;
}
.close-btn {
position : absolute ;
top : 20 px ;
right : 20 px ;
background : #333 ;
color : white ;
border : none ;
border-radius : 50 % ;
width : 40 px ;
height : 40 px ;
cursor : pointer ;
}
</ style >
</ head >
< body >
<!-- Your store content -->
< div class = "product" >
< h1 > Premium Headphones </ h1 >
< p class = "price" > $299.99 </ p >
< button onclick = " openCheckout ()" class = "buy-btn" > Buy Now with Crypto </ button >
</ div >
<!-- Checkout Modal -->
< div class = "checkout-modal" id = "checkout-modal" >
< button class = "close-btn" onclick = " closeCheckout ()" > × </ button >
< div class = "checkout-content" id = "devdraft-checkout" ></ div >
</ div >
<!-- Devdraft Widget Script -->
< script src = "https://embed.devdraft.ai/devdraft-embed.js" ></ script >
< script >
// Product data
const product = {
id: 'headphones-001' ,
name: 'Premium Headphones' ,
price: 299.99 ,
image: '🎧'
};
function openCheckout () {
// Show modal
document . getElementById ( 'checkout-modal' ). classList . add ( 'open' );
// Mount the Devdraft widget
window . DevdraftWidget . mountDevdraftCheckout ( 'devdraft-checkout' , {
// API Credentials (obtain from https://console.devdraft.ai)
clientKey: 'your-client-key' ,
clientSecret: 'your-client-secret' ,
walletId: 'your-wallet-id' ,
// Payment details
amount: product . price ,
currency: 'USDC' ,
// Cart items (optional - for display purposes)
cartItems: [{
id: product . id ,
name: product . name ,
price: product . price ,
quantity: 1 ,
image: product . image
}],
// Merchant branding
merchantName: 'AudioTech Store' ,
// Payment options
allowedTransferTypes: [ 'wallet' ],
verificationTimeout: 10 , // 10 minutes
// Callbacks
onSuccess : ( result ) => {
console . log ( 'Payment successful!' , result );
// Close checkout
closeCheckout ();
// Show success message
alert ( `Thank you for your purchase! \n Transaction ID: ${ result . transactionId } ` );
// Redirect to confirmation page
// window.location.href = `/order-confirmation?tx=${result.transactionId}`;
},
onError : ( error ) => {
console . error ( 'Payment error:' , error );
alert ( 'Payment failed: ' + error . message );
},
onClose : () => {
closeCheckout ();
}
});
}
function closeCheckout () {
// Unmount widget
window . DevdraftWidget . unmountDevdraftCheckout ( 'devdraft-checkout' );
// Hide modal
document . getElementById ( 'checkout-modal' ). classList . remove ( 'open' );
}
// Close on escape key
document . addEventListener ( 'keydown' , ( e ) => {
if ( e . key === 'Escape' ) closeCheckout ();
});
</ script >
</ body >
</ html >
Cart Integration
With Cart Items
Pass cart items to display a breakdown in the widget:
const cartItems = [
{ id: '1' , name: 'Wireless Earbuds' , price: 149.99 , quantity: 1 , image: '🎧' },
{ id: '2' , name: 'Phone Case' , price: 29.99 , quantity: 2 , image: '📱' },
{ id: '3' , name: 'USB-C Cable' , price: 14.99 , quantity: 3 , image: '🔌' }
];
// Calculate total from cart
const total = cartItems . reduce (( sum , item ) => sum + ( item . price * item . quantity ), 0 );
window . DevdraftWidget . mountDevdraftCheckout ( 'checkout' , {
clientKey: 'your-key' ,
clientSecret: 'your-secret' ,
walletId: 'your-wallet' ,
amount: total , // Will be calculated from cartItems if provided
cartItems: cartItems ,
merchantName: 'My Store'
});
With Data Attributes
< div
data-devdraft-checkout
data-client-key = "your-key"
data-client-secret = "your-secret"
data-wallet-id = "your-wallet"
data-amount = "254.94"
data-cart-items = '[{"id":"1","name":"Earbuds","price":149.99,"quantity":1},{"id":"2","name":"Case","price":29.99,"quantity":2}]'
></ div >
Restricting Payment Methods
Wallet Only
Accept only cryptocurrency wallet payments:
window . DevdraftWidget . mountDevdraftCheckout ( 'checkout' , {
// ... other options
allowedTransferTypes: [ 'wallet' ]
});
Payment Verification Timeout
Configure how long to wait for payment verification:
window . DevdraftWidget . mountDevdraftCheckout ( 'checkout' , {
// ... other options
verificationTimeout: 15 // Wait 15 minutes for payment verification
});
Supported values: 5, 10, 15, 20, 25, 30 (minutes)
If the payment isn’t verified within the timeout period, the widget shows a “Session Failed” state with an option to retry.
Transaction Statuses
The widget internally tracks the following transaction states:
Status Description AWAITING_FUNDSWaiting for funds to arrive IN_REVIEWTransaction is being reviewed FUNDS_RECEIVEDFunds have been received PAYMENT_SUBMITTEDPayment submitted for processing PAYMENT_PROCESSEDPayment successfully processed ✓ UNDELIVERABLEPayment could not be delivered RETURNEDPayment was returned REFUNDEDPayment has been refunded CANCELEDTransaction was canceled ERRORAn error occurred DISPUTEDTransaction is under dispute
The onSuccess callback is triggered when the status reaches PAYMENT_PROCESSED.
Styling & Customization
The widget uses scoped CSS classes prefixed with dd- to prevent style conflicts. The widget automatically adapts to its container width (max-width: 680px).
Container Sizing
/* Recommended container styles */
#checkout-container {
max-width : 480 px ;
width : 100 % ;
margin : 0 auto ;
}
Modal Integration
For modal/overlay implementations:
.checkout-modal {
position : fixed ;
inset : 0 ;
background : rgba ( 0 , 0 , 0 , 0.6 );
backdrop-filter : blur ( 4 px );
display : flex ;
align-items : center ;
justify-content : center ;
padding : 20 px ;
z-index : 1000 ;
}
.checkout-modal-content {
max-width : 480 px ;
width : 100 % ;
}
Security Best Practices
Never expose your API credentials in client-side code for production applications. The embed widget is designed for trusted environments.
Recommended Security Patterns
Use Environment Variables : Store credentials securely on your server
Server-Side Initialization : Generate widget configuration on your backend
Domain Restrictions : Configure allowed domains in the Devdraft Console
Amount Validation : Always validate amounts server-side before checkout
Example: Server-Generated Configuration
// Backend generates secure configuration
app . get ( '/api/checkout-config' , async ( req , res ) => {
const config = {
clientKey: process . env . DEVDRAFT_CLIENT_KEY ,
clientSecret: process . env . DEVDRAFT_CLIENT_SECRET ,
walletId: process . env . DEVDRAFT_WALLET_ID ,
amount: calculateOrderTotal ( req . session . cart ),
// ... other validated options
};
res . json ( config );
});
// Frontend fetches and mounts
fetch ( '/api/checkout-config' )
. then ( res => res . json ())
. then ( config => {
window . DevdraftWidget . mountDevdraftCheckout ( 'checkout' , config );
});
Error Handling
Common Errors
Error Cause Solution ”API client not initialized” Missing credentials Ensure clientKey and clientSecret are provided ”Element not found” Invalid target element Check the element ID exists in DOM ”Failed to create transfer” API error Check credentials and wallet ID ”Payment verification timed out” User didn’t complete payment Increase timeout or prompt retry
Error Callback
window . DevdraftWidget . mountDevdraftCheckout ( 'checkout' , {
// ... other options
onError : ( error ) => {
// Log to your error tracking service
console . error ( 'Devdraft Error:' , error );
// Show user-friendly message
showNotification ( 'Payment could not be processed. Please try again.' );
// Optionally track the error
analytics . track ( 'payment_error' , {
message: error . message ,
timestamp: new Date (). toISOString ()
});
}
});
Browser Compatibility
The widget supports all modern browsers:
Browser Minimum Version Chrome 80+ Firefox 75+ Safari 13+ Edge 80+ iOS Safari 13+ Android Chrome 80+
Troubleshooting
Increase the verificationTimeout value
Ensure the payment was sent to the correct address
Verify the exact amount was sent (including network fees separately)
Check that the correct network/blockchain was used
Styles conflicting with page
All widget styles are scoped with dd- prefix. If conflicts occur:
Load widget CSS after your page styles
Use more specific selectors for your styles
Consider using an iframe or Shadow DOM wrapper
Ensure callback functions are defined before mounting
Check that the widget mounted successfully (no errors)
Verify the payment completed (not just initiated)
Next Steps
Get API Credentials Sign up and obtain your client key and secret
SDK Integration Use the full SDK for server-side integration
Webhooks Set up webhooks for real-time payment notifications
API Reference Complete REST API documentation