Files
skills/docs/money/payment/payment-provider-paypal/README.md
2026-05-29 08:20:56 +01:00

108 lines
4.4 KiB
Markdown

# @suaveplan/payment-provider-paypal - PayPal payment provider for @suaveplan/payment-providers. Implements the PaymentProvider interface against the PayPal Orders v2 + Payments Captures Refund APIs, with an OAuth2 client-credentials token cache, injectable now/base64Encode/FetchLike seams, sandbox-endpoint shortcut, MoneyLike bigint marshalling, and structured PaymentProviderError surfaces. Universal — runs unchanged on Node, Bun, browsers, and Web Workers.
PayPal sibling adapter for the slim
[`@suaveplan/payment-providers`](../payment-providers/README.md) foundation.
Ships `PayPalProvider` — a `PaymentProvider` implementation against the
PayPal Orders v2 + Payments Captures Refund APIs, with an OAuth2
client-credentials token cache, injectable `now` / `base64Encode` /
`FetchLike` seams, a `sandbox` shortcut, `MoneyLike` bigint marshalling,
and structured `PaymentProviderError` surfaces. Universal — runs
unchanged on Node, Bun, browsers, and Web Workers.
<!-- begin:auto-docs -->
## Documentation tree
- [paypal](./src/paypal/paypal.md) — `PayPalProvider` is the PayPal-flavoured implementation of the `PaymentProvider` contract exported by `@suaveplan/payme…
- [mapping](./src/paypal/mapping.md) — Pure mapping utilities used by `PayPalProvider` to bridge the PayPal Orders v2 + Payments Captures Refund wire shapes i…
- [paypal](./src/paypal/paypal.md) — `PayPalProvider` is the PayPal-flavoured implementation of the `PaymentProvider` contract exported by `@suaveplan/payme…
<!-- end:auto-docs -->
## Install
```bash
bun add @suaveplan/payment-provider-paypal @suaveplan/payment-providers @suaveplan/payment
```
## Quick start
```ts
import { ProviderRegistry } from "@suaveplan/payment-providers";
import { PayPalProvider } from "@suaveplan/payment-provider-paypal";
const registry = new ProviderRegistry();
registry.register(
new PayPalProvider({
clientId: process.env.PAYPAL_CLIENT_ID ?? "",
clientSecret: process.env.PAYPAL_CLIENT_SECRET ?? "",
sandbox: true,
})
);
const paypal = registry.get("paypal");
const intent = await paypal.createIntent({
amount: { amount: 5000n, currency: "USD" },
description: "Order #1234",
captureMethod: "automatic",
idempotencyKey: "order-1234",
});
console.log(intent.id, intent.status);
```
## Features
- `class PayPalProvider implements PaymentProvider` with literal-typed
`name: "paypal"`
- OAuth2 client-credentials token cache with 60 s clock-skew buffer,
refreshed transparently on expiry
- Injectable `now: NowFn`, `base64Encode: Base64EncodeFn`, and
`fetch: FetchLike` for universal determinism and testability
- `sandbox` flag → `https://api-m.sandbox.paypal.com`; explicit `baseUrl`
always wins
- `MoneyLike` bigint minor-unit amounts marshalled to PayPal's major-unit
decimal-string format
- `PayPal-Request-Id` idempotency-header support on `createIntent` and
`refund`
- Exhaustive PayPal-status → `PaymentStatus` / `RefundStatus`
mapping; unknown statuses map to `failed`
- Structured `PaymentProviderError` (from `@suaveplan/payment-providers`)
on every failure path — `OAUTH_TOKEN_FAILURE`, `HTTP_ERROR`, `TIMEOUT`,
`PARSE_ERROR` — always with `provider: "paypal"`
- Universal: zero Node / browser / React imports; `sideEffects: false`
- 100% Istanbul coverage; sibling `.md` per implementation file
## Modules
- [`src/paypal/paypal.md`](./src/paypal/paypal.md) — `PayPalProvider`
class, `PayPalConfig` interface, lifecycle methods, OAuth token cache
- [`src/paypal/mapping.md`](./src/paypal/mapping.md) — pure helpers:
`mapStatus`, `mapRefundStatus`, `parseAmount`, `formatAmount`,
`mapOrder`
## Foundation
This package depends on
[`@suaveplan/payment-providers`](../payment-providers/README.md) for:
- `httpRequest`, `composeAbortSignal`, `FetchLike`
- `OAuthConfig`, `NowFn`, `Base64EncodeFn`
- `PaymentProviderError`, `PAYMENT_PROVIDER_CODES`, `oauthTokenFailure`
and on [`@suaveplan/payment`](../payment/README.md) for the structural
`PaymentProvider`, `PaymentIntent`, `Refund`, `PaymentStatus`,
`RefundStatus`, `CreatePaymentIntentInput`, and `RefundInput` types.
## Related sibling packages
- `@suaveplan/payment-provider-stripe`
- `@suaveplan/payment-provider-square`
- `@suaveplan/payment-provider-mollie`
- `@suaveplan/payment-provider-adyen`
All four follow the same pattern: depend on the slim core, expose a
single `*Provider` class, register cleanly into `ProviderRegistry`.
## License
MIT