Events
Events let you track user actions and respond to changes in real-time. For server-side notifications, see Webhooks.
How to Listen
Method 1: Subscribe to Specific Events
const unsubscribe = Paystar.subscribe(
"PAYMENT-SESSION.PROCESSED",
function (data) {
console.log("Payment was processed:", data);
},
);
// Later: unsubscribe
unsubscribe();
Method 2: Handle All Events via Callback
Pass an onEvent callback when opening a session:
// For payment sessions
Paystar.completePayment(sessionUrl, {
onEvent: function ({ event, data }) {
switch (event) {
case "PAYMENT-SESSION.PROCESSED":
handlePaymentProcessed(data);
break;
case "COMPONENT.DISMISS":
handleFormClosed();
break;
}
},
});
// For other flows (AutoPay, Wallet, Paperless, Notifications)
Paystar.startFlow(sessionUrl, {
onEvent: function ({ event, data }) {
console.log("Event:", event, "Data:", data);
},
});
Event Reference
General Events
COMPONENT.DISMISS
Fires when: User dismisses the form/modal (clicks X, presses ESC, or clicks outside the modal)
Data: none
FRAME.LOADED
Fires when: The embedded iframe has finished loading and is ready
Data: none
Payment Events
PAYMENT-SESSION.LOADED
Fires when: The payment form is ready for user interaction
Data: PaymentIntentDetailDto — the full payment session object
PAYMENT-SESSION.UPDATED
Fires when: Payment session details change (e.g., user selects a payment method)
Data: PaymentIntentDetailDto — the updated payment session object
PAYMENT-SESSION.PROCESSED
Fires when: The user has submitted a payment for processing
Data: PaymentIntentDetailDto — the final payment session object:
{
sessionIdentifier: "abc123...",
status: "Succeeded" | "Failed" | "Pending",
subtotal: 150.00,
channel: "QuickPay" | "POS",
lineItems: [
{ description: "January Water Bill", price: 150.00 }
],
paymentSource: {
paymentSourceType: "CreditCard" | "ACH",
accountNumberMasked: "****1234",
nickname: "Personal Card",
},
serviceFeeCalculation: {
amount: 2.50,
},
}
AutoPay Events
AUTOPAY-SESSION.ENROLLED
Fires when: User successfully enrolls in AutoPay
Data: AutopayEnrollmentSettings
{
enrolled: true,
processingLeadTimeInDays: 5,
maximumBalanceAllowed: 500,
paymentSourceId: 123
}
AUTOPAY-SESSION.UNENROLLED
Fires when: User cancels their AutoPay enrollment
Data: none
AUTOPAY-SESSION.SCHEDULED_PAYMENT_CANCELED
Fires when: A pending scheduled AutoPay payment is canceled
Data: none
Paperless Events
PAPERLESS-SESSION.ENROLLED
Fires when: User opts into paperless billing
Data: none
PAPERLESS-SESSION.UNENROLLED
Fires when: User opts out of paperless billing
Data: none
PAPERLESS-SESSION.UPDATED
Fires when: User updates their paperless billing preferences
Data: none
Wallet Events
PAYMENT-SOURCES.ADDED
Fires when: User adds a new payment method
Data: none
PAYMENT-SOURCES.REMOVED
Fires when: User removes a payment method
Data: none
Notification Events
NOTIFICATIONS.UPDATED
Fires when: User updates their notification preferences (email/SMS)
Data: none
Complete Example
A full HTML page showing event handling for a payment flow:
<!DOCTYPE html>
<html>
<head>
<script>
!(function () {
var n = (window.Paystar = window.Paystar || []);
if (!n.x) {
((n.x = !0),
(n.m = [
"initialize",
"completePayment",
"startFlow",
"subscribe",
"destroy",
]),
(n.f = function (t) {
return function () {
var e = Array.prototype.slice.call(arguments);
(e.unshift(t), n.push(e), n);
};
}));
}
for (var o = 0; o < n.m.length; o++) {
var c = n.m[o];
n[c] = n.f(c);
}
((n.load = function (t, e) {
var a = document.createElement("script");
((a.type = "text/javascript"),
(a.async = !0),
(a.src = "https://dev.paystar.io/app/embedded.loader.js"));
var r = document.getElementsByTagName("script")[0];
(r.parentNode.insertBefore(a, r), (n._loadOptions = e));
}),
(n.SNIPPET_VERSION = "0.1.0"));
})();
Paystar.initialize();
Paystar.load();
</script>
</head>
<body>
<button id="pay-button">Pay $150</button>
<div id="status"></div>
<script>
// Subscribe to events globally
Paystar.subscribe("PAYMENT-SESSION.PROCESSED", function (data) {
document.getElementById("status").innerText =
"Payment " + data.status;
});
Paystar.subscribe("COMPONENT.DISMISS", function () {
document.getElementById("status").innerText = "Payment cancelled";
});
// Handle button click
document.getElementById("pay-button").onclick = async function () {
const response = await fetch("/api/create-payment-session", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ amount: 15000 }),
});
const { sessionUrl } = await response.json();
Paystar.completePayment(sessionUrl, {
onComplete: function (result) {
console.log("Payment result:", result);
},
});
};
</script>
</body>
</html>
Troubleshooting
- Verify
Paystar.initialize()was called (the SDK snippet does this automatically) - Check that event names are spelled correctly — they are case-sensitive
- Look for errors in the browser console
- Make sure the SDK is fully loaded before subscribing
- Check you're not subscribing multiple times (e.g., in a re-rendering component)
- Unsubscribe before re-subscribing if your setup code runs more than once
- Avoid using both
onEventandsubscribefor the same event — pick one approach