# 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:

```typescript
// 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:

```typescript
// 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:

```typescript
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:

```typescript
// 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:

| State | Description | Default (PayPal) |
|  --- | --- | --- |
| `base` | Default button appearance. | Gold background, dark text. |
| `hover` | Mouse hover state. | Darker gold (#F7B731). |
| `active` | Button pressed. | 60% opacity. |
| `focus` | Keyboard focus. | Blue outline (2px). |
| `disabled` | Button disabled. | 50% opacity, not-allowed cursor. |
| `loading` | During payout processing. | (Custom per implementation). |


```typescript
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](/guides/checkout/components/web/paypal/payouts/events).

### Common event patterns

| Pattern | Description | Example callbacks |
|  --- | --- | --- |
| **Click handlers** | Called when user clicks. | `onClick` |
| **Pre-action handlers** | Called before processing, can approve/reject. | `onPrePayoutSubmit` |
| **Success handlers** | Called when operations complete. | `onPostPayout`, `onAccountVerified` |
| **Error handlers** | Called when errors occur. | `onError` |
| **Cancel handlers** | Called when user cancels. | `onCancel` |


### Submission component events

```typescript
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:

```typescript
// 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

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

### React integration

```tsx
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:

```typescript
// 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:

```typescript
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](/guides/checkout/components/web/paypal/payouts/events).

### Clean up components

Always unmount components when they're no longer needed:

```typescript
// 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:

```typescript
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:

- **[Amount component](/guides/checkout/components/web/paypal/payouts/amount-component):** Configure the payout amount input.
- **[PayPal receiver component](/guides/checkout/components/web/paypal/payouts/paypal-receiver-component):** Display and configure PayPal receiver.
- **[Venmo receiver component](/guides/checkout/components/web/paypal/payouts/venmo-receiver-component):** Display and configure Venmo receiver.
- **[Submission component](/guides/checkout/components/web/paypal/payouts/submission-component):** Configure the withdrawal button for returning customers.