PayPal transaction filter + payments mapping + external-id dedupe were inline and untested, and auth was a hand-rolled select instead of the shared helper. Extracted to pure lib/paypal-logic.ts (also fixes a latent throw on a missing/invalid PayPal date by falling back to now); route now uses requireMemberWithRole. 7 tests; suite 521. Behavior otherwise unchanged.