Skip to content

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

EventCallback signatureWhen it fires
ready() => voidWidget rendered and interactive
tokenize(result: TokenizationResult) => voidCard tokenized successfully
error(error: WidgetError) => voidAny error occurs
focus(field: string) => voidA field receives focus
blur(field: string) => voidA field loses focus
change(data: FieldChangeData) => voidField value or validity changes
loading(isLoading: boolean) => voidTokenization starts or ends
bin-ready(data: BinReadyData) => voidFirst 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();
});