Headless Checkout Changelog
Adds Adyen Apple Pay and a normalized partnerError payload. Apple Pay and PayPal initialization failures now surface instead of leaving a dead button.
partnerError payloads are normalized and no longer typed against partner SDK internals.Input in the Purse Vault card form is preserved during a session update unless the payment method configuration itself changes.
apiPaths passed to a bundle that enforces its own API URLs now log a console warning instead of being silently ignored.SDK errors and init failures — NOT_AUTHORIZED, for example — previously left the button active or froze the checkout silently.
onAmountUpdate calls no longer exhaust the session step budget and reach SESSION_MAX_STEPS_REACHED.The build target is pinned explicitly again. A dependency bump had picked up a narrower default that stopped downleveling ES2022 syntax.
Validation error keys are renamed. Favorite token management moves to a dedicated endpoint, and getPaymentElement() warns instead of crashing on secondary methods.
*CannotBeEmpty* to *Required*.low impactMigration guide
The FieldValidationErrors enum and the matching configuration fields are renamed. Deprecated cannotBeEmpty keys still resolve, but will be removed in a future major.
// Before
const config = { cardHolderNameCannotBeEmptyError: 'Cardholder name is mandatory.' };
// After
const config = { cardHolderNameRequiredError: 'Cardholder name is mandatory.' };
getPaymentElement() on a secondary method warns and returns undefined instead of throwing an opaque TypeError.Secondary methods — gift cards, vouchers — use getSecondaryToken() or take().
paymentMethod not provided.Tokens from a previous initialization are cleared. CHECKOUT_API_VALIDATION_SUCCEEDED now carries a per-partner-method statuses map.
interface CheckoutApiValidationSucceededEventPayload {
statuses: Record<string, { state: string; code?: string; description?: string }>;
}
plugin_result.logs is absent.PluginInitFailed or partnerError instead of being swallowed.save_token: false overrides any conflicting save_token_mode.formDataChanged is logged only once every field is valid, and holderName masking drops the last character; Corrected event categories for VALIDATION_SUCCESS, VALIDATION_FAILED, PAYMENT_ERROR, EXPIRED_SESSION, and CLIENT_HOOK_ERROR.Stripe Apple Pay is now available. The getPaymentElement() method is now more flexible, allowing optional method and partner parameters, and provides clearer error messages for incompatible hosted fields requests. Additionally, payment tokens now expose isFavorite, setAsFavorite(), and createdAt properties for enhanced management.
Integrators can now offer Apple Pay via Stripe. The button height is automatically clamped to Stripe's supported range of 40-55px as per Stripe's constraints.
getPaymentElement() method now features significantly improved resolution logic and optional parameters.The method and partner parameters are now optional for getPaymentElement():
- When
methodis omitted, the SDK automatically selects the first hosted fields-compatible primary method ifhostedFieldsis requested, or the first primary method in the session otherwise. - When
partneris omitted, the SDK uses the first primary method matching the given method name across all partners. A warning is emitted if multiple partners expose the same method. - Requesting
hostedFieldsfor an incompatible payment method will now throw aMETHOD_DOES_NOT_SUPPORT_HOSTED_FIELDSerror instead of silently failing.
isFavorite and a setAsFavorite() method.The PurseHeadlessCheckoutPrimaryToken type now includes:
interface PurseHeadlessCheckoutPrimaryToken {
isFavorite: Readable<boolean>;
setAsFavorite(): Promise<void>;
// ... other properties
}
Integrators can use these to display and manage a buyer's preferred tokens.
supportsHostedFields boolean property.The PurseHeadlessCheckoutPrimaryMethod and PurseHeadlessCheckoutPrimaryToken types now include:
interface PurseHeadlessCheckoutPrimaryMethod {
supportsHostedFields: boolean;
// ... other properties
}
interface PurseHeadlessCheckoutPrimaryToken {
supportsHostedFields: boolean;
// ... other properties
}
This property indicates whether the method or token is compatible with hosted fields.
createdAt timestamp.The PaymentToken type now includes a createdAt: string property, allowing integrators to sort or display tokens by their creation date.
When the Ingenico API returns incomplete data during initialization, the widgets now gracefully fall back to default payment networks (e.g., Mastercard/Visa) and continue to function, preventing a complete checkout blockage.
This fix ensures that payment methods declaring hosted fields support in their plugin are correctly identified, even when the session vault doesn't explicitly state hosted-fields support.
xPayButton) are now correctly forwarded by getPaymentElement().Integrators can now use the xPayButton property in PurseHeadlessCheckoutGetPaymentElementOptions to customise the appearance of Apple Pay and Google Pay buttons.
checkout.getPaymentElement({
partner: 'adyen',
method: 'googlepay',
xPayButton: {
google: {
buttonColor: 'black',
buttonType: 'buy'
}
}
});
This ensures that if your backend defines a custom template for a payment method, the generic plugin will be used even if a partner-specific plugin exists for that method.
methodSelected and methodUnselected removed from PaymentElementEventName. For payment methods that open a modal (Apple Pay, Google Pay, Lyra), replace with modalIn and modalOut.// Before
element.on('methodSelected', handler)
// After
element.on('modalIn', handler)
additionalAssets: PurseHeadlessCheckoutPaymentItemBase now exposes additionalAssets: CardSchemeAsset[] — one entry per supported card scheme (URL + label). iconUrl is still present.// method.additionalAssets: Array<{ url: string; label: string }>
method.additionalAssets // [{ url: 'https://...', label: 'Visa' }, ...]
hideHolderName: New option in HostedFieldsOptions to hide the cardholder name field.method.setOptions({
hostedForm: { hideHolderName: true },
});
disableMaxWidth: New option to override the button's default max-width constraint.method.setOptions({
xPayButton: { paypal: { disableMaxWidth: true } },
});
getElementInstance() internally, fixing silent skips when rendering via getHostedFields().item.name instead of the masked card number.This release enhances the reliability of Google Pay payments for our Ingenico/Worldline merchants by correcting configuration defaults, preventing silent tokenization failures. Additionally, we've fixed an issue ensuring that payment tokens saved in the wallet display their correct names.
name field for saved payment tokens and ensures the editTokenName API path is correct.We've added new capabilities for a smoother payment experience and enhanced developer tooling. Buyers can now customize their PayPal button appearance, while developers benefit from a streamlined way to create PaymentElement instances and readily access payment method icons.
The new disableMaxWidth option can be passed in XPayButtonUIOptions['paypal'] to prevent the PayPal button from expanding to its container's full width.
interface XPayButtonUIOptions {
paypal?: {
disableMaxWidth?: boolean;
// ... other PayPal button options
};
}
// Example usage:
checkout.getPaymentElement({
partner: 'paypal',
method: 'paypal',
paypal: {
disableMaxWidth: true,
},
});
PaymentElement directly from the checkout instance.A new shortcut method, checkout.getPaymentElement(), simplifies the creation and rendering of a single payment method's UI.
// Before: More verbose for a single method
// const checkout = new PurseHeadlessCheckout(...);
// const paymentMethods = await checkout.getPaymentMethods();
// const specificMethod = paymentMethods.find(
// (pm) => pm.partner === 'ingenico' && pm.method === 'creditcard'
// );
// if (specificMethod) {
// const el = specificMethod.getPaymentElement({ theme: {} });
// el.appendTo('#container');
// }
// After: Simplified approach
const el = checkout.getPaymentElement({
partner: 'ingenico',
method: 'creditcard',
theme: { /* ... */ },
hostedForm: { /* ... */ },
hostedFields: { /* ... */ },
});
el.on('ready', () => console.log('PaymentElement is ready.'));
el.appendTo('#container');
iconUrl.Integrators can now easily display official icons for payment methods and secondary tokens by accessing the new iconUrl property.
interface PaymentMethod {
// ... existing properties
iconUrl: string | null;
}
interface BuiltSecondaryToken {
// ... existing properties
iconUrl: string | null;
}
// Example usage:
const paymentMethods = await checkout.getPaymentMethods();
paymentMethods.forEach((method) => {
if (method.iconUrl) {
console.log(`Icon for ${method.name}: ${method.iconUrl}`);
}
});
Dedicated mappers ensure accurate data extraction for secondary tokens, including those from partners like Illicado, Easy2play giftcard, Mybeezbox, and Ogloba. This includes migrating from deprecated payment_data.card to payment_data.cards[0] for card-based secondary tokens.
currencyCode has been removed from BuiltSecondaryToken, PurseHeadlessCheckoutSecondaryToken, and PartialSecondaryToken types. Integrators should now retrieve the currency directly from the payment session, which serves as the single source of truth.
widget_data when available.This release expands payment options by introducing Apple Pay and Google Pay for Sogecommerce, PayPal BNPL, and Younited Installments. We've also enhanced Oney card support to correctly collect birthdates for private cards and added a noCVV mode for more flexible card form integrations.
This prevents 'ghost sessions' with Alma when buyers close the popup prematurely, ensuring session consistency between Purse and Alma.
For Oney private cards, the card form dynamically adapts to collect the buyer's birthdate instead of the CVV. This ensures accurate data collection for Oney payments.
noCVV mode for card forms.Integrators can now configure the card form to optionally collect the CVV by setting the noCVV flag on PaymentElement initialization. This allows for use cases where CVV collection is not always required for specific card brands or payment flows.
const paymentElement = purse.initPaymentElement({
// ... other config
card: {
noCVV: true, // CVV field becomes optional
},
});
Payment methods compatible with OFF_SESSION registrations are now correctly displayed and activated, allowing for payments even with zero-amount initial requests.
onBeforeValidate hook.This resolves an issue where the CVV field could be duplicated or misbehave when quickly switching between a saved card token form and a new card entry form, especially on slow networks (SDK-11545).
SCREAMING_SNAKE_CASE.This prevents unknown plugins from occupying slots in xPay displays when a template is not properly configured (SDK-11514).