SEMANTIC BILLING
PayPal Topology
PayPal is the only payment method using a completely separate processor. Stripe handles subscriptions, invoicing, and customer records. Braintree handles PayPal transactions, billing agreements, and disputes. subs-api orchestrates between them.
PayPal breaks the confirm-before-commit pattern
Stripe handles subscriptions, invoicing, customer records, and webhook events. Braintree handles PayPal transactions, Billing Agreement lifecycle, and dispute resolution. subs-api orchestrates between them.
Critical gotcha: adding PayPal changes the collection method on every subscription the customer has to send_invoice + days_until_due, even if they also have a credit card on file. Removing PayPal reverts to charge_automatically.
PayPal renewals use send_invoice collection mode — Stripe creates invoice but does NOT collect. subs-api receives webhook, initiates Braintree charge, then marks PaidOutOfBand. Card renewals use charge_automatically where Stripe handles payment entirely.
Credit Card, Apple Pay, Google Pay, ACH, CashApp, Link, and SEPA Debit all use charge_automatically via Stripe. PayPal is the only PM using send_invoice via Braintree.
In the deferred collection model, PayPal mandates and redirects ARE requires_action. The frontend handles them identically to 3DS — redirect the user, wait for confirmation, activate. No special PayPal code path needed.
PayPal deduplication uses braintree_transaction_id check before charge. Card payments use Stripe idempotency keys.
Does the client-secret-from-subscription-change pattern work for PayPal? When default_incomplete creates a PaymentIntent for a PayPal customer, does the client secret support the redirect/mandate flow through Stripe.js? Spike needed early Q2.
PayPal dunning is triggered by invoice.overdue event, not invoice.payment_failed. Custom retry via subs-api + Braintree. Handler code: endpoints_stripe_dunning.go.
The only payment method that requires orchestrating two processors — Stripe for subscriptions, Braintree for transactions.