@waffo/payment-sdk
v1.1.1
Published
Waffo Payment SDK for secure card tokenization and iframe rendering
Downloads
215
Readme
Waffo Payment SDK
A comprehensive payment SDK for web applications, featuring:
- 🔐 Card Tokenization - Secure card data tokenization with 3DS verification support
- 🖼️ Iframe Embedding - Embed customizable payment checkout pages with real-time theme updates
- 🍎 Apple Pay Support - Seamless Apple Pay integration within iframe
- 🎨 Theme Customization - Dynamic theme switching with merchant logo support
📦 Installation
npm install @waffo/payment-sdk
# or
pnpm add @waffo/payment-sdk🚀 Usage
1. Tokenization (Card Tokenization)
import WaffoSDK from '@waffo/payment-sdk';
// Initialize SDK
const sdk = new WaffoSDK('your-client-api-key', {
env: 'prod', // 'prod' | 'testing' | 'sandbox'
locale: 'en' // Optional, default 'en'
});
// Submit tokenization request
const result = await sdk.tokenizationSubmit('token-session-id', {
tokenDataVerification: false, // Optional, validate card data, default false
tokenData: {
pan: '4111111111111111', // Card number
name: 'John Doe', // Cardholder name
expiry: '12/2025', // Expiry date MM/YYYY
cvv: '123' // CVV (optional)
},
billingAddress: { // Optional
countryCode: 'USA',
region: 'CA',
city: 'San Francisco',
postalCode: '94102',
address: '123 Main St'
}
});
// Handle result
if (result.success) {
console.log('Token Request ID:', result.data.tokenRequestId);
if (result.data.validateUrl) {
// 3DS verification required
window.location.href = result.data.validateUrl;
}
} else {
console.error('Error:', result.error.code, result.error.message);
}
// Destroy SDK (cleanup resources)
sdk.destroy();2. RenderIframe (Embed Payment Checkout)
The renderIframe function allows you to embed the Waffo payment checkout page in your merchant page, similar to Stripe SDK's iframe embedding functionality.
Basic Usage
import WaffoSDK from '@waffo/payment-sdk';
// Render payment iframe
const payment = WaffoSDK.renderIframe({
// Required parameters
url: 'https://cashier.waffo.com/orderKey', // Payment page URL
container: '#payment-container', // Container selector or DOM element
// Optional: Theme customization
appearance: {
// Merchant logo URL (optional)
logoUrl: 'https://example.com/logo.png',
// Theme variables (optional)
variables: {
colorPrimary: '#0570de', // Primary color
colorBackground: '#ffffff', // Background color
colorCard: '#f8f9fa', // Card background color
colorText: '#30313d', // Text color
colorTextSecondary: '#6b7280', // Secondary text color
colorTextTertiary: '#9ca3af', // Tertiary text color
colorDanger: '#d93025', // Error/danger color
colorInfo: '#e3f2fd', // Info background color
fontSizeBase: '16px', // Base font size
borderRadius: '8px', // Border radius
},
},
// Optional: iframe styles
style: {
width: '100%',
height: '600px',
border: 'none',
borderRadius: '8px',
},
});
// Unmount iframe
payment.unmount();Dynamic Theme Update
You can dynamically update the theme and logo after the iframe is rendered, without reloading the iframe:
import WaffoSDK from '@waffo/payment-sdk';
// Render iframe with initial theme
const payment = WaffoSDK.renderIframe({
url: 'https://cashier.waffo.com/orderKey',
container: '#payment-container',
appearance: {
logoUrl: 'https://example.com/logo.png',
variables: {
colorPrimary: '#0570de',
colorBackground: '#ffffff',
},
},
});
// Later, update theme dynamically (e.g., user switches to dark mode)
// Note: Always include logoUrl when updating theme to preserve the logo
await payment.updateAppearance({
logoUrl: 'https://example.com/logo.png', // Keep the logo
variables: {
colorPrimary: '#5b8ef3',
colorBackground: '#1a1a1a',
colorCard: '#2a2a2a',
colorText: '#ffffff',
colorTextSecondary: '#b0b0b0',
},
});
// The iframe theme will update in real-time without page refresh!Real-time Theme Preview Example
// Example: Color picker with real-time preview
const colorInput = document.getElementById('primary-color');
let updateTimeout;
colorInput.addEventListener('input', (e) => {
// Debounce updates
clearTimeout(updateTimeout);
updateTimeout = setTimeout(async () => {
await payment.updateAppearance({
variables: {
colorPrimary: e.target.value,
},
});
}, 300);
});Key Features
✅ Theme Customization: Customize payment page styles via appearance parameter
✅ Merchant Logo: Display custom merchant logo via logoUrl
✅ Dynamic Updates: Update theme and logo in real-time without reloading iframe
✅ Apple Pay Support: Automatically handles Apple Pay communication in iframe
✅ On-Demand Loading: Apple Pay SDK loads only when needed, no performance impact
✅ Secure Sandbox: iframe uses secure sandbox and allow attributes
✅ Flexible Styling: Support custom iframe width, height, border, etc.
Complete Example
<!DOCTYPE html>
<html>
<head>
<title>Waffo Payment</title>
<style>
#payment-container {
max-width: 600px;
margin: 50px auto;
padding: 20px;
}
.theme-selector {
margin-bottom: 20px;
display: flex;
gap: 10px;
}
.theme-btn {
padding: 10px 20px;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: 500;
}
</style>
</head>
<body>
<!-- Theme selector buttons -->
<div class="theme-selector">
<button class="theme-btn" id="light-theme">Light Theme</button>
<button class="theme-btn" id="dark-theme">Dark Theme</button>
</div>
<div id="payment-container"></div>
<script type="module">
import WaffoSDK from '@waffo/payment-sdk';
// Render iframe
const payment = WaffoSDK.renderIframe({
url: 'https://cashier.waffo.com/order123',
container: '#payment-container',
appearance: {
variables: {
colorPrimary: '#0570de',
colorBackground: '#ffffff',
},
},
});
// Light theme switch
document.getElementById('light-theme').addEventListener('click', async () => {
await payment.updateAppearance({
variables: {
colorPrimary: '#0570de',
colorBackground: '#ffffff',
colorCard: '#f8f9fa',
colorText: '#30313d',
},
});
});
// Dark theme switch
document.getElementById('dark-theme').addEventListener('click', async () => {
await payment.updateAppearance({
variables: {
colorPrimary: '#5b8ef3',
colorBackground: '#1a1a1a',
colorCard: '#2a2a2a',
colorText: '#ffffff',
},
});
});
</script>
</body>
</html>📖 API Reference
new WaffoSDK(clientApiKey, options)
Create an SDK instance.
Parameters:
clientApiKey(string): Client API keyoptions(object):env(string): Environment, values:'prod'|'testing'|'sandbox'locale(string): Language code, e.g.'en','ja','zh'(optional, default'en')
Returns: WaffoSDK instance
sdk.tokenizationSubmit(tokenSessionId, request)
Submit card tokenization request.
Parameters:
tokenSessionId(string): Token session IDrequest(object):tokenDataVerification(boolean): Validate card data (optional, defaultfalse)tokenData(object): Card datapan(string): Card numbername(string): Cardholder nameexpiry(string): Expiry date, formatMM/YYYYcvv(string): CVV security code (optional)
billingAddress(object): Billing address (optional)countryCode(string): Country code (ISO 3166-1 alpha-3)region(string): State/Province/Regioncity(string): CitypostalCode(string): Postal codeaddress(string): Street address
Returns: Promise<TokenizationResult>
Success Response:
{
success: true,
data: {
tokenRequestId: string,
validateUrl?: string // If 3DS verification is required
}
}Error Response:
{
success: false,
data: null,
error: {
code: string,
message: string
}
}Error Codes:
| Error Code | Description |
|------------|-------------|
| 011001P001 | Wrong parameters. |
| 011001P002 | Idempotent param mismatch error. |
| 011001B004 | Invalid expiry date format. |
| 011001B005 | The card has been expired. |
| 011001B006 | The card's BIN has been denied. |
| 011001B024 | The token session has expired. |
| 011001B025 | Card information is invalid. - pan, name, expiry are required |
| 011001B027 | The token session is invalid. |
| 011001B031 | The merchant contract not matched. |
| 011001S001 | System process failed. |
sdk.destroy()
Destroy SDK instance and cleanup resources.
Parameters: None
Returns: void
WaffoSDK.renderIframe(options)
Render payment checkout page in an iframe.
Parameters:
options(object): RenderIframe configurationurl(string, required): Payment page URLcontainer(string | HTMLElement, required): Container selector or DOM elementappearance(object, optional): Theme customizationlogoUrl(string, optional): Merchant logo URLvariables(object, optional): Theme variablescolorPrimary(string): Primary colorcolorBackground(string): Background colorcolorCard(string): Card background colorcolorText(string): Text colorcolorTextSecondary(string): Secondary text colorcolorTextTertiary(string): Tertiary text colorcolorDanger(string): Error/danger colorcolorInfo(string): Info background colorfontSizeBase(string): Base font sizeborderRadius(string): Border radius
style(object, optional): Iframe CSS styleswidth(string): Width, default'100%'height(string): Height, default'600px'border(string): Border, default'none'borderRadius(string): Border radius, default'0px'[key: string](string): Other CSS properties
Returns: PaymentInstance
PaymentInstance Methods:
unmount(): Unmount and cleanup iframegetIframe(): Get iframe DOM elementupdateAppearance(appearance): Dynamically update theme and logo without reloading iframe
Example:
const payment = WaffoSDK.renderIframe({
url: 'https://cashier.waffo.com/order123',
container: '#payment-container',
appearance: {
logoUrl: 'https://example.com/logo.png',
variables: {
colorPrimary: '#0570de',
colorCard: '#ffffff',
},
},
});
// Update theme and logo dynamically
await payment.updateAppearance({
logoUrl: 'https://example.com/logo.png',
variables: {
colorPrimary: '#00a86b',
},
});
// Clean up
payment.unmount();payment.updateAppearance(appearance)
Dynamically update the iframe theme and logo without reloading the page.
Parameters:
appearance(object): Theme configurationlogoUrl(string, optional): Merchant logo URLvariables(object, optional): Theme variables (same asrenderIframe)
Returns: Promise<void>
Example:
// Initial render
const payment = WaffoSDK.renderIframe({
url: 'https://cashier.waffo.com/order123',
container: '#payment-container',
appearance: {
logoUrl: 'https://example.com/logo.png',
variables: {
colorPrimary: '#0570de',
},
},
});
// Update to dark theme (include logoUrl to preserve the logo)
await payment.updateAppearance({
logoUrl: 'https://example.com/logo.png',
variables: {
colorPrimary: '#5b8ef3',
colorBackground: '#1a1a1a',
colorCard: '#2a2a2a',
colorText: '#ffffff',
},
});
// Update only the logo
await payment.updateAppearance({
logoUrl: 'https://example.com/new-logo.png',
});
// Update only colors (include logoUrl to preserve the logo)
await payment.updateAppearance({
logoUrl: 'https://example.com/logo.png',
variables: {
colorPrimary: '#00a86b',
},
});Important: When calling updateAppearance, always include logoUrl if you want to preserve the merchant logo. If logoUrl is omitted, the logo may be hidden after the theme update.
Benefits:
- ✅ Real-time theme and logo updates without page reload
- ✅ Smooth user experience
- ✅ Preserves user input data
- ✅ Reduces network requests
- ✅ Perfect for theme switchers and color pickers
📄 License
MIT © Waffo
