***
title: PayPal
subtitle: Accept PayPal payments using a popup-based authentication flow.
-------------------------------------------------------------------------
PaymentKit.js handles the PayPal flow through a secure popup window. Customers authenticate with PayPal without leaving your checkout page.
# Setup
```html
```
```typescript
import PaymentKit from '@payment-kit-js/vanilla';
import PayPalPaymentMethod from '@payment-kit-js/vanilla/payment-methods/paypal';
const paymentKit = PaymentKit({
environment: 'sandbox',
secureToken: 'aBcDeFgHiJkLmNoPqRsTuVwXyZ123456', // From your backend
paymentMethods: [PayPalPaymentMethod]
});
```
# Submit payment
Unlike card payments, PayPal doesn't need input elements. Submit directly when the customer clicks your PayPal button:
```typescript
document.getElementById('paypal-button').addEventListener('click', () => {
paymentKit.submit({
fields: {
customer_name: 'Jane Smith',
customer_email: 'jane@example.com',
customer_country: 'US',
customer_zip_code: '94102'
},
paymentMethod: 'paypal',
options: {
processorId: 'proc_paypal_abc123',
customerInfo: {
first_name: 'Jane',
last_name: 'Smith'
}
},
onSuccess: (result) => {
console.log('ID:', result.id);
console.log('Checkout Attempt ID:', result.checkoutAttemptId);
console.log('Checkout Session ID:', result.checkoutSessionId);
console.log('State:', result.state);
window.location.href = '/success';
},
onError: (errors) => {
console.error(errors);
}
});
});
```
The popup must be triggered by a direct user action (button click) to avoid being blocked by popup blockers.
# Options
| Option | Type | Required | Description |
| ------------------------- | -------- | -------- | ------------------------ |
| `processorId` | `string` | Yes | Your PayPal processor ID |
| `customerInfo.first_name` | `string` | Yes | Customer's first name |
| `customerInfo.last_name` | `string` | Yes | Customer's last name |
# Error handling
PayPal errors are returned in the `errors.paypal` field as descriptive strings:
```typescript
onError: (errors) => {
if (errors.processor_id) {
// Missing processor ID
console.error(errors.processor_id); // "Processor ID is required"
} else if (errors.customer_name) {
// Missing customer name
console.error(errors.customer_name); // "Customer first and last name are required"
} else if (errors.paypal) {
// PayPal-specific errors
if (errors.paypal.includes('popup')) {
// Popup was blocked
alert('Please allow popups for this site');
} else if (errors.paypal.includes('closed by user')) {
// Customer closed popup without completing
} else if (errors.paypal.includes('Failed to check')) {
// Status polling failed
}
console.error(errors.paypal);
}
}
```
| Error Field | Error Message | Cause |
| --------------- | ----------------------------------------------------------------- | ------------------------------------------------------------- |
| `processor_id` | `Processor ID is required` | Missing `processorId` in options |
| `customer_name` | `Customer first and last name are required` | Missing `customerInfo.first_name` or `customerInfo.last_name` |
| `paypal` | `Failed to open PayPal popup. Please allow popups for this site.` | Browser blocked the popup window |
| `paypal` | `PayPal popup closed by user` | Customer closed the popup without completing payment |
| `paypal` | `Failed to check PayPal status` | Error while polling for payment completion |
| `paypal` | `PayPal checkout cancelled` | Payment was cancelled by the customer in PayPal |
| `paypal` | `PayPal checkout failed` | Payment failed on PayPal's side |
| `paypal` | `PayPal checkout expired` | Popup session expired (1 hour timeout) |
| `paypal` | `Polling error: {error}` | Network error during status polling |
| `paypal` | `PayPal checkout error: {error}` | General checkout error |