Events
Implement callbacks to customise your payment flow.
Overview
Components emit events based on user interaction or validation. You can use these to implement callback functions, which allow you to inject your own business logic and user experience customisations into the payment flow at critical moments. They ensure that while the SDK handles the complex technical aspects of payment processing, you retain full control over the customer experience and can seamlessly integrate payments into your broader business workflows and systems.
Callbacks enable you to:
- Validate business rules before payments proceed.
- Display custom error, failure, or success messages.
- Tailor user interfaces to match your brand's look and feel.
- Integrate with your own systems for fraud detection or customer management.
- Control exactly how your customers experience both successful and failed transactions.
All events are optional and can be mixed and matched based on your business needs.
Supported events
The following tables lists all events supported by the different pre-built components.
Event | Billing address | Card-on-file | Click-once | New card |
---|---|---|---|---|
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
|
Callbacks
onBlur
This callback is triggered when the input loses focus.
const component = sdk.create('card-number', {
onBlur: (event) => {
console.log('Field blurred:', event.target.value);
}
});
onCardBrandCannotRecognised
This callback is triggered when the card number input changes, but the entered digits don't match any known card brand patterns.
const cardNumberComponent = sdk.create('card-number', {
onCardBrandCannotRecognised: (event) => {
console.log('Card brand could not be recognised');
// Handle unknown card brand scenario
}
});
onCardBrandDetected
This callback is triggered when the card number input changes and a recognised card brand (e.g., Visa, MasterCard) is detected from the input value.
const cardNumberComponent = sdk.create('card-number', {
onCardBrandDetected: (event) => {
const cardBrand = event.detail.cardBrand;
const isAccepted = event.detail.isCardBrandAccept;
console.log(`Card brand detected: ${cardBrand.brand}`, isAccepted);
}
});
onChange
This callback is triggered when the input value change in one or more fields.
const component = sdk.create('card-number', {
onChange: (event) => {
console.log('Value changed:', event.target.value);
}
});
onClick
This callback is triggered when the submit button is clicked (before processing).
const cardSubmit = sdk.create('card-submit', {
onClick: (event) => {
console.log('Submit button clicked');
}
});
onCollectEnd
This callback is triggered when data collection ends.
const cardSubmit = sdk.create('card-submit', {
onCollectEnd: (data) => {
console.log('Data collection completed:', data);
hideMessage();
}
});
onCollectStart
This callback is triggered when data collection begins.
const cardSubmit = sdk.create('card-submit', {
onCollectStart: (data) => {
console.log('Data collection started:', data);
showMessage('Collecting device information...', 'info');
}
});
onCvcEntered
This callback is triggered when a customer enters a CVC value in the click-once component's CVC field.
const clickOnceComponent = sdk.create('click-once', {
onCvcEntered: () => {
console.log('CVC has been entered');
// Enable submit button or perform validation
}
});
onDeleteTokenFailed
This callback is triggered when a card token deletion request fails, for example due to a network error.
const cardOnFileComponent = sdk.create('card-on-file', {
onDeleteTokenFailed: (data) => {
console.log('Token deletion failed:', data.error);
alert('Failed to delete card. Please try again.');
}
});
onDeleteTokenSuccess
This callback is triggered when a card token is successfully deleted from the vault.
const cardOnFileComponent = sdk.create('card-on-file', {
onDeleteTokenSuccess: (data) => {
console.log('Token deleted successfully:', data.tokenId);
// Refresh the token list or show success message
}
});
onFocus
This callback is triggered when the input receives focus.
const component = sdk.create('card-number', {
onFocus: (event) => {
console.log('Field focused');
}
});
onGetFingerPrintResult
This callback is used to retrieve fingerprint data for authentication.
const cardSubmit = sdk.create('card-submit', {
onGetFingerprintResult: async () => {
// Return fingerprint data as a string
return await getDeviceFingerprintData();
}
});
onOnceCardClick
This callback is triggered when a customer selects a saved card in the click-once component.
const clickOnceComponent = sdk.create('click-once', {
onOnceCardClick: () => {
console.log('User clicked on a saved card');
// Handle card selection logic
}
});
onPostAuthentication
This callback is triggered after 3DS authentication is completed.
const cardSubmit = sdk.create('card-submit', {
onPostAuthentication: (authResult) => {
console.log('3DS authentication completed:', authResult);
if (authResult.status === 'AUTHENTICATED') {
showMessage('Authentication successful', 'success');
}
}
});
onPostAuthorisation
This callback is triggered after a payment transaction has been processed and authorisation has been completed (successfully or unsuccessfully).
const cardSubmit = sdk.create('card-submit', {
onPostAuthorisation: (result) => {
if (result.state === 'Authorised') {
// Payment successful
alert('Payment successful!');
window.location.href = '/success';
} else {
// Payment failed
alert('Payment failed. Please try again.');
}
}
});
onPostInitiateAuthentication
This callback is triggered after 3DS authentication is initiated.
const cardSubmit = sdk.create('card-submit', {
onPostInitiateAuthentication: (authResult) => {
console.log('3DS authentication initiated:', authResult);
if (authResult.status === 'CHALLENGE_REQUIRED') {
showMessage('Please complete 3DS verification', 'info');
}
}
});
onPostTokenisation
This callback is triggered after tokenisation completes with the tokenisation result.
const cardSubmit = sdk.create('card-submit', {
onPostTokenisation: (tokenData) => {
console.log('Card tokenised:', tokenData);
}
});
onPreAuthentication
This callback is triggered before 3DS authentication starts.
const cardSubmit = sdk.create('card-submit', {
onPreAuthentication: async (preInitData) => {
console.log('Starting 3DS authentication:', preInitData);
return {
acquirerProfileId: "your-acquirer-id",
providerId: "your-provider-id",
timeout: 30
};
}
});
onPreAuthorisation
This callback is triggered before the transaction authorisation. Return the transaction data.
const cardSubmit = sdk.create('card-submit', {
onPreAuthorisation: (data) => {
console.log('Pre-authorisation data:', data);
return Promise.resolve({
addressVerification: {
countryCode: "US",
houseNumberOrName: "123 Main St",
postalCode: "12345"
}
});
}
});
onPreDeleteToken
This callback is triggered before a token deletion attempt, allowing you to show custom confirmation dialogs.
const cardOnFileComponent = sdk.create('card-on-file', {
onPreDeleteToken: async (token) => {
const confirmed = confirm(`Delete card ending in ${token.maskedPrimaryAccountNumber.slice(-4)}?`);
return confirmed; // Return true to proceed, false to cancel
}
});
onPreInitiateAuthentication
This callback is triggered before 3DS authentication. Return the authorisation data if you want to proceed with pre-initiating an authentication, null
otherwise.
const cardSubmit = sdk.create('card-submit', {
onPreInitiateAuthentication: () => {
return {
threeDSecureVersion: "2.1.0",
merchantName: "Your Store"
};
}
});
onPreTokenisation
This callback is triggered before card tokenisation. To proceed, return true
. To cancel, return false
.
const cardSubmit = sdk.create('card-submit', {
onPreTokenisation: () => {
console.log('About to tokenise card');
return true; // or false to cancel
}
});
onPreRenderTokens
This callback is triggered after tokens are retrieved but before they're rendered, allowing filtering and transformation.
const cardOnFileComponent = sdk.create('card-on-file', {
onPreRenderTokens: (data) => {
// Filter only Visa cards and mark them as requiring CVC
return data.gatewayTokens
.filter(token => token.scheme === 'Visa')
.map(token => ({
id: token.gatewayTokenId,
isCvcRequired: true
}));
}
});
onRetrieveTokensFailed
This callback is triggered when the initial request to fetch saved card tokens fails.
const cardOnFileComponent = sdk.create('card-on-file', {
onRetrieveTokensFailed: (data) => {
console.log('Failed to retrieve tokens:', data.error);
// Show fallback UI or error message
}
});
onSubmitError
This callback is triggered when submission fails.
const cardSubmit = sdk.create('card-submit', {
onSubmitError: (error) => {
console.log('Submit error:', error);
}
});
onUpdateTokenFailed
This callback is triggered when updating card token information (e.g., expiry date) fails.
const cardOnFileComponent = sdk.create('card-on-file', {
onUpdateTokenFailed: (data) => {
console.log('Token update failed:', data.error);
// Show error message to user
}
});
onUpdateTokenSuccess
This callback is triggered when card token information is successfully updated.
const cardOnFileComponent = sdk.create('card-on-file', {
onUpdateTokenSuccess: (data) => {
console.log('Token updated successfully:', data);
// Refresh display with new information
}
});
onValidation
This callback is triggered when form validation occurs.
const newCard = sdk.create('new-card', {
onValidation: (validationResults) => {
console.log('Card form validation:', validationResults);
validationResults.forEach(result => {
if (!result.valid && result.errors) {
Object.keys(result.errors).forEach(fieldName => {
const error = result.errors[fieldName];
console.log(`${fieldName}: ${error.message} (${error.code})`);
});
}
});
}
});
onValidationFailed
This callback is triggered when validation fails for a single field.
const component = sdk.create('card-number', {
onValidationFailed: (validationResults) => {
console.log('Validation failed:', validationResults);
}
});
onValidationPassed
This callback is triggered when validation is successful for a single field.
const component = sdk.create('card-number', {
onValidationPassed: (validationResults) => {
console.log('Validation passed:', validationResults);
}
});
tokenItemBuilder
This callback is called when each token item's user interface is being constructed, allowing you to customise the HTML layout.
const cardOnFileComponent = sdk.create('card-on-file', {
tokenItemBuilder: (elementIds) => {
return `
<div style="display: flex; align-items: center; padding: 10px;">
<div id="${elementIds.tokenImageId}"></div>
<div id="${elementIds.tokenLabelId}" style="flex: 1; margin: 0 10px;"></div>
<div id="${elementIds.expiryDateId}" style="margin-right: 10px;"></div>
<div id="${elementIds.editButtonId}" style="margin-right: 5px;"></div>
<div id="${elementIds.deleteButtonId}"></div>
</div>
`;
}
});
tokenLabelBuilder
This callback is called to generate the display text for each card token. It replaces the default masked card number.
const cardOnFileComponent = sdk.create('card-on-file', {
tokenLabelBuilder: (token) => {
return `${token.scheme} •••• ${token.maskedPrimaryAccountNumber.slice(-4)} - ${token.issuerName}`;
}
});
Common scenarios
Handle a declined transaction
The following snippet is an example of how you might handle a declined transaction when using the card submit component.
const cardSubmitComponent = sdk.create('card-submit', {
onPostAuthorisation: (submitResult) => {
console.log('Transaction result:', submitResult);
if (submitResult.status === 'Refused') {
// Transaction was declined by the issuer or payment provider
const refusedResult = submitResult as RefusedSubmitResult;
// Handle the declined transaction
handleDeclinedTransaction(refusedResult);
} else if (submitResult.status === 'Authorised') {
// Transaction was successful
handleSuccessfulTransaction(submitResult);
} else if (submitResult.status === 'Error') {
// System error occurred
handleSystemError(submitResult);
} else if (submitResult.status === 'Pending') {
// Transaction is pending further processing
handlePendingTransaction(submitResult);
}
}
});
function handleDeclinedTransaction(refusedResult) {
// Extract decline information
const stateData = refusedResult.stateData;
const providerResponse = refusedResult.providerResponse;
const fundingData = refusedResult.fundingData;
// Log decline details
console.log('Transaction declined:', {
stateCode: stateData?.code,
stateMessage: stateData?.message,
providerCode: providerResponse?.code,
providerMessage: providerResponse?.message,
merchantAdvice: providerResponse?.merchantAdvice
});
// Show user-friendly error message based on decline reason
const declineCode = providerResponse?.code;
let userMessage = 'Your payment was declined. Please try again or use a different payment method.';
switch (declineCode) {
case 'INSUFFICIENT_FUNDS':
userMessage = 'Your card has insufficient funds. Please try a different payment method.';
break;
case 'EXPIRED_CARD':
userMessage = 'Your card has expired. Please check your card details or use a different card.';
break;
case 'INVALID_CVV':
userMessage = 'The security code (CVV) is incorrect. Please check and try again.';
break;
case 'CARD_BLOCKED':
userMessage = 'Your card is blocked. Please contact your bank or use a different payment method.';
break;
case 'LIMIT_EXCEEDED':
userMessage = 'Transaction exceeds your card limit. Please try a smaller amount or different card.';
break;
default:
// Use merchant advice if available
if (providerResponse?.merchantAdvice?.message) {
userMessage = providerResponse.merchantAdvice.message;
}
}
// Display error to user
showErrorMessage(userMessage);
// Check if retry is recommended
if (providerResponse?.merchantAdvice?.code === 'RETRY') {
enableRetryOption();
} else if (providerResponse?.merchantAdvice?.code === 'DO_NOT_RETRY') {
disableRetryOption();
suggestAlternativePayment();
}
// Log analytics event for declined transaction
logDeclineAnalytics(declineCode, stateData?.code);
}
Handle an authentication failure
The following snippet is an example of how you might handle authentication problems when using the card submit component.
const cardSubmitComponent = sdk.create('card-submit', {
onSubmitError: (error) => {
console.log('Submit error occurred:', error);
// Handle different types of authentication and processing errors
switch (error.ErrorCode) {
case 'SDK0503': // Transaction authentication rejected
showErrorMessage('Authentication was rejected by your bank. Please try again or contact your bank.');
enableRetryOption();
break;
case 'SDK0505': // Transaction authentication failed
showErrorMessage('Authentication failed. Please try again or contact your bank for assistance.');
enableRetryOption();
break;
case 'SDK0504': // SCA exemption required
showErrorMessage('Additional authentication is required. Please complete the verification process.');
// Handle SCA exemption flow
break;
default:
// Generic error handling
showErrorMessage('Payment processing failed. Please try again.');
logError(error);
}
}
});
Updated 3 days ago