108 lines
4.4 KiB
Markdown
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
|
|
|