@olympio/payment-gateway 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -0
- package/dist/index.cjs +1071 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +351 -0
- package/dist/index.d.ts +351 -0
- package/dist/index.js +1019 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/adapters/stripe/StripeGateway.ts","../src/domain/capabilities/Capability.ts","../src/domain/errors/index.ts","../src/domain/models/Money.ts","../src/adapters/stripe/mappers.ts","../src/adapters/asaas/AsaasHttpClient.ts","../src/adapters/asaas/mappers.ts","../src/adapters/asaas/AsaasGateway.ts","../src/adapters/dom/DomHttpClient.ts","../src/adapters/dom/mappers.ts","../src/adapters/dom/ports.ts","../src/adapters/dom/DomGateway.ts","../src/createGateway.ts"],"sourcesContent":["// Ponto de entrada\nexport { createGateway, type GatewayConfig } from './createGateway.js';\n\n// Ports (contrato)\nexport type {\n PaymentGateway,\n CustomerPort,\n ChargePort,\n SubscriptionPort,\n WebhookPort,\n} from './domain/ports/index.js';\n\n// Capabilities\nexport { Capability, hasCapability } from './domain/capabilities/Capability.js';\n\n// Modelos de domínio\nexport { Money } from './domain/models/Money.js';\nexport type { Provider } from './domain/models/Provider.js';\nexport type { PaymentMethod } from './domain/models/PaymentMethod.js';\nexport type {\n Customer,\n CreateCustomerInput,\n UpdateCustomerInput,\n} from './domain/models/Customer.js';\nexport type {\n Charge,\n ChargeStatus,\n CreateChargeInput,\n RefundChargeInput,\n PixDetails,\n BoletoDetails,\n} from './domain/models/Charge.js';\nexport type {\n Subscription,\n SubscriptionStatus,\n BillingInterval,\n CreateSubscriptionInput,\n} from './domain/models/Subscription.js';\nexport type {\n WebhookEvent,\n WebhookEventType,\n WebhookInput,\n} from './domain/models/WebhookEvent.js';\n\n// Erros normalizados\nexport {\n GatewayError,\n CardDeclinedError,\n AuthenticationError,\n RateLimitError,\n ValidationError,\n GatewayUnavailableError,\n UnknownGatewayError,\n UnsupportedCapabilityError,\n type GatewayErrorCode,\n type GatewayErrorOptions,\n} from './domain/errors/index.js';\n\n// Adapters (uso direto, sem a factory)\nexport { StripeGateway, type StripeGatewayConfig } from './adapters/stripe/StripeGateway.js';\nexport { AsaasGateway, type AsaasGatewayConfig } from './adapters/asaas/AsaasGateway.js';\nexport {\n type AsaasHttpClient,\n type AsaasHttpConfig,\n AsaasApiError,\n createAsaasHttpClient,\n} from './adapters/asaas/AsaasHttpClient.js';\n","import Stripe from 'stripe';\nimport { Capability } from '../../domain/capabilities/Capability.js';\nimport {\n UnsupportedCapabilityError,\n} from '../../domain/errors/index.js';\nimport type {\n Charge,\n CreateChargeInput,\n RefundChargeInput,\n} from '../../domain/models/Charge.js';\nimport type {\n CreateCustomerInput,\n Customer,\n UpdateCustomerInput,\n} from '../../domain/models/Customer.js';\nimport type { PaymentMethod } from '../../domain/models/PaymentMethod.js';\nimport type {\n BillingInterval,\n CreateSubscriptionInput,\n Subscription,\n} from '../../domain/models/Subscription.js';\nimport type {\n WebhookEvent,\n WebhookInput,\n} from '../../domain/models/WebhookEvent.js';\nimport type {\n ChargePort,\n CustomerPort,\n PaymentGateway,\n SubscriptionPort,\n WebhookPort,\n} from '../../domain/ports/index.js';\nimport {\n mapStripeError,\n toCharge,\n toCustomer,\n toSubscription,\n toWebhookEvent,\n} from './mappers.js';\nimport { ValidationError } from '../../domain/errors/index.js';\n\nexport interface StripeGatewayConfig {\n apiKey: string;\n /** Signing secret para verificar webhooks. */\n webhookSecret?: string;\n}\n\nconst PROVIDER = 'stripe' as const;\n\nconst CAPABILITY_BY_METHOD: Record<PaymentMethod, Capability> = {\n card: Capability.CARD,\n pix: Capability.PIX,\n boleto: Capability.BOLETO,\n};\n\nconst STRIPE_INTERVAL: Record<BillingInterval, 'week' | 'month' | 'year'> = {\n weekly: 'week',\n monthly: 'month',\n yearly: 'year',\n};\n\n/** Reexecuta a operação traduzindo qualquer erro do SDK para a hierarquia normalizada. */\nasync function normalizeErrors<T>(fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (err) {\n throw mapStripeError(err);\n }\n}\n\nfunction isResourceMissing(err: unknown): boolean {\n return (err as { code?: string }).code === 'resource_missing';\n}\n\nexport class StripeGateway implements PaymentGateway<Stripe> {\n readonly provider = PROVIDER;\n readonly capabilities: ReadonlySet<Capability> = new Set([\n Capability.CARD,\n Capability.REFUND,\n Capability.SUBSCRIPTIONS,\n ]);\n\n private readonly client: Stripe;\n\n readonly customers: CustomerPort;\n readonly charges: ChargePort;\n readonly subscriptions: SubscriptionPort;\n readonly webhooks: WebhookPort;\n\n constructor(\n private readonly config: StripeGatewayConfig,\n client?: Stripe,\n ) {\n this.client = client ?? new Stripe(config.apiKey);\n this.customers = this.buildCustomerPort();\n this.charges = this.buildChargePort();\n this.subscriptions = this.buildSubscriptionPort();\n this.webhooks = this.buildWebhookPort();\n }\n\n supports(capability: Capability): boolean {\n return this.capabilities.has(capability);\n }\n\n raw(): Stripe {\n return this.client;\n }\n\n private requireMethod(method: PaymentMethod): void {\n const cap = CAPABILITY_BY_METHOD[method];\n if (!this.capabilities.has(cap)) {\n throw new UnsupportedCapabilityError(PROVIDER, cap);\n }\n }\n\n private buildCustomerPort(): CustomerPort {\n const client = this.client;\n return {\n create: (input: CreateCustomerInput) =>\n normalizeErrors(async () =>\n toCustomer(\n await client.customers.create(\n {\n name: input.name,\n email: input.email,\n phone: input.phone,\n metadata: input.metadata,\n },\n input.idempotencyKey ? { idempotencyKey: input.idempotencyKey } : undefined,\n ),\n ),\n ),\n get: async (id: string): Promise<Customer | null> => {\n try {\n const c = await client.customers.retrieve(id);\n if ((c as Stripe.DeletedCustomer).deleted) return null;\n return toCustomer(c as Stripe.Customer);\n } catch (err) {\n if (isResourceMissing(err)) return null;\n throw mapStripeError(err);\n }\n },\n update: (id: string, input: UpdateCustomerInput) =>\n normalizeErrors(async () =>\n toCustomer(\n await client.customers.update(id, {\n name: input.name,\n email: input.email,\n phone: input.phone,\n metadata: input.metadata,\n }),\n ),\n ),\n delete: (id: string) =>\n normalizeErrors(async () => {\n await client.customers.del(id);\n }),\n };\n }\n\n private buildChargePort(): ChargePort {\n const client = this.client;\n return {\n create: async (input: CreateChargeInput): Promise<Charge> => {\n this.requireMethod(input.paymentMethod);\n return normalizeErrors(async () =>\n toCharge(\n await client.paymentIntents.create(\n {\n amount: input.amount.cents,\n currency: input.amount.currency.toLowerCase(),\n customer: input.customerId,\n description: input.description,\n payment_method: input.cardToken,\n payment_method_types: ['card'],\n confirm: input.cardToken !== undefined,\n metadata: input.metadata,\n },\n input.idempotencyKey ? { idempotencyKey: input.idempotencyKey } : undefined,\n ),\n ),\n );\n },\n get: async (id: string): Promise<Charge | null> => {\n try {\n return toCharge(await client.paymentIntents.retrieve(id));\n } catch (err) {\n if (isResourceMissing(err)) return null;\n throw mapStripeError(err);\n }\n },\n cancel: (id: string) =>\n normalizeErrors(async () => toCharge(await client.paymentIntents.cancel(id))),\n refund: (input: RefundChargeInput): Promise<Charge> =>\n normalizeErrors(async () => {\n await client.refunds.create({\n payment_intent: input.chargeId,\n amount: input.amount?.cents,\n });\n const pi = await client.paymentIntents.retrieve(input.chargeId);\n return { ...toCharge(pi), status: 'refunded' };\n }),\n };\n }\n\n private buildSubscriptionPort(): SubscriptionPort {\n const client = this.client;\n return {\n create: (input: CreateSubscriptionInput): Promise<Subscription> =>\n normalizeErrors(async () => {\n const price = await client.prices.create({\n unit_amount: input.amount.cents,\n currency: input.amount.currency.toLowerCase(),\n recurring: { interval: STRIPE_INTERVAL[input.interval] },\n product_data: { name: `subscription-${input.customerId}` },\n });\n const sub = await client.subscriptions.create(\n {\n customer: input.customerId,\n items: [{ price: price.id }],\n metadata: input.metadata,\n },\n input.idempotencyKey ? { idempotencyKey: input.idempotencyKey } : undefined,\n );\n return toSubscription(sub);\n }),\n get: async (id: string): Promise<Subscription | null> => {\n try {\n return toSubscription(await client.subscriptions.retrieve(id));\n } catch (err) {\n if (isResourceMissing(err)) return null;\n throw mapStripeError(err);\n }\n },\n cancel: (id: string) =>\n normalizeErrors(async () => toSubscription(await client.subscriptions.cancel(id))),\n };\n }\n\n private buildWebhookPort(): WebhookPort {\n const client = this.client;\n const secret = this.config.webhookSecret;\n return {\n verifyAndParse: (input: WebhookInput): WebhookEvent => {\n if (!secret) {\n throw new ValidationError(PROVIDER, 'webhookSecret não configurado.');\n }\n const signature = input.headers['stripe-signature'];\n try {\n const event = client.webhooks.constructEvent(input.payload, signature ?? '', secret);\n return toWebhookEvent(event);\n } catch (err) {\n throw new ValidationError(PROVIDER, 'Assinatura de webhook inválida.', {\n cause: err,\n });\n }\n },\n };\n }\n}\n","/**\n * Recursos que um gateway pode ou não suportar. Cada adapter declara seu\n * conjunto; o consumidor checa antes de chamar, evitando erros crus do gateway.\n */\nexport const Capability = {\n PIX: 'pix',\n BOLETO: 'boleto',\n CARD: 'card',\n REFUND: 'refund',\n SUBSCRIPTIONS: 'subscriptions',\n} as const;\n\nexport type Capability = (typeof Capability)[keyof typeof Capability];\n\nexport function hasCapability(\n caps: ReadonlySet<Capability>,\n capability: Capability,\n): boolean {\n return caps.has(capability);\n}\n","import type { Capability } from '../capabilities/Capability.js';\nimport type { Provider } from '../models/Provider.js';\n\nexport type { Provider };\n\nexport interface GatewayErrorOptions {\n /** Erro original do gateway/SDK, preservado para diagnóstico. */\n cause?: unknown;\n /** Payload/objeto bruto retornado pelo gateway. */\n raw?: unknown;\n}\n\n/** Código normalizado de erro, estável entre gateways. */\nexport type GatewayErrorCode =\n | 'card_declined'\n | 'authentication'\n | 'rate_limit'\n | 'validation'\n | 'unsupported_capability'\n | 'gateway_unavailable'\n | 'unknown';\n\n/** Base de todos os erros normalizados da lib. */\nexport abstract class GatewayError extends Error {\n abstract readonly code: GatewayErrorCode;\n readonly raw?: unknown;\n\n constructor(\n readonly provider: Provider,\n message: string,\n options: GatewayErrorOptions = {},\n ) {\n super(message, { cause: options.cause });\n this.name = new.target.name;\n this.raw = options.raw;\n }\n}\n\nexport class CardDeclinedError extends GatewayError {\n readonly code = 'card_declined';\n constructor(provider: Provider, options?: GatewayErrorOptions) {\n super(provider, 'Cartão recusado.', options);\n }\n}\n\nexport class AuthenticationError extends GatewayError {\n readonly code = 'authentication';\n constructor(provider: Provider, options?: GatewayErrorOptions) {\n super(provider, 'Falha de autenticação com o gateway.', options);\n }\n}\n\nexport class RateLimitError extends GatewayError {\n readonly code = 'rate_limit';\n constructor(provider: Provider, options?: GatewayErrorOptions) {\n super(provider, 'Limite de requisições do gateway excedido.', options);\n }\n}\n\nexport class ValidationError extends GatewayError {\n readonly code = 'validation';\n constructor(provider: Provider, message: string, options?: GatewayErrorOptions) {\n super(provider, message, options);\n }\n}\n\nexport class GatewayUnavailableError extends GatewayError {\n readonly code = 'gateway_unavailable';\n constructor(provider: Provider, options?: GatewayErrorOptions) {\n super(provider, 'Gateway indisponível.', options);\n }\n}\n\n/** Erro genérico para casos não mapeados, preservando o erro original. */\nexport class UnknownGatewayError extends GatewayError {\n readonly code = 'unknown';\n constructor(provider: Provider, message: string, options?: GatewayErrorOptions) {\n super(provider, message, options);\n }\n}\n\n/** Lançado ao chamar uma operação que o gateway não suporta. */\nexport class UnsupportedCapabilityError extends GatewayError {\n readonly code = 'unsupported_capability';\n constructor(\n provider: Provider,\n readonly capability: Capability,\n options?: GatewayErrorOptions,\n ) {\n super(\n provider,\n `O gateway \"${provider}\" não suporta a capability \"${capability}\".`,\n options,\n );\n }\n}\n","/**\n * Value object monetário em unidades mínimas (centavos), evitando erros de\n * ponto flutuante. Stripe trabalha em centavos; Asaas em decimal — os mappers\n * de cada adapter convertem para/desta representação única.\n */\nexport class Money {\n private constructor(\n readonly cents: number,\n readonly currency: string,\n ) {}\n\n static fromCents(cents: number, currency: string): Money {\n if (!Number.isInteger(cents)) {\n throw new RangeError(`Money.cents deve ser inteiro, recebido: ${cents}`);\n }\n return new Money(cents, currency.toUpperCase());\n }\n\n static fromDecimal(amount: number, currency: string): Money {\n return Money.fromCents(Math.round(amount * 100), currency);\n }\n\n toDecimal(): number {\n return this.cents / 100;\n }\n\n equals(other: Money): boolean {\n return this.cents === other.cents && this.currency === other.currency;\n }\n}\n","import type Stripe from 'stripe';\nimport { Money } from '../../domain/models/Money.js';\nimport type { Charge, ChargeStatus } from '../../domain/models/Charge.js';\nimport type { Customer } from '../../domain/models/Customer.js';\nimport type { PaymentMethod } from '../../domain/models/PaymentMethod.js';\nimport type {\n BillingInterval,\n Subscription,\n SubscriptionStatus,\n} from '../../domain/models/Subscription.js';\nimport type { WebhookEvent } from '../../domain/models/WebhookEvent.js';\nimport {\n AuthenticationError,\n CardDeclinedError,\n GatewayError,\n RateLimitError,\n UnknownGatewayError,\n ValidationError,\n} from '../../domain/errors/index.js';\n\nconst PROVIDER = 'stripe' as const;\n\nexport function toChargeStatus(pi: Stripe.PaymentIntent): ChargeStatus {\n switch (pi.status) {\n case 'succeeded':\n return 'paid';\n case 'canceled':\n return 'canceled';\n case 'requires_payment_method':\n return pi.last_payment_error ? 'failed' : 'pending';\n default:\n return 'pending';\n }\n}\n\nfunction toPaymentMethod(types: string[] | undefined): PaymentMethod {\n if (types?.includes('pix')) return 'pix';\n if (types?.includes('boleto')) return 'boleto';\n return 'card';\n}\n\nfunction customerId(\n customer: string | Stripe.Customer | Stripe.DeletedCustomer | null,\n): string | undefined {\n if (!customer) return undefined;\n return typeof customer === 'string' ? customer : customer.id;\n}\n\nexport function toCharge(pi: Stripe.PaymentIntent): Charge {\n return {\n id: pi.id,\n status: toChargeStatus(pi),\n amount: Money.fromCents(pi.amount, pi.currency),\n paymentMethod: toPaymentMethod(pi.payment_method_types),\n customerId: customerId(pi.customer),\n description: pi.description ?? undefined,\n createdAt: new Date(pi.created * 1000),\n metadata: pi.metadata ?? undefined,\n };\n}\n\nexport function toCustomer(c: Stripe.Customer): Customer {\n return {\n id: c.id,\n name: c.name ?? '',\n email: c.email ?? undefined,\n phone: c.phone ?? undefined,\n metadata: c.metadata ?? undefined,\n };\n}\n\nfunction toSubscriptionStatus(status: Stripe.Subscription.Status): SubscriptionStatus {\n switch (status) {\n case 'active':\n case 'trialing':\n return 'active';\n case 'canceled':\n return 'canceled';\n default:\n return 'past_due';\n }\n}\n\nfunction toInterval(interval: string | undefined): BillingInterval {\n switch (interval) {\n case 'week':\n return 'weekly';\n case 'year':\n return 'yearly';\n default:\n return 'monthly';\n }\n}\n\nexport function toSubscription(sub: Stripe.Subscription): Subscription {\n const price = sub.items.data[0]?.price;\n return {\n id: sub.id,\n status: toSubscriptionStatus(sub.status),\n customerId: customerId(sub.customer) ?? '',\n amount: Money.fromCents(price?.unit_amount ?? 0, price?.currency ?? 'brl'),\n interval: toInterval(price?.recurring?.interval),\n createdAt: new Date(sub.created * 1000),\n metadata: sub.metadata ?? undefined,\n };\n}\n\n/** Traduz erros do SDK Stripe para a hierarquia normalizada. */\nexport function mapStripeError(err: unknown): GatewayError {\n const e = err as { type?: string; code?: string; message?: string };\n const opts = { cause: err, raw: err };\n switch (e.type) {\n case 'StripeCardError':\n return new CardDeclinedError(PROVIDER, opts);\n case 'StripeAuthenticationError':\n return new AuthenticationError(PROVIDER, opts);\n case 'StripeRateLimitError':\n return new RateLimitError(PROVIDER, opts);\n case 'StripeInvalidRequestError':\n return new ValidationError(PROVIDER, e.message ?? 'Requisição inválida.', opts);\n default:\n return new UnknownGatewayError(PROVIDER, e.message ?? 'Erro do Stripe.', opts);\n }\n}\n\nexport function toWebhookEvent(event: Stripe.Event): WebhookEvent {\n switch (event.type) {\n case 'payment_intent.succeeded':\n return {\n type: 'charge.paid',\n data: toCharge(event.data.object as Stripe.PaymentIntent),\n raw: event,\n };\n case 'payment_intent.payment_failed':\n return {\n type: 'charge.failed',\n data: toCharge(event.data.object as Stripe.PaymentIntent),\n raw: event,\n };\n case 'customer.subscription.deleted':\n return {\n type: 'subscription.canceled',\n data: toSubscription(event.data.object as Stripe.Subscription),\n raw: event,\n };\n default:\n return { type: 'unknown', data: null, raw: event };\n }\n}\n","/** Erro bruto de uma resposta não-2xx do Asaas, normalizado depois pelo adapter. */\nexport class AsaasApiError extends Error {\n constructor(\n readonly status: number,\n readonly body: unknown,\n ) {\n super(`Asaas API respondeu ${status}`);\n this.name = 'AsaasApiError';\n }\n}\n\n/**\n * Transporte HTTP do Asaas. É a dependência injetável do adapter (também o que\n * `raw()` devolve), o que torna o gateway testável com um fake in-memory.\n */\nexport interface AsaasHttpClient {\n get<T>(path: string): Promise<T>;\n post<T>(path: string, body?: unknown): Promise<T>;\n delete<T>(path: string): Promise<T>;\n}\n\nexport interface AsaasHttpConfig {\n apiKey: string;\n /** Base da API. Padrão: produção. Use a URL de sandbox em testes/homologação. */\n baseUrl?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.asaas.com/v3';\n\n/** Implementação padrão baseada em `fetch` (Node 18+). */\nexport function createAsaasHttpClient(config: AsaasHttpConfig): AsaasHttpClient {\n const baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n\n async function request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${baseUrl}${path}`, {\n method,\n headers: {\n access_token: config.apiKey,\n 'Content-Type': 'application/json',\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n const text = await res.text();\n const json = text ? JSON.parse(text) : {};\n if (!res.ok) {\n throw new AsaasApiError(res.status, json);\n }\n return json as T;\n }\n\n return {\n get: (path) => request('GET', path),\n post: (path, body) => request('POST', path, body),\n delete: (path) => request('DELETE', path),\n };\n}\n","import { Money } from '../../domain/models/Money.js';\nimport type { Charge, ChargeStatus } from '../../domain/models/Charge.js';\nimport type { Customer } from '../../domain/models/Customer.js';\nimport type { PaymentMethod } from '../../domain/models/PaymentMethod.js';\nimport type {\n BillingInterval,\n Subscription,\n SubscriptionStatus,\n} from '../../domain/models/Subscription.js';\nimport type { WebhookEvent } from '../../domain/models/WebhookEvent.js';\nimport {\n AuthenticationError,\n GatewayError,\n GatewayUnavailableError,\n RateLimitError,\n UnknownGatewayError,\n ValidationError,\n} from '../../domain/errors/index.js';\nimport type {\n AsaasBillingType,\n AsaasCustomer,\n AsaasCycle,\n AsaasPayment,\n AsaasSubscription,\n AsaasWebhookBody,\n} from './types.js';\n\nconst PROVIDER = 'asaas' as const;\nconst CURRENCY = 'BRL';\n\nexport function toChargeStatus(status: string): ChargeStatus {\n switch (status) {\n case 'RECEIVED':\n case 'CONFIRMED':\n case 'RECEIVED_IN_CASH':\n return 'paid';\n case 'OVERDUE':\n return 'failed';\n case 'REFUNDED':\n case 'REFUND_REQUESTED':\n return 'refunded';\n default:\n return 'pending';\n }\n}\n\nfunction toPaymentMethod(billingType: AsaasBillingType): PaymentMethod {\n switch (billingType) {\n case 'PIX':\n return 'pix';\n case 'BOLETO':\n return 'boleto';\n default:\n return 'card';\n }\n}\n\nexport function toCharge(p: AsaasPayment): Charge {\n return {\n id: p.id,\n status: toChargeStatus(p.status),\n amount: Money.fromDecimal(p.value, CURRENCY),\n paymentMethod: toPaymentMethod(p.billingType),\n customerId: p.customer,\n description: p.description ?? undefined,\n boleto: p.bankSlipUrl ? { url: p.bankSlipUrl } : undefined,\n createdAt: new Date(p.dateCreated),\n };\n}\n\nexport function toCustomer(c: AsaasCustomer): Customer {\n return {\n id: c.id,\n name: c.name,\n email: c.email ?? undefined,\n taxId: c.cpfCnpj ?? undefined,\n phone: c.phone ?? c.mobilePhone ?? undefined,\n };\n}\n\nfunction toSubscriptionStatus(status: string): SubscriptionStatus {\n switch (status) {\n case 'ACTIVE':\n return 'active';\n case 'EXPIRED':\n return 'past_due';\n default:\n return 'canceled';\n }\n}\n\nfunction toInterval(cycle: AsaasCycle): BillingInterval {\n switch (cycle) {\n case 'WEEKLY':\n return 'weekly';\n case 'YEARLY':\n return 'yearly';\n default:\n return 'monthly';\n }\n}\n\nexport function toSubscription(s: AsaasSubscription): Subscription {\n return {\n id: s.id,\n status: toSubscriptionStatus(s.status),\n customerId: s.customer,\n amount: Money.fromDecimal(s.value, CURRENCY),\n interval: toInterval(s.cycle),\n createdAt: new Date(s.dateCreated),\n };\n}\n\ninterface AsaasErrorBody {\n errors?: Array<{ code?: string; description?: string }>;\n}\n\n/** Traduz uma resposta de erro do Asaas (status HTTP + corpo) para a hierarquia normalizada. */\nexport function mapAsaasError(status: number, body: AsaasErrorBody): GatewayError {\n const description = body.errors?.[0]?.description;\n const opts = { raw: body };\n if (status === 401 || status === 403) return new AuthenticationError(PROVIDER, opts);\n if (status === 429) return new RateLimitError(PROVIDER, opts);\n if (status >= 500) return new GatewayUnavailableError(PROVIDER, opts);\n if (status === 400) {\n return new ValidationError(PROVIDER, description ?? 'Requisição inválida.', opts);\n }\n return new UnknownGatewayError(PROVIDER, description ?? 'Erro do Asaas.', opts);\n}\n\nexport function toWebhookEvent(body: AsaasWebhookBody): WebhookEvent {\n const payment = body.payment;\n switch (body.event) {\n case 'PAYMENT_RECEIVED':\n case 'PAYMENT_CONFIRMED':\n return { type: 'charge.paid', data: toCharge(payment!), raw: body };\n case 'PAYMENT_OVERDUE':\n return { type: 'charge.failed', data: toCharge(payment!), raw: body };\n case 'PAYMENT_REFUNDED':\n return { type: 'charge.refunded', data: toCharge(payment!), raw: body };\n default:\n return { type: 'unknown', data: null, raw: body };\n }\n}\n","import { Capability } from '../../domain/capabilities/Capability.js';\nimport {\n GatewayError,\n UnknownGatewayError,\n ValidationError,\n} from '../../domain/errors/index.js';\nimport type {\n Charge,\n CreateChargeInput,\n RefundChargeInput,\n} from '../../domain/models/Charge.js';\nimport type {\n CreateCustomerInput,\n Customer,\n UpdateCustomerInput,\n} from '../../domain/models/Customer.js';\nimport type { PaymentMethod } from '../../domain/models/PaymentMethod.js';\nimport type {\n BillingInterval,\n CreateSubscriptionInput,\n Subscription,\n} from '../../domain/models/Subscription.js';\nimport type {\n WebhookEvent,\n WebhookInput,\n} from '../../domain/models/WebhookEvent.js';\nimport type {\n ChargePort,\n CustomerPort,\n PaymentGateway,\n SubscriptionPort,\n WebhookPort,\n} from '../../domain/ports/index.js';\nimport {\n AsaasApiError,\n type AsaasHttpClient,\n type AsaasHttpConfig,\n createAsaasHttpClient,\n} from './AsaasHttpClient.js';\nimport {\n mapAsaasError,\n toCharge,\n toCustomer,\n toSubscription,\n toWebhookEvent,\n} from './mappers.js';\nimport type {\n AsaasBillingType,\n AsaasCustomer,\n AsaasCycle,\n AsaasPayment,\n AsaasSubscription,\n AsaasWebhookBody,\n} from './types.js';\n\nexport interface AsaasGatewayConfig extends AsaasHttpConfig {\n /** Token configurado no Asaas para autenticar webhooks recebidos. */\n webhookToken?: string;\n}\n\nconst PROVIDER = 'asaas' as const;\n\nconst BILLING_TYPE: Record<PaymentMethod, AsaasBillingType> = {\n pix: 'PIX',\n boleto: 'BOLETO',\n card: 'CREDIT_CARD',\n};\n\nconst ASAAS_CYCLE: Record<BillingInterval, AsaasCycle> = {\n weekly: 'WEEKLY',\n monthly: 'MONTHLY',\n yearly: 'YEARLY',\n};\n\nfunction today(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\n/** Reexecuta a operação traduzindo erros do Asaas para a hierarquia normalizada. */\nasync function normalizeErrors<T>(fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (err) {\n if (err instanceof GatewayError) throw err;\n if (err instanceof AsaasApiError) throw mapAsaasError(err.status, err.body as object);\n throw new UnknownGatewayError(PROVIDER, 'Erro inesperado no Asaas.', { cause: err });\n }\n}\n\nfunction isNotFound(err: unknown): boolean {\n return err instanceof AsaasApiError && err.status === 404;\n}\n\nexport class AsaasGateway implements PaymentGateway<AsaasHttpClient> {\n readonly provider = PROVIDER;\n readonly capabilities: ReadonlySet<Capability> = new Set([\n Capability.PIX,\n Capability.BOLETO,\n Capability.CARD,\n Capability.REFUND,\n Capability.SUBSCRIPTIONS,\n ]);\n\n private readonly http: AsaasHttpClient;\n\n readonly customers: CustomerPort;\n readonly charges: ChargePort;\n readonly subscriptions: SubscriptionPort;\n readonly webhooks: WebhookPort;\n\n constructor(\n private readonly config: AsaasGatewayConfig,\n http?: AsaasHttpClient,\n ) {\n this.http = http ?? createAsaasHttpClient(config);\n this.customers = this.buildCustomerPort();\n this.charges = this.buildChargePort();\n this.subscriptions = this.buildSubscriptionPort();\n this.webhooks = this.buildWebhookPort();\n }\n\n supports(capability: Capability): boolean {\n return this.capabilities.has(capability);\n }\n\n raw(): AsaasHttpClient {\n return this.http;\n }\n\n private buildCustomerPort(): CustomerPort {\n const http = this.http;\n return {\n create: (input: CreateCustomerInput) =>\n normalizeErrors(async () =>\n toCustomer(\n await http.post<AsaasCustomer>('/customers', {\n name: input.name,\n email: input.email,\n cpfCnpj: input.taxId,\n mobilePhone: input.phone,\n externalReference: input.idempotencyKey,\n }),\n ),\n ),\n get: async (id: string): Promise<Customer | null> => {\n try {\n return toCustomer(await http.get<AsaasCustomer>(`/customers/${id}`));\n } catch (err) {\n if (isNotFound(err)) return null;\n throw mapAsaasError((err as AsaasApiError).status, (err as AsaasApiError).body as object);\n }\n },\n update: (id: string, input: UpdateCustomerInput) =>\n normalizeErrors(async () =>\n toCustomer(\n await http.post<AsaasCustomer>(`/customers/${id}`, {\n name: input.name,\n email: input.email,\n cpfCnpj: input.taxId,\n mobilePhone: input.phone,\n }),\n ),\n ),\n delete: (id: string) =>\n normalizeErrors(async () => {\n await http.delete(`/customers/${id}`);\n }),\n };\n }\n\n private buildChargePort(): ChargePort {\n const http = this.http;\n return {\n create: (input: CreateChargeInput): Promise<Charge> =>\n normalizeErrors(async () =>\n toCharge(\n await http.post<AsaasPayment>('/payments', {\n customer: input.customerId,\n billingType: BILLING_TYPE[input.paymentMethod],\n value: input.amount.toDecimal(),\n dueDate: (input.dueDate ?? new Date()).toISOString().slice(0, 10),\n description: input.description,\n creditCardToken: input.cardToken,\n remoteIp: input.remoteIp,\n externalReference: input.idempotencyKey,\n }),\n ),\n ),\n get: async (id: string): Promise<Charge | null> => {\n try {\n return toCharge(await http.get<AsaasPayment>(`/payments/${id}`));\n } catch (err) {\n if (isNotFound(err)) return null;\n throw mapAsaasError((err as AsaasApiError).status, (err as AsaasApiError).body as object);\n }\n },\n cancel: (id: string) =>\n normalizeErrors(async () => {\n const payment = await http.get<AsaasPayment>(`/payments/${id}`);\n await http.delete(`/payments/${id}`);\n return { ...toCharge(payment), status: 'canceled' as const };\n }),\n refund: (input: RefundChargeInput): Promise<Charge> =>\n normalizeErrors(async () =>\n toCharge(\n await http.post<AsaasPayment>(`/payments/${input.chargeId}/refund`, {\n value: input.amount?.toDecimal(),\n }),\n ),\n ),\n };\n }\n\n private buildSubscriptionPort(): SubscriptionPort {\n const http = this.http;\n return {\n create: (input: CreateSubscriptionInput): Promise<Subscription> =>\n normalizeErrors(async () =>\n toSubscription(\n await http.post<AsaasSubscription>('/subscriptions', {\n customer: input.customerId,\n billingType: BILLING_TYPE[input.paymentMethod],\n value: input.amount.toDecimal(),\n cycle: ASAAS_CYCLE[input.interval],\n nextDueDate: today(),\n creditCardToken: input.cardToken,\n externalReference: input.idempotencyKey,\n }),\n ),\n ),\n get: async (id: string): Promise<Subscription | null> => {\n try {\n return toSubscription(await http.get<AsaasSubscription>(`/subscriptions/${id}`));\n } catch (err) {\n if (isNotFound(err)) return null;\n throw mapAsaasError((err as AsaasApiError).status, (err as AsaasApiError).body as object);\n }\n },\n cancel: (id: string) =>\n normalizeErrors(async () => {\n const sub = await http.get<AsaasSubscription>(`/subscriptions/${id}`);\n await http.delete(`/subscriptions/${id}`);\n return { ...toSubscription(sub), status: 'canceled' as const };\n }),\n };\n }\n\n private buildWebhookPort(): WebhookPort {\n const expectedToken = this.config.webhookToken;\n return {\n verifyAndParse: (input: WebhookInput): WebhookEvent => {\n const received = input.headers['asaas-access-token'];\n if (!expectedToken || received !== expectedToken) {\n throw new ValidationError(PROVIDER, 'Token de webhook do Asaas inválido.');\n }\n const body = JSON.parse(input.payload.toString()) as AsaasWebhookBody;\n return toWebhookEvent(body);\n },\n };\n }\n}\n","import type { DomGatewayConfig } from './types.js';\n\nexport class DomHttpClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n\n constructor(config: DomGatewayConfig) {\n this.baseUrl = config.baseUrl ?? 'https://apiv3.dompagamentos.com.br/checkout/production';\n this.apiKey = config.apiKey;\n }\n\n private async request<T>(path: string, options: RequestInit): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`DOM API Error: ${response.status} ${response.statusText} - ${body}`);\n }\n if (response.status === 204) {\n return {} as T;\n }\n\n return (await response.json()) as T;\n }\n\n public async get<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'GET' });\n }\n\n public async post<T>(path: string, body?: any): Promise<T> {\n return this.request<T>(path, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n public async put<T>(path: string, body?: any): Promise<T> {\n return this.request<T>(path, {\n method: 'PUT',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n public async delete<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'DELETE' });\n }\n}\n","import type { Charge, ChargeStatus } from '../../domain/models/Charge.js';\nimport type { Customer } from '../../domain/models/Customer.js';\nimport { Money } from '../../domain/models/Money.js';\n\nexport function toDomCustomer(input: any): any {\n const data: any = {\n name: input.name,\n email: input.email,\n mobile_phone: input.phone || '00000000000',\n code_external: input.metadata?.code_external\n };\n\n if (input.taxId) {\n data.document = input.taxId;\n data.document_type = input.taxId.length === 11 ? 'CPF' : 'CNPJ';\n }\n\n return data;\n}\n\nexport function toDomainCustomer(domCustomer: any): Customer {\n return {\n id: domCustomer.id,\n name: domCustomer.name,\n email: domCustomer.email,\n taxId: domCustomer.document,\n phone: domCustomer.mobile_phone,\n metadata: domCustomer.code_external ? { code_external: domCustomer.code_external } : undefined,\n };\n}\n\nexport function mapDomStatus(domStatus: string): ChargeStatus {\n switch (domStatus) {\n case 'pending': return 'pending';\n case 'paid': return 'paid';\n case 'canceled': return 'canceled';\n case 'failed': return 'failed';\n case 'refunded': return 'refunded';\n default: return 'pending';\n }\n}\n\nexport function toDomainCharge(domTransaction: any): Charge {\n return {\n id: domTransaction.id,\n status: mapDomStatus(domTransaction.status),\n amount: Money.fromCents(domTransaction.amount, domTransaction.currency || 'BRL'),\n paymentMethod: domTransaction.payment_method === 'credit_card' ? 'card' : domTransaction.payment_method,\n customerId: domTransaction.customer?.id,\n description: domTransaction.items?.[0]?.description,\n createdAt: new Date(domTransaction.created_at),\n boleto: domTransaction.payment_method === 'boleto' ? {\n url: domTransaction.boleto_url,\n barcode: domTransaction.boleto_digitable_line,\n } : undefined,\n pix: domTransaction.payment_method === 'pix' ? {\n copyPaste: domTransaction.pix_content,\n qrCode: domTransaction.pix_qrcode,\n } : undefined,\n };\n}\n\nexport function toWebhookEvent(payload: any): any {\n const transaction = payload.data?.transaction;\n if (!transaction) return { type: 'unknown', data: null, raw: payload };\n\n const charge = toDomainCharge(transaction);\n\n switch (payload.event) {\n case 'transaction.paid':\n return { type: 'charge.paid', data: charge, raw: payload };\n case 'transaction.failed':\n return { type: 'charge.failed', data: charge, raw: payload };\n case 'transaction.refunded':\n return { type: 'charge.refunded', data: charge, raw: payload };\n default:\n return { type: 'unknown', data: null, raw: payload };\n }\n}\n","import type {\n ChargePort,\n CustomerPort,\n SubscriptionPort,\n WebhookPort,\n} from '../../domain/ports/index.js';\nimport type { CreateChargeInput, RefundChargeInput, Charge } from '../../domain/models/Charge.js';\nimport type { CreateCustomerInput, UpdateCustomerInput, Customer } from '../../domain/models/Customer.js';\nimport type { CreateSubscriptionInput, Subscription } from '../../domain/models/Subscription.js';\nimport type { WebhookEvent, WebhookInput } from '../../domain/models/WebhookEvent.js';\nimport type { DomHttpClient } from './DomHttpClient.js';\nimport { UnknownGatewayError, ValidationError } from '../../domain/errors/index.js';\nimport { toDomCustomer, toDomainCustomer, toDomainCharge, toWebhookEvent } from './mappers.js';\n\nconst PROVIDER = 'dom';\n\nexport function buildDomCustomerPort(http: DomHttpClient): CustomerPort {\n return {\n create: async (input: CreateCustomerInput): Promise<Customer> => {\n const response = await http.post<any>('/customers', toDomCustomer(input));\n return toDomainCustomer(response);\n },\n get: async (id: string): Promise<Customer | null> => {\n try {\n const response = await http.get<any>(`/customers/${id}`);\n return toDomainCustomer(response);\n } catch (err: any) {\n if (err.message.includes('404')) return null;\n throw err;\n }\n },\n update: async (id: string, input: UpdateCustomerInput): Promise<Customer> => {\n\n const response = await http.post<any>(`/customers/${id}`, toDomCustomer(input));\n return toDomainCustomer(response);\n },\n delete: async (id: string): Promise<void> => {\n await http.delete(`/customers/${id}`);\n },\n };\n}\n\nexport function buildDomChargePort(http: DomHttpClient, customerPort: CustomerPort): ChargePort {\n return {\n create: async (input: CreateChargeInput): Promise<Charge> => {\n let customerData: any;\n if (!input.cardToken) {\n const c = await customerPort.get(input.customerId);\n if (!c) throw new Error('Cliente não encontrado para criar transação (DOM Pagamentos exige customer para Pix/Boleto)');\n customerData = toDomCustomer({ ...c, phone: c.phone || '00000000000', taxId: c.taxId });\n }\n\n const isBoleto = input.paymentMethod === 'boleto';\n const isPix = input.paymentMethod === 'pix';\n const isCard = input.paymentMethod === 'card';\n\n const payload: any = {\n cod_external: input.metadata?.cod_external || input.idempotencyKey,\n items: [{ description: input.description || 'Cobrança', price: input.amount.toDecimal(), quantity: 1 }],\n payment: {\n total: input.amount.toDecimal(),\n payment_method: isCard ? 'credit_card' : input.paymentMethod,\n }\n };\n\n if (customerData) payload.customer = customerData;\n if (isCard && input.cardToken) payload.payment.credit_card = { token: input.cardToken, installments: 1 };\n if (isBoleto) payload.payment.boleto = { boleto_due_days: 3 };\n if (isPix) payload.payment.pix = {}; \n\n const response = await http.post<any>('/transactions', payload);\n return toDomainCharge(response);\n },\n get: async (id: string): Promise<Charge | null> => {\n try {\n const response = await http.get<any>(`/transactions/${id}`);\n return toDomainCharge(response);\n } catch (err: any) {\n if (err.message.includes('404')) return null;\n throw err;\n }\n },\n cancel: async (id: string): Promise<Charge> => {\n const response = await http.post<any>(`/transactions/${id}/cancel`);\n return toDomainCharge(response);\n },\n refund: async (input: RefundChargeInput): Promise<Charge> => {\n const payload: any = {};\n if (input.amount) {\n payload.amount = input.amount.toDecimal();\n }\n const response = await http.post<any>(`/transactions/${input.chargeId}/refund`, payload);\n return toDomainCharge(response);\n },\n };\n}\n\nexport function buildDomSubscriptionPort(http: DomHttpClient): SubscriptionPort {\n return {\n create: async (input: CreateSubscriptionInput): Promise<Subscription> => {\n throw new UnknownGatewayError(PROVIDER, 'DOM SubscriptionPort.create não implementado.', { cause: null });\n },\n get: async (id: string): Promise<Subscription | null> => {\n throw new UnknownGatewayError(PROVIDER, 'DOM SubscriptionPort.get não implementado.', { cause: null });\n },\n cancel: async (id: string): Promise<Subscription> => {\n throw new UnknownGatewayError(PROVIDER, 'DOM SubscriptionPort.cancel não implementado.', { cause: null });\n },\n };\n}\n\nexport function buildDomWebhookPort(webhookSecret?: string): WebhookPort {\n return {\n verifyAndParse: (input: WebhookInput): WebhookEvent => {\n\n const receivedToken = input.headers['authorization'] || input.headers['x-dom-token'];\n \n if (webhookSecret && receivedToken !== webhookSecret) {\n throw new ValidationError(PROVIDER, 'Token de webhook inválido.');\n }\n\n const payload = typeof input.payload === 'string' \n ? JSON.parse(input.payload) \n : JSON.parse(input.payload.toString());\n\n return toWebhookEvent(payload);\n },\n };\n}\n ","import { Capability } from '../../domain/capabilities/Capability.js';\nimport type {\n ChargePort,\n CustomerPort,\n PaymentGateway,\n SubscriptionPort,\n WebhookPort,\n} from '../../domain/ports/index.js';\nimport type { DomGatewayConfig } from './types.js';\nimport { DomHttpClient } from './DomHttpClient.js';\nimport {\n buildDomChargePort,\n buildDomCustomerPort,\n buildDomSubscriptionPort,\n buildDomWebhookPort,\n} from './ports.js';\n\nconst PROVIDER = 'dom' as const;\n\nexport class DomGateway implements PaymentGateway<DomHttpClient> {\n readonly provider = PROVIDER;\n\n readonly capabilities: ReadonlySet<Capability> = new Set([\n Capability.PIX,\n Capability.CARD,\n Capability.BOLETO,\n Capability.REFUND,\n ]);\n\n private readonly http: DomHttpClient;\n\n readonly customers: CustomerPort;\n readonly charges: ChargePort;\n readonly subscriptions: SubscriptionPort;\n readonly webhooks: WebhookPort;\n\n constructor(\n private readonly config: DomGatewayConfig,\n http?: DomHttpClient,\n ) {\n this.http = http ?? new DomHttpClient(config);\n\n this.customers = buildDomCustomerPort(this.http);\n this.charges = buildDomChargePort(this.http, this.customers);\n this.subscriptions = buildDomSubscriptionPort(this.http);\n this.webhooks = buildDomWebhookPort(config.webhookToken);\n }\n\n supports(capability: Capability): boolean {\n return this.capabilities.has(capability);\n }\n\n raw(): DomHttpClient {\n return this.http;\n }\n}","import type { PaymentGateway } from './domain/ports/index.js';\nimport { StripeGateway, type StripeGatewayConfig } from './adapters/stripe/StripeGateway.js';\nimport { AsaasGateway, type AsaasGatewayConfig } from './adapters/asaas/AsaasGateway.js';\nimport { DomGateway } from './adapters/dom/DomGateway.js';\nimport type { DomGatewayConfig } from './adapters/dom/types.js';\n\n/**\n * Configuração discriminada por `provider`. Adicionar um novo gateway começa\n * por estender esta união e o `switch` em `createGateway`.\n */\nexport type GatewayConfig =\n | ({ provider: 'stripe' } & StripeGatewayConfig)\n | ({ provider: 'asaas' } & AsaasGatewayConfig)\n | ({ provider: 'dom' } & DomGatewayConfig);\n\n/** Ponto de entrada: instancia o adapter correto a partir da config. */\nexport function createGateway(config: GatewayConfig): PaymentGateway {\n switch (config.provider) {\n case 'stripe':\n return new StripeGateway(config);\n case 'asaas':\n return new AsaasGateway(config);\n case 'dom':\n return new DomGateway(config);\n default: {\n const exhaustive: never = config;\n throw new Error(`Provider não suportado: ${JSON.stringify(exhaustive)}`);\n }\n }\n}\n"],"mappings":"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","names":["PROVIDER","Stripe","PROVIDER","toChargeStatus","toPaymentMethod","toCharge","toCustomer","toSubscriptionStatus","toInterval","toSubscription","toWebhookEvent","PROVIDER","normalizeErrors","toCustomer","toCharge","toSubscription","toWebhookEvent","toWebhookEvent","PROVIDER","toWebhookEvent","PROVIDER"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import Stripe from 'stripe';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Recursos que um gateway pode ou não suportar. Cada adapter declara seu
|
|
5
|
+
* conjunto; o consumidor checa antes de chamar, evitando erros crus do gateway.
|
|
6
|
+
*/
|
|
7
|
+
declare const Capability: {
|
|
8
|
+
readonly PIX: "pix";
|
|
9
|
+
readonly BOLETO: "boleto";
|
|
10
|
+
readonly CARD: "card";
|
|
11
|
+
readonly REFUND: "refund";
|
|
12
|
+
readonly SUBSCRIPTIONS: "subscriptions";
|
|
13
|
+
};
|
|
14
|
+
type Capability = (typeof Capability)[keyof typeof Capability];
|
|
15
|
+
declare function hasCapability(caps: ReadonlySet<Capability>, capability: Capability): boolean;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Value object monetário em unidades mínimas (centavos), evitando erros de
|
|
19
|
+
* ponto flutuante. Stripe trabalha em centavos; Asaas em decimal — os mappers
|
|
20
|
+
* de cada adapter convertem para/desta representação única.
|
|
21
|
+
*/
|
|
22
|
+
declare class Money {
|
|
23
|
+
readonly cents: number;
|
|
24
|
+
readonly currency: string;
|
|
25
|
+
private constructor();
|
|
26
|
+
static fromCents(cents: number, currency: string): Money;
|
|
27
|
+
static fromDecimal(amount: number, currency: string): Money;
|
|
28
|
+
toDecimal(): number;
|
|
29
|
+
equals(other: Money): boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Meio de pagamento normalizado entre gateways. */
|
|
33
|
+
type PaymentMethod = 'pix' | 'boleto' | 'card';
|
|
34
|
+
|
|
35
|
+
type ChargeStatus = 'pending' | 'paid' | 'failed' | 'refunded' | 'canceled';
|
|
36
|
+
/** Dados extras de PIX, presentes quando o meio é 'pix'. */
|
|
37
|
+
interface PixDetails {
|
|
38
|
+
qrCode?: string;
|
|
39
|
+
copyPaste?: string;
|
|
40
|
+
expiresAt?: Date;
|
|
41
|
+
}
|
|
42
|
+
/** Dados extras de boleto, presentes quando o meio é 'boleto'. */
|
|
43
|
+
interface BoletoDetails {
|
|
44
|
+
url?: string;
|
|
45
|
+
barcode?: string;
|
|
46
|
+
dueDate?: Date;
|
|
47
|
+
}
|
|
48
|
+
/** Cobrança avulsa normalizada. */
|
|
49
|
+
interface Charge {
|
|
50
|
+
id: string;
|
|
51
|
+
status: ChargeStatus;
|
|
52
|
+
amount: Money;
|
|
53
|
+
paymentMethod: PaymentMethod;
|
|
54
|
+
customerId?: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
pix?: PixDetails;
|
|
57
|
+
boleto?: BoletoDetails;
|
|
58
|
+
createdAt: Date;
|
|
59
|
+
metadata?: Record<string, string>;
|
|
60
|
+
}
|
|
61
|
+
interface CreateChargeInput {
|
|
62
|
+
amount: Money;
|
|
63
|
+
paymentMethod: PaymentMethod;
|
|
64
|
+
customerId: string;
|
|
65
|
+
description?: string;
|
|
66
|
+
/** Token de cartão (quando paymentMethod === 'card'). */
|
|
67
|
+
cardToken?: string;
|
|
68
|
+
/** Vencimento (boleto). */
|
|
69
|
+
dueDate?: Date;
|
|
70
|
+
/** IP do pagador. Exigido pelo Asaas em cobranças de cartão (anti-fraude). */
|
|
71
|
+
remoteIp?: string;
|
|
72
|
+
/** Chave de idempotência para evitar cobranças duplicadas. */
|
|
73
|
+
idempotencyKey?: string;
|
|
74
|
+
metadata?: Record<string, string>;
|
|
75
|
+
}
|
|
76
|
+
interface RefundChargeInput {
|
|
77
|
+
chargeId: string;
|
|
78
|
+
/** Estorno parcial; ausente = estorno total. */
|
|
79
|
+
amount?: Money;
|
|
80
|
+
idempotencyKey?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Cliente normalizado, como representado dentro do gateway. */
|
|
84
|
+
interface Customer {
|
|
85
|
+
/** Identificador do cliente no gateway. */
|
|
86
|
+
id: string;
|
|
87
|
+
name: string;
|
|
88
|
+
email?: string;
|
|
89
|
+
/** CPF/CNPJ. Obrigatório em alguns gateways (ex.: Asaas). */
|
|
90
|
+
taxId?: string;
|
|
91
|
+
phone?: string;
|
|
92
|
+
metadata?: Record<string, string>;
|
|
93
|
+
}
|
|
94
|
+
interface CreateCustomerInput {
|
|
95
|
+
name: string;
|
|
96
|
+
email?: string;
|
|
97
|
+
taxId?: string;
|
|
98
|
+
phone?: string;
|
|
99
|
+
idempotencyKey?: string;
|
|
100
|
+
metadata?: Record<string, string>;
|
|
101
|
+
}
|
|
102
|
+
interface UpdateCustomerInput {
|
|
103
|
+
name?: string;
|
|
104
|
+
email?: string;
|
|
105
|
+
taxId?: string;
|
|
106
|
+
phone?: string;
|
|
107
|
+
metadata?: Record<string, string>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Gateways suportados. Adicionar um novo gateway começa por aqui. */
|
|
111
|
+
type Provider = "asaas" | "stripe" | "dom";
|
|
112
|
+
|
|
113
|
+
type SubscriptionStatus = 'active' | 'canceled' | 'past_due';
|
|
114
|
+
type BillingInterval = 'weekly' | 'monthly' | 'yearly';
|
|
115
|
+
/** Assinatura recorrente normalizada. */
|
|
116
|
+
interface Subscription {
|
|
117
|
+
id: string;
|
|
118
|
+
status: SubscriptionStatus;
|
|
119
|
+
customerId: string;
|
|
120
|
+
amount: Money;
|
|
121
|
+
interval: BillingInterval;
|
|
122
|
+
createdAt: Date;
|
|
123
|
+
metadata?: Record<string, string>;
|
|
124
|
+
}
|
|
125
|
+
interface CreateSubscriptionInput {
|
|
126
|
+
customerId: string;
|
|
127
|
+
amount: Money;
|
|
128
|
+
interval: BillingInterval;
|
|
129
|
+
paymentMethod: PaymentMethod;
|
|
130
|
+
/** Token de cartão (quando paymentMethod === 'card'). */
|
|
131
|
+
cardToken?: string;
|
|
132
|
+
idempotencyKey?: string;
|
|
133
|
+
metadata?: Record<string, string>;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Evento de webhook normalizado entre gateways. O campo `raw` sempre preserva
|
|
138
|
+
* o payload original; eventos não reconhecidos viram `type: 'unknown'` em vez
|
|
139
|
+
* de serem engolidos ou de quebrarem o processamento.
|
|
140
|
+
*/
|
|
141
|
+
type WebhookEvent = {
|
|
142
|
+
type: 'charge.paid';
|
|
143
|
+
data: Charge;
|
|
144
|
+
raw: unknown;
|
|
145
|
+
} | {
|
|
146
|
+
type: 'charge.failed';
|
|
147
|
+
data: Charge;
|
|
148
|
+
raw: unknown;
|
|
149
|
+
} | {
|
|
150
|
+
type: 'charge.refunded';
|
|
151
|
+
data: Charge;
|
|
152
|
+
raw: unknown;
|
|
153
|
+
} | {
|
|
154
|
+
type: 'subscription.renewed';
|
|
155
|
+
data: Subscription;
|
|
156
|
+
raw: unknown;
|
|
157
|
+
} | {
|
|
158
|
+
type: 'subscription.canceled';
|
|
159
|
+
data: Subscription;
|
|
160
|
+
raw: unknown;
|
|
161
|
+
} | {
|
|
162
|
+
type: 'unknown';
|
|
163
|
+
data: null;
|
|
164
|
+
raw: unknown;
|
|
165
|
+
};
|
|
166
|
+
type WebhookEventType = WebhookEvent['type'];
|
|
167
|
+
/** Entrada para verificação + parsing de um webhook recebido. */
|
|
168
|
+
interface WebhookInput {
|
|
169
|
+
/** Corpo bruto da requisição (string ou Buffer), necessário p/ verificar assinatura. */
|
|
170
|
+
payload: string | Buffer;
|
|
171
|
+
headers: Record<string, string>;
|
|
172
|
+
/** Segredo de verificação (signing secret do Stripe, token do Asaas). */
|
|
173
|
+
secret: string;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
interface CustomerPort {
|
|
177
|
+
create(input: CreateCustomerInput): Promise<Customer>;
|
|
178
|
+
get(id: string): Promise<Customer | null>;
|
|
179
|
+
update(id: string, input: UpdateCustomerInput): Promise<Customer>;
|
|
180
|
+
delete(id: string): Promise<void>;
|
|
181
|
+
}
|
|
182
|
+
interface ChargePort {
|
|
183
|
+
create(input: CreateChargeInput): Promise<Charge>;
|
|
184
|
+
get(id: string): Promise<Charge | null>;
|
|
185
|
+
cancel(id: string): Promise<Charge>;
|
|
186
|
+
refund(input: RefundChargeInput): Promise<Charge>;
|
|
187
|
+
}
|
|
188
|
+
interface SubscriptionPort {
|
|
189
|
+
create(input: CreateSubscriptionInput): Promise<Subscription>;
|
|
190
|
+
get(id: string): Promise<Subscription | null>;
|
|
191
|
+
cancel(id: string): Promise<Subscription>;
|
|
192
|
+
}
|
|
193
|
+
interface WebhookPort {
|
|
194
|
+
/** Verifica a assinatura e normaliza o evento recebido. */
|
|
195
|
+
verifyAndParse(input: WebhookInput): WebhookEvent;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Porta principal: contrato comum implementado por todos os adapters.
|
|
199
|
+
*
|
|
200
|
+
* `TRaw` é o tipo do client nativo do gateway, exposto pelo escape hatch
|
|
201
|
+
* `raw()` para recursos exclusivos que o contrato comum não cobre.
|
|
202
|
+
*/
|
|
203
|
+
interface PaymentGateway<TRaw = unknown> {
|
|
204
|
+
readonly provider: Provider;
|
|
205
|
+
readonly capabilities: ReadonlySet<Capability>;
|
|
206
|
+
supports(capability: Capability): boolean;
|
|
207
|
+
readonly customers: CustomerPort;
|
|
208
|
+
readonly charges: ChargePort;
|
|
209
|
+
readonly subscriptions: SubscriptionPort;
|
|
210
|
+
readonly webhooks: WebhookPort;
|
|
211
|
+
/** Escape hatch: client nativo do gateway, tipado por adapter. */
|
|
212
|
+
raw(): TRaw;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
interface StripeGatewayConfig {
|
|
216
|
+
apiKey: string;
|
|
217
|
+
/** Signing secret para verificar webhooks. */
|
|
218
|
+
webhookSecret?: string;
|
|
219
|
+
}
|
|
220
|
+
declare class StripeGateway implements PaymentGateway<Stripe> {
|
|
221
|
+
private readonly config;
|
|
222
|
+
readonly provider: "stripe";
|
|
223
|
+
readonly capabilities: ReadonlySet<Capability>;
|
|
224
|
+
private readonly client;
|
|
225
|
+
readonly customers: CustomerPort;
|
|
226
|
+
readonly charges: ChargePort;
|
|
227
|
+
readonly subscriptions: SubscriptionPort;
|
|
228
|
+
readonly webhooks: WebhookPort;
|
|
229
|
+
constructor(config: StripeGatewayConfig, client?: Stripe);
|
|
230
|
+
supports(capability: Capability): boolean;
|
|
231
|
+
raw(): Stripe;
|
|
232
|
+
private requireMethod;
|
|
233
|
+
private buildCustomerPort;
|
|
234
|
+
private buildChargePort;
|
|
235
|
+
private buildSubscriptionPort;
|
|
236
|
+
private buildWebhookPort;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Erro bruto de uma resposta não-2xx do Asaas, normalizado depois pelo adapter. */
|
|
240
|
+
declare class AsaasApiError extends Error {
|
|
241
|
+
readonly status: number;
|
|
242
|
+
readonly body: unknown;
|
|
243
|
+
constructor(status: number, body: unknown);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Transporte HTTP do Asaas. É a dependência injetável do adapter (também o que
|
|
247
|
+
* `raw()` devolve), o que torna o gateway testável com um fake in-memory.
|
|
248
|
+
*/
|
|
249
|
+
interface AsaasHttpClient {
|
|
250
|
+
get<T>(path: string): Promise<T>;
|
|
251
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
252
|
+
delete<T>(path: string): Promise<T>;
|
|
253
|
+
}
|
|
254
|
+
interface AsaasHttpConfig {
|
|
255
|
+
apiKey: string;
|
|
256
|
+
/** Base da API. Padrão: produção. Use a URL de sandbox em testes/homologação. */
|
|
257
|
+
baseUrl?: string;
|
|
258
|
+
}
|
|
259
|
+
/** Implementação padrão baseada em `fetch` (Node 18+). */
|
|
260
|
+
declare function createAsaasHttpClient(config: AsaasHttpConfig): AsaasHttpClient;
|
|
261
|
+
|
|
262
|
+
interface AsaasGatewayConfig extends AsaasHttpConfig {
|
|
263
|
+
/** Token configurado no Asaas para autenticar webhooks recebidos. */
|
|
264
|
+
webhookToken?: string;
|
|
265
|
+
}
|
|
266
|
+
declare class AsaasGateway implements PaymentGateway<AsaasHttpClient> {
|
|
267
|
+
private readonly config;
|
|
268
|
+
readonly provider: "asaas";
|
|
269
|
+
readonly capabilities: ReadonlySet<Capability>;
|
|
270
|
+
private readonly http;
|
|
271
|
+
readonly customers: CustomerPort;
|
|
272
|
+
readonly charges: ChargePort;
|
|
273
|
+
readonly subscriptions: SubscriptionPort;
|
|
274
|
+
readonly webhooks: WebhookPort;
|
|
275
|
+
constructor(config: AsaasGatewayConfig, http?: AsaasHttpClient);
|
|
276
|
+
supports(capability: Capability): boolean;
|
|
277
|
+
raw(): AsaasHttpClient;
|
|
278
|
+
private buildCustomerPort;
|
|
279
|
+
private buildChargePort;
|
|
280
|
+
private buildSubscriptionPort;
|
|
281
|
+
private buildWebhookPort;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
interface DomGatewayConfig {
|
|
285
|
+
apiKey: string;
|
|
286
|
+
webhookToken?: string;
|
|
287
|
+
baseUrl?: string;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Configuração discriminada por `provider`. Adicionar um novo gateway começa
|
|
292
|
+
* por estender esta união e o `switch` em `createGateway`.
|
|
293
|
+
*/
|
|
294
|
+
type GatewayConfig = ({
|
|
295
|
+
provider: 'stripe';
|
|
296
|
+
} & StripeGatewayConfig) | ({
|
|
297
|
+
provider: 'asaas';
|
|
298
|
+
} & AsaasGatewayConfig) | ({
|
|
299
|
+
provider: 'dom';
|
|
300
|
+
} & DomGatewayConfig);
|
|
301
|
+
/** Ponto de entrada: instancia o adapter correto a partir da config. */
|
|
302
|
+
declare function createGateway(config: GatewayConfig): PaymentGateway;
|
|
303
|
+
|
|
304
|
+
interface GatewayErrorOptions {
|
|
305
|
+
/** Erro original do gateway/SDK, preservado para diagnóstico. */
|
|
306
|
+
cause?: unknown;
|
|
307
|
+
/** Payload/objeto bruto retornado pelo gateway. */
|
|
308
|
+
raw?: unknown;
|
|
309
|
+
}
|
|
310
|
+
/** Código normalizado de erro, estável entre gateways. */
|
|
311
|
+
type GatewayErrorCode = 'card_declined' | 'authentication' | 'rate_limit' | 'validation' | 'unsupported_capability' | 'gateway_unavailable' | 'unknown';
|
|
312
|
+
/** Base de todos os erros normalizados da lib. */
|
|
313
|
+
declare abstract class GatewayError extends Error {
|
|
314
|
+
readonly provider: Provider;
|
|
315
|
+
abstract readonly code: GatewayErrorCode;
|
|
316
|
+
readonly raw?: unknown;
|
|
317
|
+
constructor(provider: Provider, message: string, options?: GatewayErrorOptions);
|
|
318
|
+
}
|
|
319
|
+
declare class CardDeclinedError extends GatewayError {
|
|
320
|
+
readonly code = "card_declined";
|
|
321
|
+
constructor(provider: Provider, options?: GatewayErrorOptions);
|
|
322
|
+
}
|
|
323
|
+
declare class AuthenticationError extends GatewayError {
|
|
324
|
+
readonly code = "authentication";
|
|
325
|
+
constructor(provider: Provider, options?: GatewayErrorOptions);
|
|
326
|
+
}
|
|
327
|
+
declare class RateLimitError extends GatewayError {
|
|
328
|
+
readonly code = "rate_limit";
|
|
329
|
+
constructor(provider: Provider, options?: GatewayErrorOptions);
|
|
330
|
+
}
|
|
331
|
+
declare class ValidationError extends GatewayError {
|
|
332
|
+
readonly code = "validation";
|
|
333
|
+
constructor(provider: Provider, message: string, options?: GatewayErrorOptions);
|
|
334
|
+
}
|
|
335
|
+
declare class GatewayUnavailableError extends GatewayError {
|
|
336
|
+
readonly code = "gateway_unavailable";
|
|
337
|
+
constructor(provider: Provider, options?: GatewayErrorOptions);
|
|
338
|
+
}
|
|
339
|
+
/** Erro genérico para casos não mapeados, preservando o erro original. */
|
|
340
|
+
declare class UnknownGatewayError extends GatewayError {
|
|
341
|
+
readonly code = "unknown";
|
|
342
|
+
constructor(provider: Provider, message: string, options?: GatewayErrorOptions);
|
|
343
|
+
}
|
|
344
|
+
/** Lançado ao chamar uma operação que o gateway não suporta. */
|
|
345
|
+
declare class UnsupportedCapabilityError extends GatewayError {
|
|
346
|
+
readonly capability: Capability;
|
|
347
|
+
readonly code = "unsupported_capability";
|
|
348
|
+
constructor(provider: Provider, capability: Capability, options?: GatewayErrorOptions);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export { AsaasApiError, AsaasGateway, type AsaasGatewayConfig, type AsaasHttpClient, type AsaasHttpConfig, AuthenticationError, type BillingInterval, type BoletoDetails, Capability, CardDeclinedError, type Charge, type ChargePort, type ChargeStatus, type CreateChargeInput, type CreateCustomerInput, type CreateSubscriptionInput, type Customer, type CustomerPort, type GatewayConfig, GatewayError, type GatewayErrorCode, type GatewayErrorOptions, GatewayUnavailableError, Money, type PaymentGateway, type PaymentMethod, type PixDetails, type Provider, RateLimitError, type RefundChargeInput, StripeGateway, type StripeGatewayConfig, type Subscription, type SubscriptionPort, type SubscriptionStatus, UnknownGatewayError, UnsupportedCapabilityError, type UpdateCustomerInput, ValidationError, type WebhookEvent, type WebhookEventType, type WebhookInput, type WebhookPort, createAsaasHttpClient, createGateway, hasCapability };
|