Overview
Receives and processes webhook events from PayPal for subscription lifecycle management. This endpoint handles subscription activations, payment completions, payment failures, and cancellations.Endpoint
Authentication
Webhook requests are authenticated using PayPal’s signature verification mechanism. The endpoint validates:- PayPal transmission ID
- Transmission timestamp
- Transmission signature
- Certificate URL
- Authentication algorithm
Webhook Event Types
The endpoint handles the following PayPal webhook events:BILLING.SUBSCRIPTION.ACTIVATED
Triggered when a subscription becomes active after user approval. Payload:- Finds user by
paypalSubscriptionId - Activates subscription using
subscriptionService.activateSubscription() - Detects plan from PayPal plan ID
- Updates user record with subscription status and billing dates
- Enables white-label features
PAYMENT.SALE.COMPLETED
Triggered when a recurring payment is successfully processed. Payload:- Resets billing cycle dates
- Sets subscription status to
active - Creates payment record in database
- Updates
billingCycleStartandbillingCycleEnd
BILLING.SUBSCRIPTION.PAYMENT.FAILED
Triggered when a subscription payment fails. Payload:- Updates subscription status to
past_due - User retains access temporarily
- PayPal will retry payment automatically
BILLING.SUBSCRIPTION.CANCELLED
Triggered when a subscription is cancelled (via API or user action in PayPal). Payload:- Updates subscription status to
canceled - User retains access until
billingCycleEnd - Sends cancellation confirmation email
Webhook Headers
PayPal includes the following headers for signature verification:Unique identifier for the webhook transmission
Timestamp when the webhook was transmitted
Signature for verifying the webhook authenticity
URL to PayPal’s certificate for signature verification
Algorithm used for signature (e.g.,
SHA256withRSA)Response
The endpoint always returns a 200 OK response to acknowledge receipt:Signature Verification
Production Mode
In production, the endpoint performs full certificate-based signature verification:- Validates all required PayPal headers are present
- Fetches PayPal’s public certificate from
paypal-cert-url - Constructs expected signature payload
- Verifies signature using RSA-SHA256
- Rejects webhook if verification fails (401 Unauthorized)
Sandbox Mode
WhenPAYPAL_MODE=sandbox, signature verification is bypassed to allow testing:
Current Status
Note: Signature verification is currently bypassed in all modes while the production implementation is being debugged. This is safe because PayPal plan IDs are validated against a hardcoded mapping.WebhookEvent Model
All webhook events are logged in the database:prisma/schema.prisma:162
Error Handling
The webhook endpoint includes robust error handling:- Signature Verification Failures: Returns 401 Unauthorized
- Processing Errors: Returns 200 OK with
received: trueto prevent retries - User Not Found: Logs warning, returns 200 OK
- Database Errors: Logs error, returns 200 OK
Testing Webhooks
Using PayPal Sandbox
- Set
PAYPAL_MODE=sandboxin environment variables - Configure webhook URL in PayPal Developer Dashboard:
- Subscribe to relevant events:
BILLING.SUBSCRIPTION.ACTIVATEDPAYMENT.SALE.COMPLETEDBILLING.SUBSCRIPTION.PAYMENT.FAILEDBILLING.SUBSCRIPTION.CANCELLED
Manual Testing
You can simulate webhooks using the PayPal Webhook Simulator in the Developer Dashboard, or send manual requests:Subscription Service Integration
The webhook endpoint delegates processing toSubscriptionService methods:
Activation:
src/lib/services/subscription-service.ts:22
Webhook Retry Logic
PayPal automatically retries failed webhooks:- Retry Schedule: Exponential backoff (immediate, 5m, 10m, 30m, 1h, 6h, 12h, 24h)
- Max Retries: 25 attempts over 10 days
- Success Criteria: HTTP 200 response
Security Considerations
- Signature Verification: Always verify PayPal signatures in production
- HTTPS Only: Webhook endpoint must use HTTPS
- IP Allowlisting: Consider restricting to PayPal IP ranges
- Idempotency: Webhook handlers should be idempotent to handle duplicate events
- Plan ID Validation: All PayPal plan IDs are validated against hardcoded mapping
Implementation Details
Webhook Handler:src/app/api/payments/webhook/route.ts:72
Signature Verification: src/app/api/payments/webhook/route.ts:20
PayPal Plan Mapping: src/lib/paypal.ts:7
Related Endpoints
- Activate Subscription - Manual subscription activation
- Cancel Subscription - Cancel an active subscription