How Primer Events Work
Primer Checkout components dispatchCustomEvent objects. Every Primer event is created with bubbles: true and composed: true, which means events propagate up through shadow DOM boundaries and can be caught at any ancestor element, including document. This design gives you two choices for where to listen, covered in the next section.
Choosing Where to Listen
The first decision in any integration is where to attach your event listeners. Both options receive the same events - the difference is scope and architecture fit.- Component Level
- Document Level
Attach listeners directly to the Choose this when:
<primer-checkout> element. Each listener is scoped to a single checkout instance.- Your page renders more than one checkout (e.g. a multi-cart experience) and each needs independent handling.
- You want to co-locate event logic with the component that owns it, such as inside a framework component’s lifecycle hook.
- You need to tear down listeners cleanly when a checkout is removed from the DOM.
Ensuring the Component Exists
When using component-level listeners, make sure the element is in the DOM before attaching them. If your checkout renders dynamically (through a router transition, a conditional template, or lazy loading), the element may not exist at script-execution time.useEffect, Vue’s onMounted, etc.), prefer that over DOMContentLoaded.
Phase 1: Initialization
Every Primer Checkout integration begins with theprimer:ready event. This event fires once, after the SDK has fully initialized, and it delivers the PrimerJS instance as event.detail. You need this instance to register payment callbacks, pre-fill form fields, and call SDK methods so primer:ready is the correct place to do all of that setup.
Why Not Use the DOM Events for Payment Outcomes?
Primer provides both DOM events (primer:payment-success, primer:payment-failure) and PrimerJS callbacks (onPaymentSuccess, onPaymentFailure) for payment outcomes. They carry the same data. The difference is in intent:
- PrimerJS callbacks are the primary integration point. Use them for the actions that must happen after a payment (redirect to confirmation, server-side order fulfillment, retry logic).
- DOM events are the observability layer. Use them for side effects that shouldn’t block or alter the primary flow (analytics, logging, monitoring dashboards).
primer:ready and optionally add DOM event listeners for analytics.
Phase 2: Payment Method Discovery
Shortly after initialization, the SDK dispatchesprimer:methods-update with the list of payment methods available for the current session. This event fires once on load and may fire again if the session changes (e.g. after calling primer.refreshSession() in response to a cart update).
You should use this event when you want to build a custom payment method selector, conditionally render UI based on what’s available, or route users to a specific method.
<primer-payment-method> elements dynamically. The Headless Vault Guide covers that pattern in detail.
Phase 3: User Interaction
As the user fills in card details, the SDK emits events that let you respond to their input in real time.Showing the Card Network
primer:card-network-change fires as the user types their card number. It tells you which card network (Visa, Mastercard, etc.) has been detected so far, and whether detection is still in progress. Use it to display the correct card brand logo or to adjust UI (for example, hiding an Amex-only surcharge notice when the detected network changes).
Triggering Submission from a Custom Button
If you’re using your own “Pay” button instead of the built-in one, dispatchprimer:card-submit to tell the SDK to validate and submit the card form.
primer:vault-submit in the same way. See the Events Reference and Triggerable Events for the full list of events you can dispatch.
Phase 4: Payment Processing and Outcome
Once the user submits, the SDK moves through a processing → outcome sequence. Theprimer:state-change event fires at every step, giving you a single stream to drive your UI state.
State Change vs. Outcome Events
primer:state-change fires multiple times during a single payment. The outcome events (primer:payment-success, primer:payment-failure) fire exactly once at the end. Use primer:state-change for continuous UI updates (spinners, button states, progress indicators). Use the outcome events or PrimerJS callbacks for final actions (redirects, confirmations, server notifications).
Intercepting Payments with onPaymentPrepare
Sometimes you need to run a check after the user clicks “Pay” but before the payment is created like for example, confirming terms-of-service acceptance, validating inventory, or applying a last-second promotion code. TheonPaymentPrepare callback gives you that interception point.
Working with Vaulted Payment Methods
If your integration supports saved (vaulted) payment methods, two additional events become relevant:primer:vault:methods-update- fires when vaulted payment methods are loaded or when the vault state changes. Use it to render saved cards, show a “Pay with saved card” section, or determine whether CVV re-entry is required.primer:vault:selection-change- fires when the user selects or deselects a saved method. Use it to enable or disable your submit button, or to toggle between “pay with saved card” and “pay with new card” views.
primer.vault.createCvvInput(), primer.vault.startPayment(), and primer.vault.delete() see the Headless Vault Guide.
Event Flow Overview
The following diagram shows the typical sequence of events in a successful card payment, from initialization through confirmation.Debugging Tips
- Events not firing? Confirm the
<primer-checkout>element is in the DOM before you add listeners. In SPAs, race conditions between route rendering and listener attachment are the most common cause. - Shadow DOM boundary issues? Triggerable events (
primer:card-submit,primer:vault-submit) must be dispatched withbubbles: trueandcomposed: trueor they won’t reach the internal form component. - Stale data after a cart change? Call
primer.refreshSession()to sync the client-side SDK with your server session. The SDK will re-dispatchprimer:methods-updatewith the updated method list.
See Also
Events & Callbacks Reference
Every event name, payload type, callback signature, and instance method
Recipes
Use-case driven examples for common integration scenarios
Core Concepts
Event-driven architecture and the Primer component model
Error Handling
Deep dive into error handling, retries, and failure recovery