Setup
- Environment variables
- Direct config
How it works
In PayPal, an Order is both the checkout and the payment.createCheckout and createPayment both create a PayPal order with intent: CAPTURE. The customer approves the order via PayPal’s UI (redirect or JS SDK), then you capture it with capturePayment(orderId).
PAYPAL_WEBHOOK_SECRET is the Webhook ID from your PayPal dashboard — not a signing secret. PayPal verifies webhooks server-side by calling its own verification API using headers sent with the request.
PayPal does not support standalone customer management.
createCustomer,
updateCustomer, deleteCustomer, and retrieveCustomer all throw
ProviderNotSupportedError. Use payer information within orders instead.Webhooks
Enable these events in your PayPal dashboard:CHECKOUT.ORDER.APPROVEDCHECKOUT.ORDER.COMPLETEDPAYMENT.CAPTURE.COMPLETEDPAYMENT.CAPTURE.REFUNDEDBILLING.SUBSCRIPTION.CREATEDBILLING.SUBSCRIPTION.UPDATEDBILLING.SUBSCRIPTION.ACTIVATEDBILLING.SUBSCRIPTION.SUSPENDEDBILLING.SUBSCRIPTION.CANCELLEDBILLING.SUBSCRIPTION.EXPIRED
Raw PayPal events
Opt into any native PayPal event — typed against the full PayPal event catalog:| PayPal event | PayKit event emitted |
|---|---|
paypal.CHECKOUT.ORDER.APPROVED | payment.created |
paypal.CHECKOUT.ORDER.COMPLETED | payment.succeeded |
paypal.PAYMENT.CAPTURE.COMPLETED | payment.succeeded |
paypal.PAYMENT.CAPTURE.REFUNDED | refund.created |
paypal.BILLING.SUBSCRIPTION.CREATED | subscription.created |
paypal.BILLING.SUBSCRIPTION.UPDATED | subscription.updated |
paypal.BILLING.SUBSCRIPTION.ACTIVATED | subscription.updated |
paypal.BILLING.SUBSCRIPTION.SUSPENDED | subscription.updated |
paypal.BILLING.SUBSCRIPTION.CANCELLED | subscription.canceled |
paypal.BILLING.SUBSCRIPTION.EXPIRED | subscription.canceled |
paypal.PAYMENT.AUTHORIZATION.CREATED | (raw only) |
paypal.PAYMENT.AUTHORIZATION.VOIDED | (raw only) |
paypal.PAYMENT.CAPTURE.DECLINED | (raw only) |
paypal.PAYMENT.CAPTURE.PENDING | (raw only) |
paypal.PAYMENT.CAPTURE.REVERSED | (raw only) |
paypal.PAYMENT.REFUND.PENDING | (raw only) |
paypal.PAYMENT.REFUND.FAILED | (raw only) |
paypal.BILLING.SUBSCRIPTION.PAYMENT.FAILED | (raw only) |
paypal.CUSTOMER.DISPUTE.CREATED | (raw only) |
paypal.CUSTOMER.DISPUTE.RESOLVED | (raw only) |
paypal.CUSTOMER.DISPUTE.UPDATED | (raw only) |
provider_metadata
createCheckout requires currency, amount, and itemName in provider_metadata because PayPal orders need explicit line-item data: