Skip to content

Events & 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 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
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
};
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
};
type FieldChangeData = {
value: string; // Current field value (masked for card number)
isValid: boolean;
error?: string; // Validation error message if invalid
};

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.

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();
});