Skip to content

PayPal sandbox only. No real money moves.

ProveProof

Gate G4: webhook signatures

Does signature verification accept real PayPal events and reject tampered ones? Method, evidence and limits.

Passa real sandbox run passed

Verified againstGate G4: PASS. Read from docs/GATES.md when the site is built.

Page last changed 7 Nov 2026 (from the git history)

G4 PASS

Question

Does verification against the sandbox webhook id accept real events delivered by PayPal, and reject tampered ones?

Method

  • Workflow: gate-g4, by hand, main only. A small sandbox flow makes PayPal send real webhooks to a receiver (tools/g4-receiver): a capture of 1.00 with final_capture and a void of a second authorization.
  • The log is fetched from the receiver and every delivery goes, as received, to POST /v1/notifications/verify-webhook-signature with the raw body spliced in.
  • Scripts: gates/g4.ts and gates/g4-events.ts (event capture alone) in packages/payments.
  • Needs the repository variable G4_RECEIVER_URL and, by name, the secrets PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET, PAYPAL_WEBHOOK_ID, SANDBOX_BUYER_EMAIL, SANDBOX_BUYER_PASSWORD and G4_LOG_TOKEN.

Observed

Six real deliveries, each answered HTTP 200 with verification_status SUCCESS:

EventCountResult
CHECKOUT.ORDER.APPROVED2SUCCESS, SUCCESS
PAYMENT.AUTHORIZATION.CREATED2SUCCESS, SUCCESS
PAYMENT.CAPTURE.COMPLETED1SUCCESS
PAYMENT.AUTHORIZATION.VOIDED1SUCCESS

Six sanitized fixtures were written to packages/payments/test/fixtures/webhooks/. Real events carry fields the fake simulator lacked (event_version, resource_type, resource_version, summary, links); the fields only the simulator has are orderId, authId, captureId, amountCents and reason.

Evidence

Limits

The owner-run redelivery check that would close W06 is written out in docs/RUNBOOK-GATES.md. How the server handles webhooks is on the webhooks page.

Edit on GitHub

Last updated on