Events & Callbacks
Registering callbacks
Pass callbacks in the constructor config:
const widget = new ElasticPayCardWidget("card-widget", { apiUrl: "https://staging-api.elasticpay.co", publishableKey: "pk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", clientSecret: "pi_0abc123_secret_xyz987", onReady: () => console.log("Widget ready"), onTokenize: (result) => console.log("Token:", result.id), onError: (error) => console.error("Error:", error.message),});Or use the .on() method after initialization:
widget.on("tokenize", (result) => { console.log("Token:", result.id);});
widget.on("error", (error) => { showError(error.message);});Event reference
| Event | Callback signature | When it fires |
|---|---|---|
ready | () => void | Widget rendered and interactive |
tokenize | (result: TokenizationResult) => void | Card tokenized successfully |
error | (error: WidgetError) => void | Any error occurs |
focus | (field: string) => void | A field receives focus |
blur | (field: string) => void | A field loses focus |
change | (data: FieldChangeData) => void | Field value or validity changes |
loading | (isLoading: boolean) => void | Tokenization starts or ends |
bin-ready | (data: BinReadyData) => void | First 8 digits entered — card brand identified |
TokenizationResult
type TokenizationResult = { id: string; // "pm_0xyz789abc123..." type: string; // "card" last4: string; // "1111" bin8: string; // "41111111" expMonth: number; // 12 expYear: number; // 2026 brand: string; // "visa" used: boolean; // true after the token has been consumed once expiresAt: string; // ISO 8601 token expiry};WidgetError
type WidgetError = { type: "validation" | "network" | "tokenization" | "unknown"; code: string; // Machine-readable error code message: string; // Human-readable message field?: string; // Which field caused the error, if applicable};FieldChangeData
type FieldChangeData = { value: string; // Current field value (masked for card number) isValid: boolean; error?: string; // Validation error message if invalid};BinReadyData
The bin-ready event fires after the first 8 digits are entered, giving you the card brand before tokenization:
type BinReadyData = { bin: string; // "41111111" brand: string; // "visa" | "mastercard" | "amex" | "discover" | "diners" | "jcb"};Use this to show fee previews or card brand logos before the customer submits.
Full event wiring example
const widget = new ElasticPayCardWidget("card-widget", { apiUrl: "https://staging-api.elasticpay.co", publishableKey: "pk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", clientSecret: clientSecret, showSubmitButton: false,});
widget.on("ready", () => { document.getElementById("pay-button")!.removeAttribute("disabled");});
widget.on("bin-ready", ({ brand }) => { document.getElementById("card-brand-icon")!.setAttribute("src", `/icons/${brand}.svg`);});
widget.on("loading", (isLoading) => { document.getElementById("pay-button")!.textContent = isLoading ? "Processing..." : "Pay";});
widget.on("tokenize", async (result) => { const response = await fetch("/api/confirm-payment", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ paymentMethodId: result.id }), }); const data = await response.json(); if (data.status === "succeeded") { window.location.href = "/payment/success"; }});
widget.on("error", (error) => { document.getElementById("error-message")!.textContent = error.message;});
document.getElementById("pay-button")?.addEventListener("click", () => { widget.tokenize();});