Skip to content

Implementation

Learn how to use the PayPal component 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 the PayPal component, you first need to:

Step 1: Initialise the SDK

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: "Create",
    merchantTransactionId: crypto.randomUUID(),
    merchantTransactionDate: () => new Date().toISOString(),
  },
  onGetShopper: () => {
    return Promise.resolve({
      id: 'Shopper_01',
      email: 'customer@example.com',
      firstName: 'John',
      lastName: 'Doe'
    });
  },
  onGetShippingAddress: () => {
    return Promise.resolve({
      address: '123 Main Street',
      city: 'New York',
      state: 'NY',
      postalCode: '10001',
      countryCode: 'US'
    });
  }
})
PropertyDescription
environment
string
required
The environment type.

Possible values:
  • test: For sandbox.
  • live: For production.
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 Coming soon
  • Site Coming soon
onGetShopper
function
Callback function to provide shopper data dynamically. Returns a Promise with shopper information.
onGetShippingAddress
function
Callback function to provide shipping address data dynamically. Returns a Promise with shipping address information.
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.

Possible values:
  • Create
  • Confirm
  • Capture
  • Void
  • Refund
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 the component configuration

Next, you're going to create the component configuration.

const paypalConfig = {
  payeeEmailAddress: 'merchant@example.com',
  paymentDescription: 'Order #12345',
  shippingPreference: 'NO_SHIPPING',
  userAction: 'PAY_NOW',
  renderType: 'standalone',
  fundingSources: 'paypal'
  }
};
ParameterDescription
payeeEmailAddress
string (≤ 254 characters)
required
Your email address.
paymentDescription
string
required
A description of the payment.
shippingPreference
string
required
The shipping details to use.

Possible values:
  • NO_SHIPPING: No shipping address required.
  • GET_FROM_FILE: Get shipping address from PayPal account.
  • SET_PROVIDED_ADDRESS: Use provided shipping address.
userAction
string
required
The next step in the payment flow.

Possible values:
  • PAY_NOW: Immediate payment capture.
  • CONTINUE: Continue to PayPal for payment.
renderType
string
required
The type of button to render.

Possible values:
  • standalone: A single button. Choose this when there is only one payment method.
  • setOfButtons: Multiple buttons. Choose this when there are multiple payment methods.
fundingSources
string or array of string
required
The payment method(s) to support. If the renderType is standalone, it must be a string. If it's setOfButtons, then it must be an array of strings.

Possible values:
  • paypal: Standard PayPal payments.
  • venmo: Venmo payments.
  • paylater: PayPal Pay Later financing.
shippingAddress
object
Details about the shipping address. You should provide this only when the shippingPreference is SET_PROVIDED_ADDRESS.
shippingAddress.addressLine1
string (≤ 300 characters)
required
The first line of the shipping address.
shippingAddress.addressLine2
string (≤ 300 characters)
The second line of the shipping address.
shippingAddress.city
string
required
The city of the shipping address.
shippingAddress.postalCode
string (≤ 60 characters)
required
The postal or ZIP code of the shipping address.
shippingAddress.state
string
The state or province of the shipping address.
shippingAddress.recipientName
string
The name of the recipient.
shippingAddress.countryCode
string (2 characters)
required
The country code of the shipping address, in ISO-3166-1 alpha-2 format.
shippingOptions
array of objects
Details about the shipping options. You should provide this only when the shippingPreference is GET_FROM_FILE.
shippingOptions.id
string (≤ 127 characters)
required
The unique identifier for the shipping option.
shippingOptions.label
string (≤ 127 characters)
required
The display name for the shipping option.
shippingOptions.selected
boolean
required
Whether this shipping option is selected.
shippingOptions.amounts
object
Details about the shipping option's pricing.
shippingOptions.amounts.currencyCode
string
The currency code.
shippingOptions.amounts.shipping
string
The shipping cost.
shippingOptions.type
string (enum)
required
The shipping type.

Possible values:
  • Shipping
  • Pickup
  • PickupInStore
  • PickupInPerson

Step 3: Add the HTML container

To render the component, add the HTML container.

<div id="paypal-button-container"></div>

Step 4: Mount the component

For the component to be visible and functional, you need to mount it. Make sure to supply both the component name and the container name.

const paypalButton = paymentSDK.create('paypal-button', paypalConfig);
paypalButton.mount('paypal-button-container');

At this point, your component is ready to use.

Step 5: Handle the payment result

In order to complete the payment flow, you need to implement basic event handling.

const paypalConfig = {
  // ... previous config
  onApprove: async (data, actions) => {
    try {
      // Process the approved payment
      const result = await processPayment(data.orderID);
      
      if (result.success) {
        // Redirect to success page or show confirmation
        window.location.href = '/payment-success';
      } else {
        // Handle processing failure
        showErrorMessage('Payment processing failed');
      }
    } catch (error) {
      console.error('Payment processing error:', error);
      showErrorMessage('Payment failed. Please try again.');
    }
  },
  
  onError: (error) => {
    // Handle payment errors
    console.error('Payment error:', error);
    showErrorMessage('Payment failed. Please try again.');
  },
  
  onCancel: (data) => {
    // Handle payment cancellation
    console.log('Payment cancelled by user');
    // Optionally redirect or display a message
  }
};

Step 6: Unmount the component

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

paypalButton.unmount();

What's next?

Customise the look and feel

You can configure the appearance and behaviour of the PayPal component to fit your brand. We've documented all configurable parameters in the Customisation page.

const paypalConfig = {
  renderType: 'standalone',
  payeeEmailAddress: 'merchant@example.com',
  paymentDescription: 'Premium Subscription',
  shippingPreference: 'NO_SHIPPING',
  userAction: 'PAY_NOW',
  fundingSources: 'paypal',
  locale: 'en-US',
  style: {
    layout: 'horizontal',
    color: 'blue',
    shape: 'pill',
    label: 'buynow',
    height: 45,
    borderRadius: 4
  },
  queryParams: {
    buyerCountry: 'US',
    debug: false
  }
};

Add more event handling

The PayPal component emits events based on user interaction or validation. As seen in the steps above, you can implement callback functions to handle these events and perform actions, such as display success and error messages. For more information about all the available events, see the Events page.

const paypalConfig = {
  onShippingAddressChange: (data, actions) => {
    console.log('Shipping address changed:', data);
    // Validate and potentially reject
    if (invalidAddress) {
      return actions.reject();
    }
  }
};

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 paypalConfig = {
    renderType: 'standalone',
    payeeEmailAddress: 'merchant@example.com',
    paymentDescription: 'Order #12345',
    shippingPreference: 'NO_SHIPPING',
    userAction: 'PAY_NOW',
    fundingSources: 'paypal'
  };

  const paypalComponent = sdk.create('paypal-button', paypalConfig);
  paypalComponent.mount('paypal-button-container');
  
} catch (error) {
  console.error('Failed to initialise PayPal payment component:', error);
  // Show fallback UI or error message to user
  document.getElementById('paypal-button-container').innerHTML = 
    '<p>Payment system temporarily unavailable. Please try again later.</p>';
}

Subscribe to webhooks

To get real-time updates about PayPal transactions, you can subscribe to the PayPal webhooks.

Complete example

Here's a complete example of the PayPal 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 PayPal 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;
    }

    #paypal-button-container {
      margin: 20px 0;
    }
  </style>
</head>
<body>
  <div class="payment-container">
    <h1>Complete your payment</h1>
    
    <!-- The PayPal button component will be mounted here -->
    <div id="paypal-button-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'
        },
        ownerType: 'MerchantGroup',
        ownerId: 'owner-123',
        transactionData: {
          amount: 1000,
          currency: 'USD',
          entryType: 'Ecom',
          intent: 'Create',
          merchantTransactionId: 'txn-' + Date.now(),
          merchantTransactionDate: () => new Date().toISOString()
        },
        onGetShopper: () => {
          // Return current shopper data - this could come from your app state, form, or API
          return Promise.resolve({
            id: 'shopper-123',
            email: 'customer@example.com',
            firstName: 'John',
            lastName: 'Doe',
            phoneNumber: '+1-555-0123'
          });
        },
        onGetShippingAddress: () => {
          // Return current shipping address - this could come from checkout form
          return Promise.resolve({
            address: '123 Main Street',
            city: 'New York',
            state: 'NY',
            postalCode: '10001',
            countryCode: 'US'
          });
        }
      });

      // Create the PayPal button component
      const paypalComponent = pxpSdk.create('paypal-button', {
        renderType: 'standalone',
        payeeEmailAddress: 'merchant@example.com',
        paymentDescription: 'Order #12345',
        shippingPreference: 'NO_SHIPPING',
        userAction: 'PAY_NOW',
        fundingSources: 'paypal',
        style: {
          layout: 'vertical',
          color: 'gold',
          shape: 'rect',
          label: 'paypal',
          height: 45
        },
        onApprove: function(data) {
          trackEvent('paypal_payment_approved', { orderId: data.orderID });
          alert('Payment successful!');
        },
        onCancel: function(data) {
          trackEvent('paypal_payment_cancelled', { orderId: data.orderID });
          console.log('Payment cancelled');
        },
        onError: function(error) {
          trackEvent('paypal_payment_error', { error: error.message });
          alert('Payment failed. Please try again.');
        }
      });

      // Mount the component
      paypalComponent.mount('paypal-button-container');

      // Unmount the component when the page is being unloaded
      window.addEventListener('beforeunload', function() {
        paypalComponent.unmount();
      });
    });
  </script>
</body>
</html>