User GuidePayment
PayPal Configuration
Configure PayPal Payment
PayPal is a globally recognized payment platform supporting both one-time payments and subscriptions.
Setup Steps
- Visit PayPal Developer
- Create application and get Client ID / Client Secret
- Configure Webhook in Developer Dashboard
- Record Webhook ID for environment variables
Environment Variables
# PayPal Configuration
PAYPAL_CLIENT_ID="AYxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
PAYPAL_CLIENT_SECRET="ELxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
PAYPAL_WEBHOOK_ID="WH-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
PAYPAL_SANDBOX="true" # Set to "false" for productionOne-time vs Subscription
One-time Payment (Orders + Capture)
- No need to create Product / Plan in PayPal Dashboard
- Suitable for lifetime access, one-time purchases
Subscription Payment
- Requires creating Product and Plan in PayPal Dashboard
- Developer Dashboard → Products & Services → Subscriptions
- Create Product → Create Plan
- Record Plan ID and configure in
config/payment.tsaspaypalPlanId - Subscription status verified via Webhook or active query
Sandbox Testing
PayPal provides a Sandbox environment for development testing.
Enable Sandbox
-
Set environment variable:
PAYPAL_SANDBOX=true -
Sandbox API:
https://api-m.sandbox.paypal.com -
Sandbox Accounts
- Create Sandbox buyer/seller accounts in Developer Dashboard
- Use Sandbox buyer account to complete payment tests
Webhook Note: Sandbox and Production webhooks are completely isolated. You must configure Webhook under Sandbox App. Sandbox webhook events may have delays (seconds to tens of seconds).
Switch to Production
- Set
PAYPAL_SANDBOX=false - Use production Client ID / Client Secret
- Reconfigure Webhook under production App
Webhook Events
Recommended events to monitor (covering one-time payments and subscription lifecycle):
| Event | Description |
|---|---|
PAYMENT.CAPTURE.COMPLETED | Payment captured successfully |
PAYMENT.CAPTURE.DENIED | Payment capture denied |
PAYMENT.CAPTURE.REFUNDED | Payment refunded |
BILLING.SUBSCRIPTION.ACTIVATED | Subscription activated |
BILLING.SUBSCRIPTION.UPDATED | Subscription updated |
BILLING.SUBSCRIPTION.CANCELLED | Subscription cancelled |
BILLING.SUBSCRIPTION.EXPIRED | Subscription expired |
BILLING.SUBSCRIPTION.SUSPENDED | Subscription suspended |
PAYMENT.SALE.COMPLETED | Sale completed |
Plan Configuration Examples
Subscription Plan
monthlyPaypal: {
provider: 'paypal',
id: 'monthlyPaypal',
amount: 10,
currency: 'USD',
duration: {
months: 1,
type: 'recurring'
},
paypalPlanId: 'P-XXXXXXXXXX', // Plan ID created in PayPal Dashboard
i18n: {
'en': {
name: 'PayPal Monthly Plan',
description: 'Monthly recurring subscription via PayPal',
duration: 'month',
features: ['All premium features', 'Priority support']
},
'zh-CN': {
name: 'PayPal 月度订阅',
description: '通过 PayPal 的月度循环订阅',
duration: '月',
features: ['所有高级功能', '优先支持']
}
}
}One-time Payment (Lifetime)
lifetimePaypal: {
provider: 'paypal',
id: 'lifetimePaypal',
amount: 199,
currency: 'USD',
duration: {
months: 9999,
type: 'one_time'
},
i18n: {
'en': {
name: 'Lifetime (PayPal)',
description: 'One-time payment, lifetime access',
duration: 'lifetime',
features: ['All premium features', 'Priority support', 'Free lifetime updates']
},
'zh-CN': {
name: '终身会员 (PayPal)',
description: '一次付费,永久使用',
duration: '终身',
features: ['所有高级功能', '优先支持', '终身免费更新']
}
}
}Payment Flow
One-time Payment (Orders + Capture)
User selects plan → Create order → Redirect to PayPal authorization →
Callback /api/payment/return/paypal → Server capture →
Update order/subscription → Redirect to success pageSubscription Payment
User selects subscription → Create subscription → Redirect to PayPal authorization →
Callback /api/payment/return/paypal?subscription=true →
Active query subscription status (ACTIVE) → Update subscription → Success pageWebhook serves as eventual consistency (handling delays/cancellations/refunds/renewals).
Important Notes
- PayPal supports multi-currency (USD, EUR, GBP, etc.)
- Supports both one-time payment and subscription
- Subscription requires Plan ID created in PayPal Dashboard
- Callback URL must use HTTPS
- Sandbox and Production environments are completely isolated
- Webhook events may have delays in Sandbox environment
Back to Payment Configuration Overview