FloPayFloPay
GatewaysPayPal

Webhooks

Inbound PayPal events FloPay subscribes to and how they map to outbound Flo webhooks.

PayPal Events

When a client provisions a direct PayPal gateway, FloPay subscribes to a fixed set of PayPal webhook events at the gateway level and normalizes them into the existing outbound Flo webhook families.

The outbound contract does not change. Direct PayPal events arrive at your client webhook endpoint as the same subscription.*, item.*, and invoice.* events documented in Events. This page is reference material for what happens upstream — your handler code does not need to branch on gateway. The outbound payload shape is identical regardless of which gateway produced the underlying event.

Subscribed PayPal Events

FloPay subscribes to the following 15 PayPal webhook events. These are configured on the PayPal app you provision during direct PayPal setup.

PayPal eventPurpose
CHECKOUT.ORDER.APPROVEDBuyer approved a one-time order in the PayPal flow.
PAYMENT.CAPTURE.COMPLETEDOne-time capture succeeded.
PAYMENT.CAPTURE.DENIEDOne-time capture was denied by PayPal.
PAYMENT.CAPTURE.PENDINGCapture is pending PayPal review.
PAYMENT.CAPTURE.REFUNDEDA previous capture was refunded.
PAYMENT.CAPTURE.REVERSEDA previous capture was reversed (chargeback / dispute).
BILLING.SUBSCRIPTION.CREATEDSubscription created in PayPal.
BILLING.SUBSCRIPTION.ACTIVATEDSubscription transitioned to active.
BILLING.SUBSCRIPTION.UPDATEDSubscription details changed (plan, quantity, etc.).
BILLING.SUBSCRIPTION.CANCELLEDSubscription was cancelled.
BILLING.SUBSCRIPTION.SUSPENDEDSubscription was suspended (paused).
BILLING.SUBSCRIPTION.EXPIREDSubscription reached its end and was not renewed.
BILLING.SUBSCRIPTION.PAYMENT.FAILEDA recurring charge failed after PayPal exhausted retries.
VAULT.PAYMENT-TOKEN.CREATEDA vaulted PayPal payment token was created — enables saved-payment upsells.
VAULT.PAYMENT-TOKEN.DELETEDA vaulted PayPal payment token was removed.

Signature Verification

FloPay verifies each delivery by calling PayPal's hosted /v1/notifications/verify-webhook-signature endpoint with the webhook id stored in the gateway record's webhook_signing_secret column. Local certificate-based verification is deferred — every inbound PayPal event hits PayPal's verification endpoint before it is processed.

Inbound → Outbound Mapping

PayPal eventOutbound Flo eventNotes
CHECKOUT.ORDER.APPROVED(no outbound)Internal trigger to capture the order.
PAYMENT.CAPTURE.COMPLETEDitem.purchased, invoice.paidEmitted on successful one-time capture, including the first cycle of a subscription.
PAYMENT.CAPTURE.DENIEDinvoice.overdueThe invoice stays collectible; PayPal denied this specific capture.
PAYMENT.CAPTURE.PENDING(no outbound)FloPay holds processing until the capture resolves to completed, denied, or reversed.
PAYMENT.CAPTURE.REFUNDEDitem.refundedOne-to-one with refunding the capture id.
PAYMENT.CAPTURE.REVERSEDitem.refundedReversal (chargeback / dispute) maps to the same outbound family.
BILLING.SUBSCRIPTION.CREATEDsubscription.created
BILLING.SUBSCRIPTION.ACTIVATEDsubscription.created or subscription.reactivatedsubscription.created on first activation; subscription.reactivated when a previously cancelled subscription is restored.
BILLING.SUBSCRIPTION.UPDATEDsubscription.updated
BILLING.SUBSCRIPTION.CANCELLEDsubscription.cancelled
BILLING.SUBSCRIPTION.SUSPENDEDsubscription.paused
BILLING.SUBSCRIPTION.EXPIREDsubscription.expired
BILLING.SUBSCRIPTION.PAYMENT.FAILEDinvoice.overduePayPal exhausted its retry window — Flo does not issue further off-session retries.
VAULT.PAYMENT-TOKEN.CREATED(no outbound)Internal: FloPay stores the token on user_payment_method with type='paypal' for upsell reuse.
VAULT.PAYMENT-TOKEN.DELETED(no outbound)Internal: FloPay removes the stored token.

subscription.resumed is emitted when a previously suspended subscription returns to active. Depending on the originating PayPal flow this can arrive via BILLING.SUBSCRIPTION.ACTIVATED or BILLING.SUBSCRIPTION.UPDATED — FloPay normalizes on its own state transition, not the inbound PayPal event name.

Recurring Billing Behaviour

PayPal — not Flo — drives the recurring billing cycle for direct PayPal subscriptions. Renewals fire PAYMENT.CAPTURE.COMPLETED against the subscription, and FloPay emits subscription.renewed (with the linked invoice.paid).

Off-session retries are PayPal's responsibility. FloPay does not retry a failed PayPal recurring charge — once BILLING.SUBSCRIPTION.PAYMENT.FAILED arrives, PayPal has already exhausted its dunning window.

  • Events — full outbound event catalog and examples
  • Payloads — outbound field-level schema
  • Overview — outbound webhook contract
  • Direct PayPal — gateway setup and lifecycle

On this page