Payment fields
Compose custom checkout UIs with card, Mobile Money, wallet, address, and payment selector components.
Payment fields are UI blocks you place in your page. You keep the layout and pay button; Wajub renders secure payment inputs.
For a turnkey checkout (coupons, OTP, full shipping), use hosted checkout instead.
Style components with the same Appearance object as hosted checkout.
Quick start
<div id="card"></div>
<button id="pay" disabled>Pay</button>
<script src="https://js.wajub.com"></script>
<script>
const sessionId = 'YOUR_SESSION_TOKEN';
const factory = wajub.components(sessionId, {
locale: 'fr',
componentOrigin: 'https://shop.example.com',
appearance: { primaryColor: '#2563eb', borderRadius: '12px', labels: 'floating' },
});
const card = factory.create('card')
.on('change', (e) => { document.getElementById('pay').disabled = !e.complete; })
.on('focus', () => console.log('focused'))
.on('blur', () => console.log('blurred'))
.on('success', (txn) => console.log('paid', txn))
.on('error', (err) => console.error(err.code))
.mount('#card');
document.getElementById('pay').onclick = () =>
wajub.confirmPayment({ sessionId, components: card });
</script>Component types
| Type | Description | Pay button |
|---|---|---|
card | Card number, expiry, CVC | You + confirmPayment() |
mobileMoney | Mobile Money form | You + confirmPayment() |
wallet | Apple Pay / Google Pay | Native wallet button |
payment | Method selector + form (+ optional address) | You + confirmPayment() |
address | Shipping / billing address | N/A — use getValue() |
// Address only
factory.create('address', {
addressMode: 'shipping',
collectName: true,
fields: { phone: 'auto' },
}).mount('#address');
// Payment with inline address
factory.create('payment', {
collectAddress: 'shipping',
collectName: true,
layout: 'tabs',
}).mount('#payment');ComponentConfig options
| Option | Type | Description |
|---|---|---|
sessionId | string | Required |
locale | string | UI language |
componentOrigin | string | Canonical site origin (multi-domain) |
appearance | AppearanceConfig | Full styling — Appearance |
layout | CheckoutLayout | classic · compact · tabs · accordion |
collectAddress | shipping · billing | payment — collect address inline |
addressMode | shipping · billing | address — label mode |
collectName | boolean | Show name field on address component |
fields.phone | always · auto · never | Phone field visibility |
Factory-level options (wajub.components(sessionId, opts)) apply as defaults to every
factory.create() call.
Events
Subscribe with .on(event, handler):
| Event | Payload | Description |
|---|---|---|
ready | ComponentInstance | Mounted and interactive |
change | { complete?, empty?, error?, value? } | Field validity changed |
focus | — | Field focused |
blur | — | Field blurred |
success | transaction | Payment completed |
error | WajubError | Payment failed |
loaderror | WajubError | Component failed to load |
resize | height payload | Container resized |
statechange | { state, method? } | Checkout state transition |
methodchange | { methodId? } | Payment method changed |
component.on('change', (e) => {
console.log('complete:', e.complete, 'empty:', e.empty);
if (e.error) console.log(e.error.message);
if (e.value) console.log('address:', e.value); // address component
});change.complete ≠ paid
change.complete means fields are valid — listen for success for
a completed payment.
Instance API
| Method | Description |
|---|---|
wajub.components(sessionId, opts?) | Create factory |
factory.create(type, config?) | Create component instance |
.mount(element) | Mount to DOM |
.on(event, fn) / .off(event, fn) | Event subscription |
.update({ appearance, locale, layout }) | Live config update |
.focus() / .blur() | Field focus control |
.submit() | Submit programmatically |
.selectMethod(id) | Switch method (payment component) |
.getState() | Current checkout state |
.isComplete() | All required fields valid |
.getError() | Current error or null |
.getValue() | Address { name, phone, address, mode } |
.destroy() | Unmount and cleanup |
wajub.confirmPayment({ sessionId, components }) | Submit payment |
Framework components
React, Vue, and Svelte wrappers pass through all ComponentConfig options and call
instance.update() when appearance, locale, or layout props change.
| React prop | Description |
|---|---|
className | Wrapper class |
minHeight | Container min-height (default 480) |
onInstance | (instance) => void — ref to ComponentInstance |
Limitations
| Feature | Hosted checkout | Payment fields |
|---|---|---|
| Saved payment methods | Yes | Yes |
| Coupons | Yes | No |
| Custom fields | Yes | No |
| Full shipping flow | Yes | No |
| OTP | Yes | No — use hosted checkout |
| 3DS | Yes | Yes |
| Wallet | Yes | Yes (native button — do not call confirmPayment) |
Wallet
confirmPayment() is rejected for the wallet component — the
customer pays via the native Apple Pay / Google Pay button.