Payments: PayPal for OMA checkout and for Atelier agencies
Imported from GitHub issue El-SaMa/oma#144 by @El-SaMa.
Current state
GatewayKind already includes paypal, but services/core-api/src/payments/gateways.ts maps it to undefined. There is no adapter, no credentials provider and no webhooks.
Part 1: PayPal for OMA (Lanetti's own invoices and checkout)
- Operator: a PayPal Business account for Maximum Effort Ay; REST app client id and secret in OMA settings (env var names only).
- Adapter
PayPalGateway: Orders v2 (create order, approve redirect, capture), EUR,invoice_idset to the OMA invoice id,custom_idset to the org. - Webhooks:
PAYMENT.CAPTURE.COMPLETED/DENIED/REFUNDED,CUSTOMER.DISPUTE.*, with signature verification through PayPal's verify-webhook-signature API. Idempotent mark-paid with exact amount and currency. - Refunds from the admin invoice page.
- Checkout UI option next to Stripe/Kustom/bank transfer, with native fi/en/sv copy.
- Platform tools:
oma.list_payment_gateways/oma.initiate_invoice_paymentsupport PayPal. - Test end to end in the PayPal sandbox; handbook
billing/payments.md.
Part 2: PayPal for Atelier agencies (their clients pay the agency)
Same white-label rule as #136: the money and the descriptor must be the agency's, never Lanetti's. Do not collect on the agency's behalf (merchant-of-record and payment-services issues).
- Preferred: PayPal partner onboarding ("Multiparty / Commerce Platform") so an agency connects its own PayPal account from the console, and orders are created on the agency's behalf (
PayPal-Auth-Assertion/ partner merchant id). This needs PayPal partner approval for Lanetti (operator task; can take time). - Fallback until approved: the agency pastes its own REST client id and secret (sealed at invoke like the Stripe keys today), or just uses its own PayPal payment link (already possible via the invoice payment link field).
- Reuse the agency invoice pay flow (
apps/web/lib/reseller/client-pay.ts, pay button on/billing/agency/[id]) and the webhook route pattern of/api/webhooks/agency-stripe/[resellerOrgId]. - Terms:
/legal/resellersection 5 already covers agency-owned payment accounts.
Done when
PayPal works for OMA invoices in production, and agencies can take PayPal from their clients into their own PayPal account, with webhooks, refunds, tests and handbook done.