Skip to content

Events & fee quotes

The component dispatches plain CustomEvents that bubble across the shadow boundary — listen on the element (or anywhere above it). Full payload shapes are in the events reference.

const payment = document.querySelector('govifi-payment');
payment.addEventListener('payment.success', (e) => {
const { sessionId, transactionId, paymentUid, last4, cardType, totalAmount } = e.detail;
// `paymentUid` (P-…) is the canonical PaymentApi payment id — record/verify against it
// rather than the incidental processor `transactionId`.
// Show your receipt UI. Fulfill via webhook, not here.
});
payment.addEventListener('payment.error', (e) => {
const { code, message, recoverable } = e.detail;
// recoverable=true → the customer can retry (e.g. card_declined)
});
payment.addEventListener('session.expired', () => {
// Create a fresh session server-side and re-render.
});

Error codes are stable and finite: card_declined, expired_card, incorrect_cvc, insufficient_funds, processing_error, network_error, session_expired, validation_error.

Once the customer’s payment details are complete, the component tokenizes them and the API quotes the convenience fee from the actual instrument — the same token used to confirm, so the quoted fee always equals the charged fee.

Apple Pay is the exception: there is no instrument until the wallet sheet runs (which happens only after the customer has seen the total), so its fee is an amount-based estimate quoted from a representative card of the same brand. The component still emits feequote for apple_pay so the total reflects the fee before the sheet opens.

The component then emits feequote:

payment.addEventListener('feequote', (e) => {
const { amount, convenienceFee, totalAmount, method } = e.detail; // minor units
renderSummary({ amount, convenienceFee, totalAmount });
});

This is the single source of truth for fees — the same engine that charges the fee produces the quote. If your page renders its own order summary (layout="embedded" with show-fee-line="false"), drive it from this event rather than computing fees yourself.

EventFires when
session.readySession config loaded; component is interactive
method.changedCustomer picked a method or saved card
feequoteFee quoted from the entered (tokenized) details
validationField validity changed ({ valid, errors })
payment.processingSubmit pressed, request in flight
payment.success / payment.errorTerminal result
session.expiredSession hit its expiry
challengeA verification step is required (see below)
walletDeletedCustomer removed a saved method (management mode)

High-risk payments may require verification — a captcha, or an SMS/email code. The component renders the challenge UI itself and emits challenge so your page can react (e.g. pause a countdown). No integration work is required beyond not hiding the component mid-challenge.