5.6 KiB
OpenSpec Change: enterprise-payment-providers
- Change ID: enterprise-payment-providers
- Package:
@suaveplan/payment-providers - Category: universal
- Target path:
universal/commerce/payment-providers - Status: IN PROGRESS
- Date: 2026-04-24
- Reference spec:
/mnt/s/web/suaveplan/enterprise/payment-providers.md
Summary
Deliver @suaveplan/payment-providers on the genesis branch from scratch at enterprise quality. The package provides concrete PaymentAdapter implementations for Stripe, PayPal, Square, Mollie, and Adyen. Each adapter wraps the provider's REST API using injectable fetch (no provider SDK dependency), implements the full PaymentAdapter interface from @suaveplan/payment, handles provider-specific webhook signature verification, and normalises provider error codes to the canonical PAYMENT.* code registry. The main-branch version sat at 100% coverage. Genesis adds structured errors, Zod schemas, OTel instrumentation, retry with circuit breaker, and integration-test harnesses.
Current-state audit (genesis)
The package does not exist on genesis yet — this is a fresh build.
Available workspace deps on genesis
| Package | Role |
|---|---|
@suaveplan/error (workspace:^) |
PaymentProviderError; extends PAYMENT.* code set |
@suaveplan/types (workspace:^) |
LoggerLike, Clock |
@suaveplan/payment (workspace:^) |
PaymentAdapter interface; PaymentIntent, PaymentWebhookEvent types |
@suaveplan/retry (workspace:^) |
Retry + circuit breaker for provider API calls |
@suaveplan/crypto (workspace:^) |
HMAC webhook signature verification |
zod (catalog:forms) |
Provider response schema validation |
@opentelemetry/api (catalog:observability) |
Spans + counters |
Dev deps: vitest, @vitest/coverage-istanbul (all catalog:testing).
Public API surface
Provider factories
function createStripeAdapter(options: StripeAdapterOptions): PaymentAdapter
function createPayPalAdapter(options: PayPalAdapterOptions): PaymentAdapter
function createSquareAdapter(options: SquareAdapterOptions): PaymentAdapter
function createMollieAdapter(options: MollieAdapterOptions): PaymentAdapter
function createAdyenAdapter(options: AdyenAdapterOptions): PaymentAdapter
All option types share a common base:
interface BaseAdapterOptions {
apiKey: string
webhookSecret?: string
environment?: 'sandbox' | 'production' // default 'production'
retryOptions?: RetryOptions
fetch?: typeof globalThis.fetch
clock?: Clock
logger?: LoggerLike
}
interface StripeAdapterOptions extends BaseAdapterOptions {
apiVersion?: string // default 'latest'
}
interface PayPalAdapterOptions extends BaseAdapterOptions {
clientId: string
clientSecret: string
}
interface AdyenAdapterOptions extends BaseAdapterOptions {
merchantAccount: string
liveUrlPrefix?: string
}
Provider-normalised types
Each provider's raw response is normalised to PaymentIntent via a per-provider mapper; these mappers are exported for testing:
function normalizeStripePaymentIntent(raw: unknown): PaymentIntent
function normalizePayPalOrder(raw: unknown): PaymentIntent
function normalizeSquarePayment(raw: unknown): PaymentIntent
function normalizeMolliePayment(raw: unknown): PaymentIntent
function normalizeAdyenPayment(raw: unknown): PaymentIntent
Error codes
Provider errors are wrapped in PaymentError with existing PAYMENT_PROVIDER_ERROR code plus an added detail field:
interface PaymentProviderErrorDetail {
provider: string
providerCode?: string
providerMessage?: string
}
Genesis additions
- Zod schemas for all provider-specific option types and raw response shapes.
- Sandbox/production switching —
environment: 'sandbox'routes to provider test endpoints automatically. - Idempotency key passthrough — all create/capture/refund calls forward the caller-supplied idempotency key as the provider-specific header (
Idempotency-Keyfor Stripe, etc.). - Circuit breaker — wraps all provider API calls via
@suaveplan/retry; opens after 5 consecutive provider errors. - OTel instrumentation — span
payment_provider.api_callwith attributespayment_provider.name,payment_provider.method; counterpayment_provider.api_total; histogrampayment_provider.api_duration_ms. - Provider error normalisation — 4xx/5xx provider responses are mapped to the closest
PAYMENT.*error code with provider details preserved in the error context.
File layout
universal/commerce/payment-providers/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
error-codes.ts
constants/
index.ts
types/
common.ts
common.md
providers/
stripe/
stripe.ts
stripe.md
stripe.types.ts
stripe.test.ts
index.ts
paypal/
paypal.ts
paypal.md
paypal.types.ts
paypal.test.ts
index.ts
square/
square.ts
square.md
square.types.ts
square.test.ts
index.ts
mollie/
mollie.ts
mollie.md
mollie.types.ts
mollie.test.ts
index.ts
adyen/
adyen.ts
adyen.md
adyen.types.ts
adyen.test.ts
index.ts
__benchmarks__/
payment-providers.bench.ts
tests/
integration.test.ts
Impact
Downstream consumers: @suaveplan/booking, any server-side checkout flow.
Workspace dep prerequisites: @suaveplan/error, @suaveplan/types, @suaveplan/payment, @suaveplan/retry, @suaveplan/crypto.