Skip to main content

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

Events Not Firing?
  • 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
Getting Duplicate Events?
  • 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 onEvent and subscribe for the same event — pick one approach