How it is built

Every tool in Remedy, the one job it does, and where it lives in the code. Live status is on the Status page.

Every PayPal API Remedy calls

9 PayPal APIs, each with one job. All run against the PayPal sandbox. Going live sets PAYPAL_ENV=live, which moves every PayPal address (the REST API, the Server SDK, the JavaScript SDK and PayPal's MCP server) to PayPal's live ones, and swaps in a live app's client ID, secret and webhook ID.

PayPal’s MCP server, read in the sandbox on November 8, 2026: get_order answered in 1,190 ms, and check C6 read the order through it (content/public/paypal-mcp-read.json, written by scripts/payments/mcp-probe.ts).

All 9 PayPal APIs, with the call and the job for each
PayPalCallWhat it does here
OAuth 2.0POST /v1/oauth2/tokenOne cached access token for every call below.
PayoutsPOST /v1/payments/payoutsPays a verified refund to an email, a phone number or Venmo.
Payments v2: refundPOST /v2/payments/captures/{id}/refundSends the refund back to how the owner paid, inside 180 days.
Orders v2POST /v2/checkout/ordersThe sample shop's purchase, and a safe replacement order.
JavaScript SDK v6web-sdk/v6/coreThe PayPal button in the sample shop.
Transaction SearchGET /v1/reporting/transactionsFinds buyers who paid the firm with PayPal, so they can be told about the recall.
DisputesGET /v1/customer/disputesChecks that a purchase has no open dispute before it is refunded.
PayPal MCP serverget_order (read only)Check C6 reads the purchase's captures and refunds from PayPal's own MCP server; the Orders API is the fallback. Only read tools can be called.
WebhooksPOST /v1/notifications/verify-webhook-signatureChecks PayPal's signature on every payout and refund event before it updates a payment.

How firms connect their PayPal

A firm connects its own PayPal REST app in its console: the client ID and secret are checked with PayPal (an OAuth token request), sealed with AES-256-GCM and never shown again, and its refunds and payouts then run on that app. The sample firm pays from the platform's sandbox account. PayPal's Partner Referrals API needs an app PayPal has approved as a partner, and this sandbox app received 403 NOT_AUTHORIZED when it was tried on November 7, 2026, so firms connect their own app today.

A production rollout onboards each firm through PayPal's Partner Referrals API instead: the firm signs in on PayPal's own page and grants Remedy permission, and Remedy keeps only the firm's merchant ID. Each call for that firm then carries Remedy's own partner token with a PayPal-Auth-Assertion header naming the firm, so the money still moves on the firm's own account and no secret of the firm's is ever held.

What changes in the code
  • paypal/firm-account.ts connectAccount stores the merchant ID from PayPal's onboarding return in place of a sealed client ID and secret; restForFirm builds each call with the partner token and a PayPal-Auth-Assertion header for that merchant.
  • db/schema.sql The firm row's two sealed credential columns give way to one merchant ID column, as a reviewed migration.
  • payments/router.ts No change: the router, the six checks and the ledger already pay through whatever account restForFirm returns.