Skip to content

About configuration

Learn about how to configure PayPal payout components for Web.

Overview

The PayPal Web SDK provides configurable components for integrating PayPal and Venmo payouts into your web application. Each component offers comprehensive configuration options for styling, behaviour, and event handling.

Configuration structure

All payout components follow a consistent configuration pattern:

// Create component with configuration
const submissionComponent = pxpCheckoutSdk.create("payout-submission", {
  // Required properties
  recipientWallet: "Paypal",
  
  // Styling
  styles: {
    base: {
      backgroundColor: '#FFC438',
      color: '#09090C',
      borderRadius: '3px'
    },
    hover: {
      backgroundColor: '#F7B731'
    }
  },
  
  // Event handlers
  onPostPayout: (result) => {
    // Handle successful payout
  }
});

// Mount to DOM
submissionComponent.mount('submission-container');

Authentication and environment are configured at SDK initialisation via PxpCheckout.initialize(), not at component level.

Basic configuration

At minimum, each component requires a few essential properties:

// Payout amount component (no required config)
const amountComponent = pxpCheckoutSdk.create("payout-amount");

// PayPal receiver component (no required config)
const paypalReceiverComponent = pxpCheckoutSdk.create("paypal-payout-receiver");

// Venmo receiver component (no required config)
const venmoReceiverComponent = pxpCheckoutSdk.create("venmo-payout-receiver");

// Payout submission component
const submissionComponent = pxpCheckoutSdk.create("payout-submission", {
  recipientWallet: "Paypal"  // Required: "Paypal" or "Venmo"
});

Advanced configuration

For more complex implementations, you can configure styling, callbacks, and additional features:

const submissionComponent = pxpCheckoutSdk.create("payout-submission", {
  // Required
  recipientWallet: "Paypal",
  
  // Custom button text
  submitText: "Withdraw Funds",
  
  // Custom CSS class
  class: "custom-payout-button",
  
  // Styling for different states
  styles: {
    base: {
      backgroundColor: '#FFC438',
      color: '#09090C',
      borderRadius: '3px',
      padding: '12px 24px',
      fontSize: '16px',
      fontWeight: '500'
    },
    hover: {
      backgroundColor: '#F7B731'
    },
    active: {
      opacity: '0.6'
    },
    focus: {
      outline: '2px solid #0070CC',
      outlineOffset: '2px'
    },
    disabled: {
      opacity: '0.5',
      cursor: 'not-allowed'
    }
  },
  
  // Branding image configuration
  brandingImageConfig: {
    width: "60px",
    height: "auto"
  },
  
  // Event handlers
  onClick: (event) => {
    console.log("Button clicked");
  },
  
  onPrePayoutSubmit: async () => {
    const confirmed = await showConfirmationModal();
    return { isApproved: confirmed, note: "Customer withdrawal" };
  },
  
  onPostPayout: (result) => {
    handlePayoutSuccess(result);
  },
  
  onError: (error) => {
    handlePayoutError(error);
  }
});

Styling components

Default styling

All components come with PayPal-branded default styling:

  • Submission button (PayPal): Gold button (#FFC438) with dark text, 3px border radius.
  • Submission button (Venmo): Blue button (#008CFF) with white text.
  • Amount input: Standard input field with customisable label.
  • Receiver display: Read-only field with optional masking and toggle.

Custom styling

Each component offers comprehensive styling options using CSS properties:

// Amount component styling
const amountComponent = pxpCheckoutSdk.create("payout-amount", {
  label: "Withdrawal Amount",
  style: {
    color: "#333333",
    borderColor: "#cccccc",
    backgroundColor: "#EFEDEE"
  },
  labelStyle: {
    color: "#001BB7",
    fontWeight: "600"
  }
});

// Receiver component styling
const receiverComponent = pxpCheckoutSdk.create("paypal-payout-receiver", {
  label: "PayPal Email",
  showMaskToggle: true,
  style: {
    color: "#333333",
    borderColor: "#cccccc",
    backgroundColor: "#f5f5f5"
  },
  labelStyle: {
    color: "#001BB7"
  }
});

Button state styling

Submission buttons support styling for multiple states:

StateDescriptionDefault (PayPal)
baseDefault button appearance.Gold background, dark text.
hoverMouse hover state.Darker gold (#F7B731).
activeButton pressed.60% opacity.
focusKeyboard focus.Blue outline (2px).
disabledButton disabled.50% opacity, not-allowed cursor.
loadingDuring payout processing.(Custom per implementation).
const submissionComponent = pxpCheckoutSdk.create("payout-submission", {
  recipientWallet: "Paypal",
  styles: {
    base: {
      backgroundColor: '#FFC438',
      color: '#09090C',
      borderRadius: '8px',
      padding: '16px 32px',
      fontSize: '18px',
      fontWeight: '600',
      border: 'none',
      cursor: 'pointer'
    },
    hover: {
      backgroundColor: '#E6B032',
      transform: 'translateY(-1px)'
    },
    active: {
      opacity: '0.7',
      transform: 'translateY(0)'
    },
    focus: {
      outline: '3px solid #0070CC',
      outlineOffset: '3px'
    },
    disabled: {
      backgroundColor: '#CCCCCC',
      color: '#666666',
      cursor: 'not-allowed'
    },
    loading: {
      opacity: '0.8',
      cursor: 'wait'
    }
  }
});

Event handling

All components provide event handlers for user interactions and lifecycle events. For a full list of supported callbacks and their payloads, see Events.

Common event patterns

PatternDescriptionExample callbacks
Click handlersCalled when user clicks.onClick
Pre-action handlersCalled before processing, can approve/reject.onPrePayoutSubmit
Success handlersCalled when operations complete.onPostPayout, onAccountVerified
Error handlersCalled when errors occur.onError
Cancel handlersCalled when user cancels.onCancel

Submission component events

const submissionComponent = pxpCheckoutSdk.create("payout-submission", {
  recipientWallet: "Paypal",
  
  // Click handling (before validation)
  onClick: (event) => {
    console.log("Withdrawal button clicked");
    showLoadingState();
  },
  
  // Pre-payout approval (can approve/reject)
  onPrePayoutSubmit: async () => {
    const confirmed = await showConfirmationDialog();
    return { 
      isApproved: confirmed,
      note: "Customer withdrawal request"
    };
  },
  
  // Success handling
  onPostPayout: (result) => {
    console.log("Payout successful:", result.transactionId);
    navigateToSuccessPage(result.transactionId);
  },
  
  // Error handling
  onError: (error) => {
    console.error("Payout failed:", error.ErrorCode, error.message);
    showErrorMessage(error.message);
  }
});

Component mounting

Unlike native SDKs, web components must be mounted to DOM elements:

// Create component
const amountComponent = pxpCheckoutSdk.create("payout-amount", {
  label: "Amount"
});

// Mount to DOM element (CSS selector)
amountComponent.mount("amount-container");

// Later: unmount when done
amountComponent.unmount();

HTML structure

<div class="payout-form">
  <div id="amount-container"></div>
  <div id="receiver-container"></div>
  <div id="submit-container"></div>
</div>

React integration

import { useEffect, useRef } from 'react';

function PayoutForm({ pxpCheckout }) {
  const componentRef = useRef(null);
  
  useEffect(() => {
    if (pxpCheckout) {
      componentRef.current = pxpCheckout.create("payout-amount");
      componentRef.current.mount("amount-container");
    }
    
    return () => {
      componentRef.current?.unmount();
    };
  }, [pxpCheckout]);
  
  return <div id="amount-container" />;
}

Best practices

Configure for your brand

Customise the styling to match your application's design:

// Define brand colours
const brandColors = {
  primary: '#0066CC',
  surface: '#F8F9FA',
  onSurface: '#212529',
  accent: '#FFC438'
};

// Apply to components
const submissionComponent = pxpCheckoutSdk.create("payout-submission", {
  recipientWallet: "Paypal",
  styles: {
    base: {
      backgroundColor: brandColors.accent,
      color: brandColors.onSurface,
      fontFamily: 'Inter, sans-serif'
    }
  }
});

Handle all events

Implement comprehensive event handling:

const submissionComponent = pxpCheckoutSdk.create("payout-submission", {
  recipientWallet: "Paypal",
  onClick: (event) => handleClick(event),
  onPrePayoutSubmit: () => handlePreSubmit(),
  onPostPayout: (result) => handleSuccess(result),
  onError: (error) => handleError(error)
});

For more information about events, see Events.

Clean up components

Always unmount components when they're no longer needed:

// Store component references
const components = [];

// Create and track components
const amount = pxpCheckoutSdk.create("payout-amount");
amount.mount("amount-container");
components.push(amount);

// Clean up on page leave
window.addEventListener('beforeunload', () => {
  components.forEach(component => component.unmount());
});

Test different configurations

Test your components in various scenarios:

  • Different browsers (Chrome, Firefox, Safari, Edge).
  • Mobile and desktop viewports.
  • Various payout amounts.
  • Error conditions.
  • Network failures.

Complete configuration example

Here's a comprehensive example showing all configuration options:

import { PxpCheckout, IntentType, CurrencyType } from "@pxpio/web-components-sdk";

// Get session from your backend
const sessionData = await fetchSessionFromBackend();

// Initialise SDK
const pxpCheckoutSdk = PxpCheckout.initialize({
  environment: "test",
  session: sessionData,
  ownerId: "Unity",
  ownerType: "MerchantGroup",
  transactionData: {
    amount: 100.00,
    currency: "USD" as CurrencyType,
    entryType: "Ecom",
    intent: { paypal: IntentType.Payout },
    merchantTransactionId: crypto.randomUUID(),
    merchantTransactionDate: () => new Date().toISOString()
  },
  paypalConfig: {
    payoutConfig: {
      proceedPayoutWithSdk: true,
      paypalWallet: {
        email: "customer@example.com",
        payerId: "PAYER123456"
      }
    }
  }
});

// Create amount component with full configuration
const amountComponent = pxpCheckoutSdk.create("payout-amount", {
  label: "Withdrawal Amount",
  style: {
    color: "#333333",
    borderColor: "#0070CC",
    backgroundColor: "#FFFFFF",
    borderRadius: "4px",
    padding: "12px"
  },
  labelStyle: {
    color: "#001BB7",
    fontSize: "14px",
    fontWeight: "600"
  }
});

// Create receiver component with full configuration
const receiverComponent = pxpCheckoutSdk.create("paypal-payout-receiver", {
  label: "PayPal Email",
  showMaskToggle: true,
  applyMask: true,
  style: {
    color: "#333333",
    borderColor: "#CCCCCC",
    backgroundColor: "#F5F5F5",
    borderRadius: "4px",
    padding: "12px"
  },
  labelStyle: {
    color: "#001BB7",
    fontSize: "14px",
    fontWeight: "600"
  }
});

// Create submission component with full configuration
const submissionComponent = pxpCheckoutSdk.create("payout-submission", {
  // Required
  recipientWallet: "Paypal",
  
  // Button text
  submitText: "Withdraw to PayPal",
  
  // Custom class
  class: "payout-submit-button",
  
  // Branding
  brandingImageConfig: {
    width: "60px",
    height: "auto"
  },
  
  // Full styling
  styles: {
    base: {
      backgroundColor: '#FFC438',
      color: '#09090C',
      borderRadius: '4px',
      padding: '14px 28px',
      fontSize: '16px',
      lineHeight: '18px',
      fontWeight: '600',
      border: 'none',
      cursor: 'pointer',
      width: '100%'
    },
    hover: {
      backgroundColor: '#F7B731'
    },
    active: {
      opacity: '0.6'
    },
    focus: {
      outline: '2px solid #0070CC',
      outlineOffset: '2px'
    },
    disabled: {
      opacity: '0.5',
      cursor: 'not-allowed'
    },
    loading: {
      opacity: '0.8'
    }
  },
  
  // Event handlers
  onClick: (event) => {
    console.log("Button clicked");
    trackEvent("payout_button_clicked");
  },
  
  onPrePayoutSubmit: async () => {
    console.log("Pre-payout check");
    
    // Show confirmation modal
    const confirmed = await showConfirmationModal({
      title: "Confirm Withdrawal",
      message: "Are you sure you want to withdraw $100.00 to your PayPal account?"
    });
    
    if (!confirmed) {
      return { isApproved: false };
    }
    
    // Perform validation
    const validation = await validateWithdrawal();
    if (!validation.valid) {
      showErrorMessage(validation.message);
      return { isApproved: false };
    }
    
    return { 
      isApproved: true,
      note: "Customer withdrawal request"
    };
  },
  
  onPostPayout: (result) => {
    console.log("Payout successful:", result);
    
    // Update UI
    showSuccessMessage(`$100.00 has been sent to your PayPal account!`);
    
    // Track success
    trackEvent("payout_completed", {
      transactionId: result.transactionId,
      amount: 100.00
    });
    
    // Redirect
    setTimeout(() => {
      window.location.href = `/payout-success?txn=${result.transactionId}`;
    }, 2000);
  },
  
  onError: (error) => {
    console.error("Payout error:", error);
    
    // Log error
    logError("payout_error", {
      code: error.ErrorCode,
      message: error.message
    });
    
    // Show error message
    showErrorMessage("Withdrawal failed. Please try again.");
  }
});

// Mount components
amountComponent.mount("amount-container");
receiverComponent.mount("receiver-container");
submissionComponent.mount("submit-container");

// Clean up function
function cleanup() {
  amountComponent.unmount();
  receiverComponent.unmount();
  submissionComponent.unmount();
}

Next steps

Now that you understand component configuration fundamentals, dive into the detailed documentation for each component: