Learn how to configure the click-once component.
At minimum, the click-once component can be created with default settings to display saved card tokens and enable quick payments:
import PxpCheckout from '@pxp-io/web-components-sdk';
const pxpCheckout = PxpCheckout.initialize({
session: {
sessionId: 'your-session-id',
hmacKey: 'your-hmac-key',
encryptionKey: 'your-encryption-key'
},
environment: 'production',
transactionData: {
amount: 1000,
currency: 'USD',
entryType: 'Ecom',
intent: {
card: 'Authorisation'
},
merchantTransactionId: 'unique-transaction-id',
merchantTransactionDate: () => new Date().toISOString()
},
kountDisabled: false, // OPTIONAL: Set to true to disable Kount fraud detection
ownerType: 'MerchantGroup',
ownerId: 'your-owner-id'
});
// Create click-once component
const clickOnceComponent = pxpCheckout.create('click-once', {});
// Mount component
clickOnceComponent.mount('click-once-container');For more complex implementations, you can configure filtering, sorting, nested components, and event handlers:
// Create nested CVC component
const cardCvc = pxpCheckout.create('card-cvc', {
label: "Security code",
required: true
});
// Create click-once with advanced configuration
const clickOnceComponent = pxpCheckout.create('click-once', {
// Token management
limitTokens: 5,
filterBy: {
excludeExpiredTokens: true,
schemes: ["Visa", "Mastercard"],
fundingSource: "Credit"
},
orderBy: {
lastUsageDate: {
direction: "desc",
orderByField: "lastSuccessfulPurchaseDate",
priority: 1
}
},
// CVC requirement
isCvcRequired: true,
cvcComponentConfig: {
required: true,
label: "Security Code",
applyMask: true,
showMaskToggle: true
},
// Submit configuration
cardSubmitComponentConfig: {
submitText: "Pay {amount} {currency}",
onPreAuthorisation: async (data) => {
return { psd2Data: {} };
},
onPostAuthorisation: (result) => {
console.log('Payment completed:', result.merchantTransactionId);
window.location.href = '/success';
}
},
// Event handlers
onRetrieveTokensFailed: (error) => {
console.error('Failed to retrieve tokens:', error);
showErrorMessage('Unable to load saved cards. Please try again.');
}
});
clickOnceComponent.mount('click-once-container');const clickOnceConfig: ClickOnceComponentConfig = {
limitTokens: number,
filterBy: {
excludeExpiredTokens: boolean,
schemes: string[],
fundingSource: string,
issuerCountryCode: string,
ownerType: string
},
orderBy: {
expiryDate: string,
scheme: string,
fundingSource: string,
ownerType: string,
issuerCountryCode: string,
lastUsageDate: {
orderByField: string
}
},
cardBrandImages: {
visaSrc: string,
mastercardSrc: string,
amexSrc: string,
cupSrc: string,
dinersSrc: string,
discoverSrc: string,
jcbSrc: string
},
isCvcRequired: boolean,
cvcComponentConfig: CardCvcComponentConfig,
cardSubmitComponentConfig: CardSubmitComponentConfig,
hideCardBrandLogo: boolean,
submitButtonText: string,
disableCardSelection: boolean,
isRenderLastPurchaseCard: boolean,
isRenderLastPayoutCard: boolean,
class: string,
selectTokenItemClass: string,
useTransparentCardBrandImage: boolean,
selectCardButtonAriaLabel: string,
label: string,
labelAriaLabel: string,
submitAriaLabel: string,
cardNumberAriaLabel: string,
cardExpiryDateAriaLabel: string,
transactionInitiatorType: TransactionInitiatorType,
externalTokenId: string
}| Parameter | Description |
|---|---|
limitTokensnumber | The maximum number of tokens to display in the component. |
filterByobject | Details about the filtering options. |
filterBy.excludeExpiredTokensboolean | Whether to exclude tokens associated with expired cards. |
filterBy.schemesstring [] | The list of card schemes to include. For example, [Visa, Mastercard]. |
filterBy.fundingSourcestring | The funding source type to include. For example Credit or Debit. |
filterBy.issuerCountryCodestring | The issuer country code to include. |
filterBy.ownerTypestring | The owner type to include. |
orderByobject | Details about the ordering options. |
orderBy.expiryDateobject | Details for ordering by expiry date. |
orderBy.expiryDate.directionstring | The direction to order by. Possible values:
|
orderBy.expiryDate.prioritynumber | The priority of the ordering option. |
orderBy.schemeobject | Details for ordering by card scheme. |
orderBy.scheme.valuesOrderstring | The card scheme. |
orderBy.scheme.prioritynumber | The priority of the ordering option. |
orderBy.fundingSourceobject | Details for ordering by funding source. |
orderBy.fundingSource.valuesOrderstring | The funding source. Possible values:
|
orderBy.fundingSource.prioritynumber | The priority of the ordering option. |
orderBy.ownerTypeobject | Details for ordering by owner type. |
orderBy.ownerType.valuesOrderstring | The owner type. Possible values:
|
orderBy.ownerType.prioritynumber | The priority of the ordering option. |
orderBy.issuerCountryCodeobject | Details for ordering by issuer country code. |
orderBy.issuerCountryCode.directionstring | The direction to order by. Possible values:
|
orderBy.lastUsageDateobject | Details for ordering by last usage date. |
orderBy.lastUsageDate.directionstring | The direction to order by. Possible values:
|
cardBrandImagesobject | Details about the card brand images. |
cardBrandImages.visastring | The URL for the Visa card brand image. |
cardBrandImages.mastercardstring | The URL for the Mastercard card brand image. |
cardBrandImages.amexstring | The URL for the Amex card brand image. |
cardBrandImages.cupstring | The URL for the CUP card brand image. |
cardBrandImages.dinersstring | The URL for the Diners card brand image. |
cardBrandImages.discoverstring | The URL for the Discover card brand image. |
cardBrandImages.jcbstring | The URL for the JCB card brand image. |
isCvcRequiredboolean | Whether CVC is required. |
cvcComponentConfigCardCvcComponentConfig | Details about the configuration for the card CVC component. See Card CVC. |
cardSubmitComponentConfigCardSubmitComponentConfig | Details about the configuration for the card submit component. See Card submit. |
hideCardBrandLogoboolean | Whether to hide the card brand logo. |
submitButtonTextstring | The text for the submit button. |
disableCardSelectionboolean | Whether to disable card selection. |
isRenderLastPurchaseCardboolean | Whether to render the last card that was used for a purchase. |
isRenderLastPayoutCardboolean | Whether to display cards previously used for successful payouts. When true, cards with a lastSuccessfulPayoutDate will be shown even if they haven't been used for purchases. Recommended for payout flows (IntentType.Payout) to show recipients their familiar payout cards. Defaults to true. |
classstring | The class name for the component. |
selectTokenItemClassstring | The class name for the select token item in the select token list. |
useTransparentCardBrandImageboolean | Whether to use transparent card brand images. Defaults to true. |
selectCardButtonAriaLabelstring | The aria label for the select card button. |
labelstring | The label for the click-once component. |
labelAriaLabelstring | The aria label for the click-once component. |
submitAriaLabelstring | The aria label for the submit button. |
cardNumberAriaLabelstring | The aria label for the card number. |
cardExpiryDateAriaLabelstring | The aria label for the card expiry date. |
transactionInitiatorTypeTransactionInitiatorType | The transaction initiator type. Determines whether the transaction is customer-initiated (CIT) or merchant-initiated (MIT). |
externalTokenIdstring | External token identifier. Use this to specify a specific token to display when you have the token ID from an external system. |
The cardSubmitComponentConfig property accepts all card submit component configurations, including the onCustomValidation callback for validating merchant-owned fields alongside SDK component validation. See Card submit for all available submit configuration options.
Payout support: The click-once component supports card payouts (also called disbursements or withdrawals) where funds are sent from your merchant account to a cardholder's card. This is commonly used for:
- Marketplace seller payments
- Insurance claim settlements
- Refunds and reimbursements
- Competition prizes and rewards
When using intent: { card: IntentType.Payout }, configure isRenderLastPayoutCard: true to display cards previously used for successful payouts, providing a familiar payout experience for returning recipients.
const clickOnceConfig: ClickOnceComponentConfig = {
onCvcEntered: () => void,
onOnceCardClick: () => void,
onPreRenderTokens: (data: RetrieveCardTokensReponseSuccess) => CardTokenMapping[],
onRetrieveTokensFailed: (error: BaseSdkException | RetrieveCardTokensReponseFailed | RetrieveCardTokenDetailsResponseFailed) => void,
buttonBuilder: (elementIds: ClickOnceButtonBuilderElementIds) => string,
selectTokenItemBuilder: (elementIds: ClickOnceSelectTokenBuilderElementIds) => string
};| Callback | Description |
|---|---|
onCvcEntered: () => void | Event handler for when a card verification code is entered. |
onOnceCardClick: () => void | Event handler for when a card is clicked. |
onPreRenderTokens: (data: RetrieveCardTokensReponseSuccess) => CardTokenMapping[] | Callback to order or filter tokens before rendering. Receives the successful response from the token retrieval API and returns an array of transformed card token objects ready for display. |
onRetrieveTokensFailed: (error: BaseSdkException | RetrieveCardTokensReponseFailed | RetrieveCardTokenDetailsResponseFailed) => void | Event handler for when token retrieval fails. Receives error details for handling and displaying appropriate error messages. |
buttonBuilder: (elementIds: ClickOnceButtonBuilderElementIds) => string | Callback to build custom token item layout. Receives element IDs and returns an HTML string containing elements with those IDs for custom rendering. |
selectTokenItemBuilder: (elementIds: ClickOnceSelectTokenBuilderElementIds) => string | Callback to build custom token label. Receives element IDs for the token and returns custom HTML for displaying the token selection item. |
For more information about callbacks, see Events.
A complete implementation with filtering, sorting, and integrated payment handling:
const clickOnceConfig: ClickOnceComponentConfig = {
limitTokens: 5,
filterBy: {
excludeExpiredTokens: true,
schemes: ["Visa", "Mastercard"],
fundingSource: "Credit",
issuerCountryCode: "USA",
ownerType: "Consumer"
},
orderBy: {
expiryDate: {
direction: "asc",
priority: 1
},
scheme: {
valuesOrder: ["Visa", "Mastercard", "Amex"],
priority: 2
},
fundingSource: {
valuesOrder: ["Credit", "Debit"],
priority: 3
},
ownerType: {
valuesOrder: ["Consumer", "Commercial"],
priority: 4
},
issuerCountryCode: {
direction: "desc",
priority: 5
},
lastUsageDate: {
direction: "desc",
orderByField: "lastSuccessfulPurchaseDate",
priority: 6
}
},
cardBrandImages: {
visaSrc: "https://example.com/visa.png",
mastercardSrc: "https://example.com/mastercard.png",
amexSrc: "https://example.com/amex.png",
cupSrc: "https://example.com/cup.png",
dinersSrc: "https://example.com/diners.png",
discoverSrc: "https://example.com/discover.png",
jcbSrc: "https://example.com/jcb.png",
},
isCvcRequired: true,
cvcComponentConfig: {
required: true,
label: "Security Code",
applyMask: true,
showMaskToggle: true,
labelPosition: "left",
errorMessage: "Please enter a valid security code",
inputStyles: {
base: {
color: "#333",
fontSize: "16px"
}
}
},
cardSubmitComponentConfig: {
submitText: "Pay {amount} {currency}",
avsRequest: true,
billingAddressComponents: {
billingAddressComponent: billingAddress
},
// Validate merchant fields alongside SDK billing address
onCustomValidation: async () => {
let isValid = true;
const email = document.getElementById('email').value;
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!email || !emailRegex.test(email)) {
showFieldError('email', 'Please enter a valid email address');
isValid = false;
}
const termsAccepted = document.getElementById('terms-checkbox').checked;
if (!termsAccepted) {
showFieldError('terms', 'You must accept the terms and conditions');
isValid = false;
}
return isValid;
},
onPreAuthorisation: async (data) => {
return { psd2Data: {} };
},
onPostAuthorisation: (result) => {
console.log('Payment completed:', result.merchantTransactionId);
window.location.href = '/success';
}
},
hideCardBrandLogo: false,
submitButtonText: "Pay now",
disableCardSelection: false,
isRenderLastPurchaseCard: true,
isRenderLastPayoutCard: true,
transactionInitiatorType: TransactionInitiatorType.CIT,
externalTokenId: "ext_token_123456789",
onCvcEntered: () => {
console.log('CVC has been entered');
},
onOnceCardClick: () => {
console.log('Card was clicked');
},
onPreRenderTokens: (data) => {
// Filter to only show tokens from USA issuers
return data.gatewayTokens
.filter((token) => token.issuerCountryCode === 'USA')
.map((token) => ({
id: token.gatewayTokenId,
isCvcRequired: true
}));
},
onRetrieveTokensFailed: (error) => {
console.error('Failed to retrieve tokens:', error);
showErrorMessage('Unable to load saved cards. Please try again.');
},
buttonBuilder: (elementIds) => {
return `
<div class="custom-token-layout">
<div id="${elementIds.tokenImageId}" class="token-image"></div>
<div id="${elementIds.tokenLabelId}" class="token-label"></div>
<div id="${elementIds.cvcComponentId}" class="cvc-input"></div>
<div id="${elementIds.payNowId}" class="pay-button"></div>
</div>
`;
},
selectTokenItemBuilder: (elementIds) => {
return `
<div class="custom-select-token">
<div id="${elementIds.tokenImageId}" class="card-brand-image"></div>
<div id="${elementIds.cardNumberId}" class="card-number"></div>
<div id="${elementIds.expiryDateId}" class="expiry-date"></div>
</div>
`;
}
};Use the click-once component to send funds to a cardholder's card (common for marketplace payouts, refunds, or prize disbursements):
const pxpCheckout = PxpCheckout.initialize({
session: {
sessionId: 'your-session-id',
hmacKey: 'your-hmac-key',
encryptionKey: 'your-encryption-key'
},
environment: 'production',
transactionData: {
amount: 150.00,
currency: 'USD',
entryType: 'Ecom',
intent: {
card: IntentType.Payout // Critical: Set to Payout for disbursements
},
merchantTransactionId: 'payout-' + Date.now(),
merchantTransactionDate: () => new Date().toISOString()
},
kountDisabled: false, // OPTIONAL: Set to true to disable Kount fraud detection
ownerType: 'MerchantGroup',
ownerId: 'your-owner-id'
});
const clickOnceConfig: ClickOnceComponentConfig = {
limitTokens: 5,
// Enable payout-specific features
isRenderLastPayoutCard: true, // Show cards used for previous payouts
isRenderLastPurchaseCard: false, // Optionally hide purchase-only cards
// Sort by most recent payout activity
orderBy: {
lastUsageDate: {
direction: "desc",
orderByField: "lastSuccessfulPayoutDate",
priority: 1
}
},
submitButtonText: "Send funds",
cardSubmitComponentConfig: {
submitText: "Withdraw {amount} {currency}",
onPreAuthorisation: async (data) => {
return {
riskScreeningData: {
performRiskScreening: true,
userIp: "192.168.1.100",
account: {
id: "recipient_12345",
creationDateTime: "2024-01-15T10:30:00.000Z"
},
fulfillments: [{
type: "Shipped",
recipientPerson: {
phoneNumber: "+1234567890"
}
}]
}
};
},
onPostAuthorisation: (result) => {
console.log('Payout completed:', result.merchantTransactionId);
window.location.href = '/payout-confirmation';
}
},
onRetrieveTokensFailed: (error) => {
console.error('Failed to load payout cards:', error);
showErrorMessage('Unable to load saved cards. Please try again.');
}
};
const clickOnceComponent = pxpCheckout.create('click-once', clickOnceConfig);
clickOnceComponent.mount('click-once-container');When using IntentType.Payout, funds move from your merchant account to the cardholder's card. Ensure you have sufficient balance in your account and use appropriate messaging ("withdraw", "receive", "send to your card"). Note that not all cards support payouts.