How to Test PayPal Webhooks
Capture PayPal PAYMENT.CAPTURE.COMPLETED and subscription events in real time — inspect headers, signatures, and full event objects.
TL;DR: PayPal sends signed JSON webhooks for payment, subscription, and dispute events. Generate a Requex URL, register it in your PayPal Developer Dashboard under your app's Webhook subscriptions, then trigger a test event from the PayPal simulator.
Key PayPal Webhook Events
PayPal groups webhook events by resource type. These are the events most integrations need to handle:
| Event Type | When It Fires |
|---|---|
PAYMENT.CAPTURE.COMPLETED | Payment captured successfully |
PAYMENT.CAPTURE.DENIED | Payment capture was declined |
BILLING.SUBSCRIPTION.CREATED | A new subscription was created |
BILLING.SUBSCRIPTION.CANCELLED | A subscription was cancelled |
BILLING.SUBSCRIPTION.RENEWED | A subscription renewal payment succeeded |
CUSTOMER.DISPUTE.CREATED | A customer opened a dispute or chargeback |
Step 1: Generate Requex Endpoint
Open requex.me in your browser. A unique public URL is created immediately — no account required. Copy the URL. It looks like:
https://requex.me/hook/a1b2c3d4-e5f6-7890-abcd-ef1234567890
Keep this tab open. Requests from PayPal appear in real time so you can inspect the full JSON payload as soon as the event fires.
Step 2: Register in PayPal Developer Dashboard
Go to developer.paypal.com and sign in. Navigate to My Apps & Credentials and click on your app (or create a Sandbox app if you do not have one). Scroll down to the Webhooks section and click Add Webhook.
- Webhook URL: Paste your Requex URL.
- Event types: Select the events you want to test (e.g.
PAYMENT.CAPTURE.COMPLETED,BILLING.SUBSCRIPTION.CREATED). - Click Save to register the webhook.
PayPal validates the URL during registration by sending a quick verification request. Requex will accept it automatically and you should see a verification request appear in the Requex dashboard immediately.
Step 3: Use the PayPal Webhook Simulator
PayPal provides a built-in Webhook Simulator so you can send test events without completing a real transaction. In the Developer Dashboard, go to your app, scroll to the Webhooks section, and click Simulate webhook event.
- Select your webhook from the dropdown.
- Choose the event type to simulate (e.g.
PAYMENT.CAPTURE.COMPLETED). - Click Send test notification.
Within a second the event will appear in your Requex dashboard with the full JSON payload PayPal sends.
Step 4: Inspect the Payload
Click the request in Requex to expand it. A typical PAYMENT.CAPTURE.COMPLETED payload looks like this:
{
"id": "WH-2WR32451HC0233532-67976317FL4543714",
"event_type": "PAYMENT.CAPTURE.COMPLETED",
"event_version": "1.0",
"resource_type": "capture",
"resource": {
"id": "2GG279541U471931P",
"status": "COMPLETED",
"amount": {
"value": "19.99",
"currency_code": "USD"
},
"seller_protection": {
"status": "ELIGIBLE"
},
"final_capture": true,
"create_time": "2026-04-05T10:00:00Z",
"update_time": "2026-04-05T10:00:05Z"
},
"create_time": "2026-04-05T10:00:06Z",
"links": [
{ "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-xxx", "rel": "self", "method": "GET" },
{ "href": "https://api.paypal.com/v1/notifications/webhooks-events/WH-xxx/resend", "rel": "resend", "method": "POST" }
]
}Key fields to note: event_type for routing your handler, resource.id as your idempotency key, and resource.amount for the transaction value. The links array includes a resend URL which is useful for retrying events during development.
PayPal Webhook Signature Verification
PayPal signs every webhook request. You can verify the signature using the PayPal API — there is no shared secret; instead, PayPal uses a certificate-based verification flow. When you receive a webhook, check these headers in Requex first:
PAYPAL-TRANSMISSION-ID— unique ID for the transmissionPAYPAL-TRANSMISSION-TIME— timestamp of transmissionPAYPAL-CERT-URL— URL to fetch the PayPal public certificatePAYPAL-TRANSMISSION-SIG— the signature itselfPAYPAL-AUTH-ALGO— the algorithm used (typically SHA256withRSA)
To verify, call the PayPal Verify Webhook Signature endpoint, passing these headers plus the raw request body and your webhook ID:
// Node.js example — verify PayPal webhook signature
const axios = require('axios');
async function verifyPayPalWebhook(req) {
const { data } = await axios.post(
'https://api-m.sandbox.paypal.com/v1/notifications/verify-webhook-signature',
{
auth_algo: req.headers['paypal-auth-algo'],
cert_url: req.headers['paypal-cert-url'],
transmission_id: req.headers['paypal-transmission-id'],
transmission_sig: req.headers['paypal-transmission-sig'],
transmission_time: req.headers['paypal-transmission-time'],
webhook_id: process.env.PAYPAL_WEBHOOK_ID,
webhook_event: req.body,
},
{ headers: { Authorization: 'Bearer ' + accessToken } }
);
return data.verification_status === 'SUCCESS';
}Use api-m.sandbox.paypal.com for sandbox and api-m.paypal.com for production. Never skip verification in production — PayPal webhook IDs and transmission IDs together provide a strong guarantee of authenticity.
Common PayPal Webhook Issues
| Issue | Cause | Fix |
|---|---|---|
| Webhook not received at all | The app is in Sandbox mode but the event was triggered in Live mode, or vice versa | Ensure your Requex URL is registered under the correct Sandbox or Live credentials in the Developer Dashboard |
| Signature verification returns FAILURE | Wrong webhook ID passed to the verify endpoint, or the raw body was modified before verification | Double-check PAYPAL_WEBHOOK_ID matches the registered webhook; ensure body is passed as-is without JSON re-serialisation |
| Events arrive after a long delay | PayPal retries failed deliveries with exponential backoff; your endpoint returned a non-200 status on an earlier attempt | Always return HTTP 200 immediately on receipt, even if processing is async; handle the business logic in a background job |
Test Your PayPal Webhooks for Free
Generate a public endpoint in seconds. No sign-up — just open, copy, and paste into the PayPal Developer Dashboard.
Open Requex →Related guides
Start Testing Webhooks Now
Generate your unique URL and test webhooks instantly. Free, no signup.
Open Webhook Tester →