Configuration
Odus Elements is configured at two levels:
- Global — via the
ElementsConfigobject passed to theOdusElementsconstructor. - Per-element — via
MountOptionspassed toupdate()after mounting individual elements.
ElementsConfig
| Option | Type | Required | Description |
|---|---|---|---|
apiKey | string | ✅ | Your Odus publishable key |
environment | 'test' | 'live' | ✅ | API environment |
returnUrl | string | ✅ | URL to redirect to after 3DS authentication or other redirect flows |
locale | Locale | Language for all elements (auto-detected by default) | |
callbacks | Callbacks | Payment lifecycle event handlers | |
additionalPaymentMethods | AdditionalPaymentMethods | Express payment method config (e.g., Apple Pay) |
const checkout = new OdusElements({
apiKey: 'pk_test_your_publishable_key',
environment: 'test',
returnUrl: 'https://your-website.com/checkout/return',
locale: 'en',
callbacks: {
onPaymentSucceeded: (result) => console.log('Succeeded', result),
onPaymentFailed: (error) => console.error('Failed', error),
onActionRequired: (url) => {
window.location.href = url;
},
},
});
Callbacks
Handle payment lifecycle events by passing callback functions in the callbacks option.
In reactive frameworks (React, Vue, Svelte), callbacks defined at mount time capture state via closure and can become stale when dependencies change. Use setCallbacks() to update callbacks without remounting:
// React example
useEffect(() => {
checkoutRef.current?.setCallbacks({
onPaymentSucceeded: () => trackPurchase(priceId, quantity),
onPaymentFailed: (result) => logError(priceId, result),
});
}, [priceId, quantity]);
Only the callbacks you pass are replaced — omitted callbacks remain unchanged.
onPaymentSucceeded
Fires when a payment is successfully authorized. Does not fire for redirect-based flows (PayPal, 3DS).
onPaymentSucceeded: (result) => {
// result is the payment status: 'authorized'
window.location.href = '/checkout/success';
};
onPaymentFailed
Fires when a payment fails. Does not fire for redirect-based flows.
onPaymentFailed: (result) => {
// result is a user-friendly error message
console.error('Payment failed:', result);
};
onActionRequired
Fires when a payment requires a redirect (e.g., 3DS authentication, PayPal authorization).
onActionRequired: (redirectUrl) => {
window.location.href = redirectUrl;
};
Unlike Drop-in Checkout, Elements has no manualActionHandling toggle — onActionRequired always fires when a redirect is needed. Handle the URL however you like (navigate, open in a modal, etc.).
onLoadingStateChange
Fires when the loading state changes while a payment is being authorized — true when the request starts and false when it settles. Use it to show or hide your own loading indicator.
onLoadingStateChange: (isLoading) => {
if (isLoading) {
// Show loading spinner, disable the pay button
} else {
// Hide loading spinner, re-enable the pay button
}
};
Localization
Elements auto-detects the customer's browser language by default. Override this globally in ElementsConfig:
const checkout = new OdusElements({
// ...other options
locale: 'fr',
});
Supported Locales
| Code | Language |
|---|---|
en | English |
fr | French |
de | German |
es | Spanish |
it | Italian |
pl | Polish |
pt | Portuguese |
tr | Turkish |
cs | Czech |
nl | Dutch |
sk | Slovak |
Additional Payment Methods
Configure express payment methods through the additionalPaymentMethods option.
Apple Pay
const checkout = new OdusElements({
// ...other options
additionalPaymentMethods: {
applePay: {
displayName: 'My Store',
countries: ['US', 'GB'],
requiredBillingContactFields: ['postalAddress'],
requiredShippingContactFields: ['email', 'name'],
},
},
});
| Option | Type | Description |
|---|---|---|
displayName | string | Name shown in the Apple Pay payment sheet |
countries | string[] | ISO country codes where Apple Pay is available |
requiredBillingContactFields | ApplePayContactField[] | Billing fields to request (Apple docs) |
requiredShippingContactFields | ApplePayContactField[] | Shipping fields to request (Apple docs) |
ApplePayContactField values: email, name, phone, postalAddress, phoneticName
PayPal requires no additional configuration — simply mount the express.payPal element and it renders automatically after associatePayment() is called, provided the payment supports PayPal.
Per-Element Options (MountOptions)
Customize individual elements via update() after mounting:
checkout.elements.contact.email.mount('#email-container');
checkout.elements.contact.email.update({
locale: 'fr',
disabled: true,
initialValue: 'user@example.com',
});
// Limit street address to 100 characters
checkout.elements.address.street.mount('#street-container');
checkout.elements.address.street.update({ maxLength: 100 });
// Override the label and placeholder to match your existing checkout copy
checkout.elements.address.street.update({
label: 'Street Address',
placeholder: 'e.g. 123 Main St',
});
| Option | Type | Description |
|---|---|---|
locale | string | Override the global locale for this element |
disabled | boolean | Render the element in a disabled state |
initialValue | varies | Pre-fill the element (type depends on the element) |
maxLength | number | Maximum character limit for text inputs (e.g., address.street) |
label | string | Override the field label. Applies to text elements (address, cardholder, email, phone). Defaults to the localized copy |
placeholder | string | Override the field placeholder. Applies to text elements (address, cardholder, email, phone). Defaults to the localized copy |
callbacks | object | Per-element event callbacks |
Per-Element Events
Register event callbacks using on():
checkout.elements.contact.email.on('change', (data) => console.log('changed', data)).on('blur', () => console.log('blurred'));
| Event | Description |
|---|---|
change | Element value changed |
blur | Element lost focus |
focus | Element gained focus |
error | Element encountered a validation error |
ready | Element finished rendering and is interactive |