Learn how to use card components in your project.
Every component follows the same basic three-step lifecycle:
- Create the component and optionally add your own configuration.
- Mount the component. This is what makes the component visible and interactive.
- Unmount the component. This is a clean-up step that clears up resources.
To use card components, you need to install Components for Web.
To get started, initialise the Checkout SDK.
const pxpCheckoutSdk = PxpCheckout.initialize({
environment: "test",
session: sessionData,
ownerId: "Unity",
ownerType: "MerchantGroup",
transactionData: {
currency: "USD" as CurrencyType,
amount: 25,
entryType: "Ecom",
intent: {
card: "Authorisation",
paypal: "Authorisation"
},
merchantTransactionId: crypto.randomUUID(),
merchantTransactionDate: () => new Date().toISOString(),
},
onGetShopper: () => {
// Return current shopper data dynamically
return Promise.resolve({
id: 'shopper-09',
email: 'customer@example.com',
firstName: 'John',
lastName: 'Doe',
phoneNumber: '+1-555-0123'
});
},
onGetShippingAddress: () => {
// Return current shipping address dynamically
return Promise.resolve({
address: '123 Main Street',
city: 'New York',
state: 'NY',
postalCode: '10001',
countryCode: 'US'
});
}
})| Property | Description |
|---|---|
environmentstring required | The environment type. Possible values:
|
sessionsessionData required | Details about the checkout session. |
ownerIdstring required | Your unique merchant group identifier, as assigned by PXP. You can find it in the Unity Portal, by going to Merchant setup > Merchant groups and checking the Merchant group ID column or by clicking on a site and checking the General information section. |
ownerTypestring required | The type of owner. Set this to MerchantGroup. Possible values:
|
onGetShopperfunction | Callback function to provide shopper data dynamically. Returns a Promise with shopper information including ID, email, name, and contact details. This is used for card tokenisation and transaction processing. |
onGetShippingAddressfunction | Callback function to provide shipping address data dynamically. Returns a Promise with current shipping address information. This is used when shipping information is required for the transaction. |
transactionDataobject required | Details about the transaction. |
transactionData.currencystring (1-3 characters) | The currency code associated with the transaction, in ISO 4217 format. |
transactionData.amountnumber required | The transaction amount. |
transactionData.entryTypestring required | The entry type. Possible values:
|
transactionData.intentobject required | The transaction intents for each payment method. Learn more about intents. |
transactionData.intent.cardstring | The intent for card transactions. Possible values:
|
transactionData.intent.paypalstring | The intent for PayPal transactions. Possible values:
|
transactionData.merchantTransactionIdstring required | A unique identifier for this transaction. |
transactionData.merchantTransactionDatestring required | The date and time of the transaction, in ISO 8601 format. |
Next, you're going to create a component. Use the following snippet and change component-name to the name of the component you want to add. For example, new-card for the new card component.
const component = sdk.create('component-name');To render the component, add the corresponding HTML container. Use the following snippet and change component-name to the name of the component you want to add. For example, new-card-container for the new card component.
<div id="container-name"></div>For the component to be visible and functional, you need to mount it. Use the following snippet, and replace both the component name (e.g., NewCard) and the container name (e.g., new-card-container).
componentName.mount('container-name');At this point, your component is ready to use.
Lastly, remember to unmount the component when it's no longer needed.
componentName.unmount('container-name');You can configure the appearance and behaviour of components to fit your brand. We've documented all configurable parameters for each component in the Customisation section.
const cardNumber = sdk.create('card-number', {
placeholder: 'Enter card number',
label: 'Card number',
required: true,
acceptedCardBrands: ['visa', 'mastercard', 'amex'],
styles: {
base: { fontSize: '16px', color: '#333' },
invalid: { borderColor: 'red' }
}
});Components emit events based on user interaction or validation. You can implement callback functions to handle these events and perform actions, such as display success and error messages. For more details about event handling, see the Events page.
const newCard = sdk.create('new-card', {
onChange: (state) => console.log('Component state changed'),
onValidation: (data) => console.log('Overall validation'),
fields: {
cardNumber: {
onChange: (event) => console.log('Card number changed'),
onValidationFailed: (data) => console.log('Card number invalid')
}
}
});Components automatically trigger analytics events when significant actions or states occur. You can consume these events to gather real-time insights, such as tracking payment completion times. For more details about analytics tracking, see the Analytics page.
if (analyticsEvent instanceof ClickOncePaymentCompletionTimeAnalyticsEvent) {
const completionTime = analyticsEvent.duration;
if (completionTime > 5000) { // Alert if over 5s
alertPerformanceTeam(analyticsEvent);
}
}Error handling is crucial for payment components because they deal with sensitive financial data and complex validation rules. They can happen due to issues with configuration, validation, authentication, or connectivity. For more details about error handling, see the Errors page.
try {
const component = sdk.create('new-card');
component.mount('card-container');
} catch (error) {
console.error('Failed to initialise payment component:', error);
// Show fallback UI or error message to user
}Here's a complete example of the new card component being added to a website.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Payment Example</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 50px auto;
padding: 20px;
background-color: #f5f5f5;
}
.payment-container {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
}
#new-card-container {
margin: 20px 0;
}
</style>
</head>
<body>
<div class="payment-container">
<h1>Complete your payment</h1>
<!-- The new card component will be mounted here -->
<div id="new-card-container"></div>
</div>
<!-- Link to the SDK script -->
<script src="https://your-domain.com/pxp-checkout-sdk.js"></script>
<script>
// Simple analytics function
function trackEvent(eventName, data) {
console.log('Analytics:', eventName, data);
}
// Initialise when page loads
document.addEventListener('DOMContentLoaded', function() {
// Initialise the SDK
const pxpSdk = PxpCheckout.initialize({
environment: 'sandbox',
session: {
sessionId: 'your-session-id-here',
hmacKey: 'your-hmac-key-here',
encryptionKey: 'your-encryption-key-here',
allowedFundingTypes: {
cards: ['visa', 'mastercard', 'amex']
}
},
merchantShopperId: 'shopper-123',
ownerType: 'MerchantGroup',
ownerId: 'owner-123',
transactionData: {
amount: 1000,
currency: 'USD',
entryType: 'Ecom',
intent: {
card: 'Authorisation',
paypal: 'Authorisation'
},
merchantTransactionId: 'txn-' + Date.now(),
merchantTransactionDate: () => new Date().toISOString()
}
});
// Create the new card component
const newCardComponent = pxpSdk.create('new-card', {
fields: {
cardNumber: {
required: true,
placeholder: '1234 5678 9012 3456',
inputStyles: {
base: {
border: '2px solid #ddd',
borderRadius: '6px',
padding: '12px',
fontSize: '16px'
},
focus: {
borderColor: '#4CAF50',
outline: 'none'
}
},
onCardBrandDetected: function(event) {
trackEvent('card_brand_detected', { brand: event.cardBrand });
}
},
expiryDate: {
required: true,
placeholder: 'MM/YY',
inputStyles: {
base: {
border: '2px solid #ddd',
borderRadius: '6px',
padding: '12px',
fontSize: '16px'
},
focus: {
borderColor: '#4CAF50',
outline: 'none'
}
}
},
cvc: {
required: true,
placeholder: '123',
inputStyles: {
base: {
border: '2px solid #ddd',
borderRadius: '6px',
padding: '12px',
fontSize: '16px'
},
focus: {
borderColor: '#4CAF50',
outline: 'none'
}
}
},
cardHolderName: {
required: true,
placeholder: 'John Doe',
inputStyles: {
base: {
border: '2px solid #ddd',
borderRadius: '6px',
padding: '12px',
fontSize: '16px'
},
focus: {
borderColor: '#4CAF50',
outline: 'none'
}
},
onChange: function(event) {
trackEvent('cardholder_name_changed', { length: event.target.value.length });
}
}
},
submitButton: {
text: 'Pay $10.00',
style: {
backgroundColor: '#4CAF50',
border: 'none',
padding: '15px',
borderRadius: '6px',
color: 'white',
fontSize: '16px',
fontWeight: 'bold',
cursor: 'pointer',
width: '100%',
marginTop: '10px'
},
hoverStyle: {
backgroundColor: '#45a049'
}
},
onPostAuthorisation: async function(data) {
console.log('Transaction completed');
console.log('Merchant Transaction ID:', data.merchantTransactionId);
console.log('System Transaction ID:', data.systemTransactionId);
// Get full result from backend
const result = await getAuthorisationResultFromGateway(data.merchantTransactionId, data.systemTransactionId);
if (result.state === 'Authorised' || result.state === 'Captured') {
trackEvent('payment_success', {
merchantTransactionId: data.merchantTransactionId,
amount: 1000
});
alert('Payment successful!');
} else {
trackEvent('payment_failed', {
merchantTransactionId: data.merchantTransactionId,
state: result.state
});
alert('Payment failed. Please try again.');
}
}
});
// Mount the component
newCardComponent.mount('new-card-container');
// Unmount the component when the page is being unloaded
window.addEventListener('beforeunload', function() {
newCardComponent.unmount();
});
});
</script>
</body>
</html>