Implementation

Learn how to use Card Components in your project.

Overview

Every component follows the same basic three-step lifecycle:

  1. Create the component and optionally add your own configuration.
  2. Mount the component. This is what makes the component visible and interactive.
  3. Unmount the component. This is a clean-up step that clears up resources.

Before you start

To use Card Components, you need to install Checkout Components for Web.

Step 1: Initialise the SDK

To get started, initialise the Checkout SDK.

const pxpCheckoutSdk = PxpCheckout.initialize({
  environment: "test",
  session: sessionData,
  ownerId: "Unity",
  ownerType: "MerchantGroup",
  merchantShopperId: "Shopper_09",
  transactionData: {
    currency: "USD" as CurrencyType,
    amount: 25,
    entryType: "Ecom",
    intent: "Authorisation",
    merchantTransactionId: crypto.randomUUID(),
    merchantTransactionDate: () => new Date().toISOString(),
  },
})
PropertyDescription
environment
string
required
The environment type.

Possible values:
  • test
  • live
session
sessionData
required
Details about the checkout session.
ownerId
string
required
The identifier of the owner related to the ownerType.
ownerType
string
required
The type of owner.

Possible values:
  • MerchantGroup
  • Merchant
  • Site
merchantShopperId
string
required
A unique identifier for this shopper.
transactionData
object
required
Details about the transaction.
transactionData.currency
string (1-3 characters)
The currency code associated with the transaction, in ISO 4217 format.
transactionData.amount
number
required
The transaction amount.
transactionData.entryType
string
required
The entry type.

Possible values:
  • Ecom
  • MOTO
transactionData.intent
string
required
The transaction intent. Learn more about intents.

Possible values:
  • Authorisation
  • EstimatedAuthorisation
  • Purchase
  • Payout
  • Verification
transactionData.merchantTransactionId
string
required
A unique identifier for this transaction.
transactionData.merchantTransactionDate
string
required
The date and time of the transaction, in ISO 8601 format.

Step 2: Create a component

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');
View list of component names

Pre-built components:

  • card-on-file
  • click-once
  • billing-address
  • new-card

Standalone components:

  • card-number
  • card-expiry-date
  • card-cvc
  • card-holder-name
  • card-brand-selector
  • card-consent
  • dynamic-card-image
  • card-submit
  • country-selection
  • postcode
  • address
  • prefill-billing-address-checkbox

Step 3: Add the corresponding HTML container

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>
View list of container names

Pre-built components:

  • card-on-file-container
  • click-once-container
  • billing-address-container
  • new-card-container

Standalone components:

  • card-number-container
  • card-expiry-date-container
  • card-cvc-container
  • card-holder-name-container
  • card-brand-selector-container
  • card-consent-container
  • dynamic-card-image-container
  • card-submit-container
  • country-container
  • postcode-container
  • address-container
  • prefill-billing-address-checkbox-container

Step 4: Mount the component

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.

Step 5: Unmount the component

Lastly, remember to unmount the component when it's no longer needed.

componentName.unmount('container-name');

What's next?

Customise the look and feel

You can configure the appearance and behaviour of components to fit your brand. We've documented all configurable parameters for each component in the Customise Card Components 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' }
  }
});

Add event handling

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')
    }
  }
});

Implement analytics tracking

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);
  }
}

Add error handling

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
}

Complete example

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: '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: function(result) {
          if (result.isSuccessful) {
            trackEvent('payment_success', { amount: 1000 });
            alert('Payment successful!');
          } else {
            trackEvent('payment_failed', { error: result.error });
            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>