@adonis-agora/payments 0.2.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.
Files changed (222) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/commands/main.d.ts +16 -0
  3. package/dist/commands/main.d.ts.map +1 -0
  4. package/dist/commands/main.js +17 -0
  5. package/dist/commands/main.js.map +1 -0
  6. package/dist/commands/make_billable.d.ts +16 -0
  7. package/dist/commands/make_billable.d.ts.map +1 -0
  8. package/dist/commands/make_billable.js +30 -0
  9. package/dist/commands/make_billable.js.map +1 -0
  10. package/dist/commands/make_webhook_handler.d.ts +20 -0
  11. package/dist/commands/make_webhook_handler.d.ts.map +1 -0
  12. package/dist/commands/make_webhook_handler.js +34 -0
  13. package/dist/commands/make_webhook_handler.js.map +1 -0
  14. package/dist/commands/payments_sync.d.ts +20 -0
  15. package/dist/commands/payments_sync.d.ts.map +1 -0
  16. package/dist/commands/payments_sync.js +95 -0
  17. package/dist/commands/payments_sync.js.map +1 -0
  18. package/dist/commands/payments_webhook.d.ts +19 -0
  19. package/dist/commands/payments_webhook.d.ts.map +1 -0
  20. package/dist/commands/payments_webhook.js +123 -0
  21. package/dist/commands/payments_webhook.js.map +1 -0
  22. package/dist/configure.d.ts +12 -0
  23. package/dist/configure.d.ts.map +1 -0
  24. package/dist/configure.js +34 -0
  25. package/dist/configure.js.map +1 -0
  26. package/dist/providers/payments_provider.d.ts +15 -0
  27. package/dist/providers/payments_provider.d.ts.map +1 -0
  28. package/dist/providers/payments_provider.js +155 -0
  29. package/dist/providers/payments_provider.js.map +1 -0
  30. package/dist/src/billing/billing_overview.d.ts +26 -0
  31. package/dist/src/billing/billing_overview.d.ts.map +1 -0
  32. package/dist/src/billing/billing_overview.js +27 -0
  33. package/dist/src/billing/billing_overview.js.map +1 -0
  34. package/dist/src/billing/billing_store.d.ts +73 -0
  35. package/dist/src/billing/billing_store.d.ts.map +1 -0
  36. package/dist/src/billing/billing_store.js +2 -0
  37. package/dist/src/billing/billing_store.js.map +1 -0
  38. package/dist/src/billing/index.d.ts +8 -0
  39. package/dist/src/billing/index.d.ts.map +1 -0
  40. package/dist/src/billing/index.js +6 -0
  41. package/dist/src/billing/index.js.map +1 -0
  42. package/dist/src/billing/lucid_billing_store.d.ts +84 -0
  43. package/dist/src/billing/lucid_billing_store.d.ts.map +1 -0
  44. package/dist/src/billing/lucid_billing_store.js +143 -0
  45. package/dist/src/billing/lucid_billing_store.js.map +1 -0
  46. package/dist/src/billing/metered_bill.d.ts +60 -0
  47. package/dist/src/billing/metered_bill.d.ts.map +1 -0
  48. package/dist/src/billing/metered_bill.js +46 -0
  49. package/dist/src/billing/metered_bill.js.map +1 -0
  50. package/dist/src/billing/mixins/index.d.ts +6 -0
  51. package/dist/src/billing/mixins/index.d.ts.map +1 -0
  52. package/dist/src/billing/mixins/index.js +6 -0
  53. package/dist/src/billing/mixins/index.js.map +1 -0
  54. package/dist/src/billing/mixins/with_billable.d.ts +23 -0
  55. package/dist/src/billing/mixins/with_billable.d.ts.map +1 -0
  56. package/dist/src/billing/mixins/with_billable.js +33 -0
  57. package/dist/src/billing/mixins/with_billable.js.map +1 -0
  58. package/dist/src/billing/mixins/with_payment.d.ts +45 -0
  59. package/dist/src/billing/mixins/with_payment.d.ts.map +1 -0
  60. package/dist/src/billing/mixins/with_payment.js +94 -0
  61. package/dist/src/billing/mixins/with_payment.js.map +1 -0
  62. package/dist/src/billing/mixins/with_subscription.d.ts +50 -0
  63. package/dist/src/billing/mixins/with_subscription.d.ts.map +1 -0
  64. package/dist/src/billing/mixins/with_subscription.js +95 -0
  65. package/dist/src/billing/mixins/with_subscription.js.map +1 -0
  66. package/dist/src/billing/mixins/with_usage_event.d.ts +22 -0
  67. package/dist/src/billing/mixins/with_usage_event.d.ts.map +1 -0
  68. package/dist/src/billing/mixins/with_usage_event.js +39 -0
  69. package/dist/src/billing/mixins/with_usage_event.js.map +1 -0
  70. package/dist/src/billing/mixins/with_webhook_event.d.ts +21 -0
  71. package/dist/src/billing/mixins/with_webhook_event.d.ts.map +1 -0
  72. package/dist/src/billing/mixins/with_webhook_event.js +42 -0
  73. package/dist/src/billing/mixins/with_webhook_event.js.map +1 -0
  74. package/dist/src/billing/webhook_dispatcher.d.ts +79 -0
  75. package/dist/src/billing/webhook_dispatcher.d.ts.map +1 -0
  76. package/dist/src/billing/webhook_dispatcher.js +125 -0
  77. package/dist/src/billing/webhook_dispatcher.js.map +1 -0
  78. package/dist/src/billing/webhook_events.d.ts +49 -0
  79. package/dist/src/billing/webhook_events.d.ts.map +1 -0
  80. package/dist/src/billing/webhook_events.js +44 -0
  81. package/dist/src/billing/webhook_events.js.map +1 -0
  82. package/dist/src/billing/webhook_processor.d.ts +39 -0
  83. package/dist/src/billing/webhook_processor.d.ts.map +1 -0
  84. package/dist/src/billing/webhook_processor.js +209 -0
  85. package/dist/src/billing/webhook_processor.js.map +1 -0
  86. package/dist/src/define_config.d.ts +251 -0
  87. package/dist/src/define_config.d.ts.map +1 -0
  88. package/dist/src/define_config.js +67 -0
  89. package/dist/src/define_config.js.map +1 -0
  90. package/dist/src/diagnostics.d.ts +155 -0
  91. package/dist/src/diagnostics.d.ts.map +1 -0
  92. package/dist/src/diagnostics.js +153 -0
  93. package/dist/src/diagnostics.js.map +1 -0
  94. package/dist/src/driver.d.ts +222 -0
  95. package/dist/src/driver.d.ts.map +1 -0
  96. package/dist/src/driver.js +2 -0
  97. package/dist/src/driver.js.map +1 -0
  98. package/dist/src/drivers/abacate.d.ts +35 -0
  99. package/dist/src/drivers/abacate.d.ts.map +1 -0
  100. package/dist/src/drivers/abacate.js +381 -0
  101. package/dist/src/drivers/abacate.js.map +1 -0
  102. package/dist/src/drivers/asaas.d.ts +36 -0
  103. package/dist/src/drivers/asaas.d.ts.map +1 -0
  104. package/dist/src/drivers/asaas.js +455 -0
  105. package/dist/src/drivers/asaas.js.map +1 -0
  106. package/dist/src/drivers/stripe.d.ts +36 -0
  107. package/dist/src/drivers/stripe.d.ts.map +1 -0
  108. package/dist/src/drivers/stripe.js +392 -0
  109. package/dist/src/drivers/stripe.js.map +1 -0
  110. package/dist/src/drivers/woovi.d.ts +49 -0
  111. package/dist/src/drivers/woovi.d.ts.map +1 -0
  112. package/dist/src/drivers/woovi.js +339 -0
  113. package/dist/src/drivers/woovi.js.map +1 -0
  114. package/dist/src/ensure_customer.d.ts +23 -0
  115. package/dist/src/ensure_customer.d.ts.map +1 -0
  116. package/dist/src/ensure_customer.js +25 -0
  117. package/dist/src/ensure_customer.js.map +1 -0
  118. package/dist/src/hooks/webhook_handlers.d.ts +50 -0
  119. package/dist/src/hooks/webhook_handlers.d.ts.map +1 -0
  120. package/dist/src/hooks/webhook_handlers.js +53 -0
  121. package/dist/src/hooks/webhook_handlers.js.map +1 -0
  122. package/dist/src/http.d.ts +24 -0
  123. package/dist/src/http.d.ts.map +1 -0
  124. package/dist/src/http.js +52 -0
  125. package/dist/src/http.js.map +1 -0
  126. package/dist/src/index.d.ts +29 -0
  127. package/dist/src/index.d.ts.map +1 -0
  128. package/dist/src/index.js +15 -0
  129. package/dist/src/index.js.map +1 -0
  130. package/dist/src/invoice/drivers/asaas.d.ts +23 -0
  131. package/dist/src/invoice/drivers/asaas.d.ts.map +1 -0
  132. package/dist/src/invoice/drivers/asaas.js +85 -0
  133. package/dist/src/invoice/drivers/asaas.js.map +1 -0
  134. package/dist/src/invoice/drivers/enotas.d.ts +23 -0
  135. package/dist/src/invoice/drivers/enotas.d.ts.map +1 -0
  136. package/dist/src/invoice/drivers/enotas.js +83 -0
  137. package/dist/src/invoice/drivers/enotas.js.map +1 -0
  138. package/dist/src/invoice/drivers/focus.d.ts +23 -0
  139. package/dist/src/invoice/drivers/focus.d.ts.map +1 -0
  140. package/dist/src/invoice/drivers/focus.js +90 -0
  141. package/dist/src/invoice/drivers/focus.js.map +1 -0
  142. package/dist/src/invoice/drivers/plugnotas.d.ts +22 -0
  143. package/dist/src/invoice/drivers/plugnotas.d.ts.map +1 -0
  144. package/dist/src/invoice/drivers/plugnotas.js +81 -0
  145. package/dist/src/invoice/drivers/plugnotas.js.map +1 -0
  146. package/dist/src/invoice/drivers/tecnospeed.d.ts +29 -0
  147. package/dist/src/invoice/drivers/tecnospeed.d.ts.map +1 -0
  148. package/dist/src/invoice/drivers/tecnospeed.js +87 -0
  149. package/dist/src/invoice/drivers/tecnospeed.js.map +1 -0
  150. package/dist/src/invoice/emit_invoice.d.ts +45 -0
  151. package/dist/src/invoice/emit_invoice.d.ts.map +1 -0
  152. package/dist/src/invoice/emit_invoice.js +72 -0
  153. package/dist/src/invoice/emit_invoice.js.map +1 -0
  154. package/dist/src/invoice/invoice_manager.d.ts +12 -0
  155. package/dist/src/invoice/invoice_manager.d.ts.map +1 -0
  156. package/dist/src/invoice/invoice_manager.js +35 -0
  157. package/dist/src/invoice/invoice_manager.js.map +1 -0
  158. package/dist/src/invoice/invoice_provider.d.ts +48 -0
  159. package/dist/src/invoice/invoice_provider.d.ts.map +1 -0
  160. package/dist/src/invoice/invoice_provider.js +2 -0
  161. package/dist/src/invoice/invoice_provider.js.map +1 -0
  162. package/dist/src/money.d.ts +11 -0
  163. package/dist/src/money.d.ts.map +1 -0
  164. package/dist/src/money.js +14 -0
  165. package/dist/src/money.js.map +1 -0
  166. package/dist/src/payments_manager.d.ts +40 -0
  167. package/dist/src/payments_manager.d.ts.map +1 -0
  168. package/dist/src/payments_manager.js +94 -0
  169. package/dist/src/payments_manager.js.map +1 -0
  170. package/dist/src/services/main.d.ts +6 -0
  171. package/dist/src/services/main.d.ts.map +1 -0
  172. package/dist/src/services/main.js +17 -0
  173. package/dist/src/services/main.js.map +1 -0
  174. package/dist/src/telescope/index.d.ts +3 -0
  175. package/dist/src/telescope/index.d.ts.map +1 -0
  176. package/dist/src/telescope/index.js +2 -0
  177. package/dist/src/telescope/index.js.map +1 -0
  178. package/dist/src/telescope/payments_watcher.d.ts +27 -0
  179. package/dist/src/telescope/payments_watcher.d.ts.map +1 -0
  180. package/dist/src/telescope/payments_watcher.js +58 -0
  181. package/dist/src/telescope/payments_watcher.js.map +1 -0
  182. package/dist/src/telescope/telescope-sdk.d.ts +21 -0
  183. package/dist/src/telescope/telescope-sdk.d.ts.map +1 -0
  184. package/dist/src/telescope/telescope-sdk.js +11 -0
  185. package/dist/src/telescope/telescope-sdk.js.map +1 -0
  186. package/dist/src/testing/fake_payments_driver.d.ts +64 -0
  187. package/dist/src/testing/fake_payments_driver.d.ts.map +1 -0
  188. package/dist/src/testing/fake_payments_driver.js +171 -0
  189. package/dist/src/testing/fake_payments_driver.js.map +1 -0
  190. package/dist/src/testing/in_memory_billing_store.d.ts +110 -0
  191. package/dist/src/testing/in_memory_billing_store.d.ts.map +1 -0
  192. package/dist/src/testing/in_memory_billing_store.js +136 -0
  193. package/dist/src/testing/in_memory_billing_store.js.map +1 -0
  194. package/dist/src/testing/index.d.ts +6 -0
  195. package/dist/src/testing/index.d.ts.map +1 -0
  196. package/dist/src/testing/index.js +4 -0
  197. package/dist/src/testing/index.js.map +1 -0
  198. package/dist/src/testing/mutable_clock.d.ts +12 -0
  199. package/dist/src/testing/mutable_clock.d.ts.map +1 -0
  200. package/dist/src/testing/mutable_clock.js +20 -0
  201. package/dist/src/testing/mutable_clock.js.map +1 -0
  202. package/dist/src/types.d.ts +178 -0
  203. package/dist/src/types.d.ts.map +1 -0
  204. package/dist/src/types.js +9 -0
  205. package/dist/src/types.js.map +1 -0
  206. package/dist/src/webhook_handlers.d.ts +76 -0
  207. package/dist/src/webhook_handlers.d.ts.map +1 -0
  208. package/dist/src/webhook_handlers.js +128 -0
  209. package/dist/src/webhook_handlers.js.map +1 -0
  210. package/dist/src/webhook_security.d.ts +29 -0
  211. package/dist/src/webhook_security.d.ts.map +1 -0
  212. package/dist/src/webhook_security.js +53 -0
  213. package/dist/src/webhook_security.js.map +1 -0
  214. package/dist/stubs/config/payments.stub +101 -0
  215. package/dist/stubs/database/migrations/create_billing_tables.stub +90 -0
  216. package/dist/stubs/main.d.ts +9 -0
  217. package/dist/stubs/main.d.ts.map +1 -0
  218. package/dist/stubs/main.js +16 -0
  219. package/dist/stubs/main.js.map +1 -0
  220. package/dist/stubs/make/billable/main.stub +28 -0
  221. package/dist/stubs/make/webhook_handler/main.stub +29 -0
  222. package/package.json +150 -0
@@ -0,0 +1,12 @@
1
+ /**
2
+ * A clock whose time can be advanced manually — for deterministic time-based tests
3
+ * (retries, trial windows) without real waits. Mirrors durable's testing `MutableClock`.
4
+ */
5
+ export declare class MutableClock {
6
+ #private;
7
+ constructor(start?: Date);
8
+ now(): Date;
9
+ advance(ms: number): void;
10
+ set(date: Date): void;
11
+ }
12
+ //# sourceMappingURL=mutable_clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutable_clock.d.ts","sourceRoot":"","sources":["../../../src/testing/mutable_clock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,YAAY;;gBAGX,KAAK,OAAuC;IAIxD,GAAG,IAAI,IAAI;IAIX,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIzB,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;CAGtB"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * A clock whose time can be advanced manually — for deterministic time-based tests
3
+ * (retries, trial windows) without real waits. Mirrors durable's testing `MutableClock`.
4
+ */
5
+ export class MutableClock {
6
+ #now;
7
+ constructor(start = new Date('2026-01-01T00:00:00.000Z')) {
8
+ this.#now = start;
9
+ }
10
+ now() {
11
+ return this.#now;
12
+ }
13
+ advance(ms) {
14
+ this.#now = new Date(this.#now.getTime() + ms);
15
+ }
16
+ set(date) {
17
+ this.#now = date;
18
+ }
19
+ }
20
+ //# sourceMappingURL=mutable_clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutable_clock.js","sourceRoot":"","sources":["../../../src/testing/mutable_clock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,YAAY;IACvB,IAAI,CAAO;IAEX,YAAY,KAAK,GAAG,IAAI,IAAI,CAAC,0BAA0B,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,GAAG;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,GAAG,CAAC,IAAU;QACZ,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Shared domain types for the billing layer.
3
+ *
4
+ * These are the provider-agnostic shapes the drivers normalize into. Every gateway driver
5
+ * (Stripe, AbacatePay, Asaas, Woovi) maps its own API response onto these types, so the
6
+ * billing layer and application code never touch gateway-specific payloads.
7
+ */
8
+ /** A monetary amount in the currency's smallest unit (e.g. cents for BRL/USD). */
9
+ export type Money = number;
10
+ /** ISO 4217 currency code, lowercase (e.g. `'brl'`, `'usd'`). */
11
+ export type Currency = string;
12
+ export type BillingStatus = 'pending' | 'paid' | 'failed' | 'refunded' | 'canceled' | 'disputed';
13
+ export type SubscriptionStatus = 'trialing' | 'active' | 'past_due' | 'incomplete' | 'canceled' | 'ended';
14
+ export type PaymentMethodType = 'card' | 'pix' | 'boleto' | 'debit_card' | 'unknown';
15
+ /**
16
+ * Canonical payment method names used to route charges to a provider (`config.methods`).
17
+ * `undefined` means "let the customer choose at checkout" (gateway's `UNDEFINED`).
18
+ */
19
+ export type PaymentMethodName = 'pix' | 'credit_card' | 'debit_card' | 'boleto' | 'undefined';
20
+ export interface MoneyAmount {
21
+ amount: Money;
22
+ currency: Currency;
23
+ }
24
+ /** A customer as seen by the gateway. */
25
+ export interface Customer {
26
+ id: string;
27
+ email?: string;
28
+ name?: string;
29
+ /** CPF/CNPJ (BR gateways) or tax id. */
30
+ taxId?: string;
31
+ /** Provider-specific extra data. */
32
+ metadata?: Record<string, unknown>;
33
+ }
34
+ export interface Payment {
35
+ id: string;
36
+ /** External gateway id. */
37
+ gatewayId: string;
38
+ provider: string;
39
+ amount: MoneyAmount;
40
+ status: BillingStatus;
41
+ /** The customer the payment belongs to, when the gateway has one. */
42
+ customerId?: string;
43
+ /** Payment method type (pix, card, boleto...). */
44
+ method?: PaymentMethodType;
45
+ /** Provider-specific raw payload. */
46
+ payload: Record<string, unknown>;
47
+ createdAt: string;
48
+ paidAt?: string;
49
+ /** Pix QR code / copy-paste code when the gateway provides one. */
50
+ pixQrCode?: string;
51
+ pixCopiaECola?: string;
52
+ /** URL to a hosted checkout/charge page when the gateway provides one. */
53
+ hostedUrl?: string;
54
+ /** The subscription this payment belongs to, when recurring. */
55
+ subscriptionId?: string;
56
+ /** Invoice emitted for this payment, when `invoice` was requested. */
57
+ invoice?: Invoice;
58
+ }
59
+ export interface Refund {
60
+ id: string;
61
+ gatewayId: string;
62
+ provider: string;
63
+ amount: MoneyAmount;
64
+ status: 'succeeded' | 'pending' | 'failed';
65
+ createdAt: string;
66
+ }
67
+ export interface CheckoutSession {
68
+ id: string;
69
+ gatewayId: string;
70
+ provider: string;
71
+ /** URL to redirect the customer to (hosted checkout). */
72
+ url: string;
73
+ status: 'open' | 'complete' | 'expired';
74
+ amount?: MoneyAmount;
75
+ /** The subscription created by this checkout, when it was a subscription checkout. */
76
+ subscriptionId?: string;
77
+ customerId?: string;
78
+ }
79
+ export interface Subscription {
80
+ id: string;
81
+ gatewayId: string;
82
+ provider: string;
83
+ customerId: string;
84
+ status: SubscriptionStatus;
85
+ /** Price id/plan id at the gateway. */
86
+ planId: string;
87
+ amount?: MoneyAmount;
88
+ /** ISO date the trial ends (when on trial). */
89
+ trialEndsAt?: string;
90
+ /** ISO date the subscription ends (canceled/ended). */
91
+ endsAt?: string;
92
+ /** Current billing period start (ISO). */
93
+ currentPeriodStart?: string;
94
+ /** Current billing period end (ISO). */
95
+ currentPeriodEnd?: string;
96
+ /** Provider-specific raw payload. */
97
+ payload: Record<string, unknown>;
98
+ createdAt: string;
99
+ }
100
+ export interface Invoice {
101
+ id: string;
102
+ gatewayId: string;
103
+ provider: string;
104
+ customerId?: string;
105
+ subscriptionId?: string;
106
+ status: 'draft' | 'open' | 'paid' | 'void' | 'uncollectible' | 'issued' | 'pending' | 'failed' | 'canceled';
107
+ amount: MoneyAmount;
108
+ /** ISO date the invoice was created. */
109
+ createdAt: string;
110
+ /** URL to download the invoice PDF, when the provider gives one. */
111
+ hostedPdfUrl?: string;
112
+ /** Invoice number, when issued. */
113
+ number?: string;
114
+ /** Access key (chave de acesso), when available. */
115
+ key?: string;
116
+ /** ISO date the invoice was issued. */
117
+ issuedAt?: string;
118
+ /** Provider-specific raw payload. */
119
+ payload: Record<string, unknown>;
120
+ }
121
+ /** A normalized webhook event from a gateway. */
122
+ export interface WebhookEvent<T = unknown> {
123
+ /** Stable event id — used for idempotency. */
124
+ id: string;
125
+ provider: string;
126
+ /** Gateway event type, e.g. `checkout.completed`, `invoice.payment_succeeded`. */
127
+ type: string;
128
+ /** ISO timestamp of when the event happened at the gateway. */
129
+ createdAt?: string;
130
+ /** The normalized event payload. */
131
+ data: T;
132
+ /** The raw, unmodified gateway payload. */
133
+ raw: Record<string, unknown>;
134
+ }
135
+ /**
136
+ * Invoice emission options, passed to a charge/subscription call. The presence of the
137
+ * option means "emit an invoice for this charge":
138
+ *
139
+ * - `true` — use the default invoice provider from `config/payments.ts` (`invoice.default`).
140
+ * - `'focus'` — use the named invoice provider (a key of `invoice.providers`).
141
+ * - `{ provider?, ... }` — use the named provider (or the default) with these overrides.
142
+ *
143
+ * ```ts
144
+ * await payments.bill({
145
+ * customerId: 'cus_x',
146
+ * amount: 1990,
147
+ * invoice: {
148
+ * provider: 'focus',
149
+ * service: { description: 'Software license', code: '1.01' },
150
+ * tax: { iss: 5 },
151
+ * },
152
+ * })
153
+ * ```
154
+ */
155
+ export interface InvoiceOptions {
156
+ /** Named invoice provider (a key of `invoice.providers`). Defaults to `invoice.default`. */
157
+ provider?: string;
158
+ /** Service details for service invoices. Falls back to `invoice.defaults.service`. */
159
+ service?: {
160
+ description?: string;
161
+ /** Service code (código de serviço). */
162
+ code?: string;
163
+ /** Municipal service code (código de serviço municipal). */
164
+ cityServiceCode?: string;
165
+ };
166
+ /** Tax configuration. Falls back to `invoice.defaults.tax`. */
167
+ tax?: Record<string, unknown>;
168
+ /** Invoice recipient. Defaults to the billing customer's data. */
169
+ customer?: {
170
+ name?: string;
171
+ taxId?: string;
172
+ email?: string;
173
+ address?: Record<string, unknown>;
174
+ };
175
+ /** Extra provider-specific fields. */
176
+ metadata?: Record<string, unknown>;
177
+ }
178
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Shared domain types for the billing layer.
3
+ *
4
+ * These are the provider-agnostic shapes the drivers normalize into. Every gateway driver
5
+ * (Stripe, AbacatePay, Asaas, Woovi) maps its own API response onto these types, so the
6
+ * billing layer and application code never touch gateway-specific payloads.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,76 @@
1
+ import type { WebhookHandler } from './billing/webhook_processor.js';
2
+ import type { WebhookEvent } from './types.js';
3
+ /**
4
+ * A webhook-handler service constructor: the lib resolves it from the Adonis container
5
+ * (DI works) and calls `handle(event)` for each event of the registered type. A class
6
+ * with no dependencies is unaffected — the container simply does `new Ctor()`.
7
+ */
8
+ export interface WebhookHandlerService {
9
+ new (...args: never[]): {
10
+ handle(event: WebhookEvent): void | Promise<void>;
11
+ };
12
+ }
13
+ /** The container surface handler resolution needs. */
14
+ export interface HandlerContainer {
15
+ make<T>(token: unknown): Promise<T>;
16
+ }
17
+ /**
18
+ * Detect a {@link WebhookHandlerService} (a class with a `handle` method) vs a plain
19
+ * handler function. Arrow functions have no prototype; named functions have one without
20
+ * a `handle` member — only a class declaring `handle` matches, so plain handlers are
21
+ * never misrouted.
22
+ */
23
+ export declare function isWebhookHandlerService(entry: unknown): entry is WebhookHandlerService;
24
+ /**
25
+ * Resolve one `billing.handlers` entry (or a folder-discovered handler) into a concrete
26
+ * {@link WebhookHandler}: plain functions pass through; service classes are instantiated
27
+ * through the container and bound to their `handle` method.
28
+ */
29
+ export declare function resolveWebhookHandler(entry: WebhookHandler | WebhookHandlerService, container: HandlerContainer): Promise<WebhookHandler>;
30
+ /**
31
+ * A folder-discovered handler: the normalized event type plus the raw entry (function or
32
+ * service class) to resolve through the container at wiring time.
33
+ */
34
+ export interface DiscoveredWebhookHandler {
35
+ type: string;
36
+ entry: WebhookHandler | WebhookHandlerService;
37
+ }
38
+ /** Shape each file in the conventions folder must default-export. */
39
+ export interface WebhookHandlerModule {
40
+ /**
41
+ * Normalized event type this handler listens to (e.g. `'payment.succeeded'`). A service
42
+ * class declares it as `static eventType` instead.
43
+ */
44
+ type?: string;
45
+ /** Event-type static on a service class form. */
46
+ eventType?: string;
47
+ /** The handler function (object form). */
48
+ handle?: WebhookHandler;
49
+ }
50
+ /** Normalize a module's default export into a {@link DiscoveredWebhookHandler}, or null. */
51
+ export declare function normalizeWebhookHandlerModule(mod: unknown): DiscoveredWebhookHandler | null;
52
+ /** The build-time barrel the Assembler `init` hook generates — a map of key → lazy import. */
53
+ export type WebhookHandlersBarrel = Record<string, () => Promise<Record<string, unknown>>>;
54
+ /**
55
+ * Load the generated barrel (`.adonisjs/payments/webhook_handlers.js`) — the build-time
56
+ * equivalent of a directory scan, with no runtime `readdir`. Each module's default export
57
+ * is normalized via {@link normalizeWebhookHandlerModule}.
58
+ */
59
+ export declare function loadWebhookHandlersFromBarrel(barrel: WebhookHandlersBarrel): Promise<DiscoveredWebhookHandler[]>;
60
+ /**
61
+ * Pick the module extension a directory scan should import, from the `readdir` entries
62
+ * already in hand — NOT from this library's own compiled file. A consuming app resolves
63
+ * this library as built `.js`, but its own `app/payment_handlers` are `.ts` in dev;
64
+ * deriving the extension from `import.meta.url` would always pick `.js` and discover
65
+ * nothing. `.d.ts` entries are never importable. `.ts` wins over `.js` when both exist
66
+ * (same module never registered twice). Mirrors durable's `pickModuleExt`.
67
+ */
68
+ export declare function pickModuleExt(entries: readonly string[]): '.ts' | '.js' | null;
69
+ /**
70
+ * Scan the conventions folder RECURSIVELY for handler modules (default export is a
71
+ * `{ type, handle }` object or a service class with `static eventType`). Missing
72
+ * directory → empty list (the convention is opt-in: no `app/payment_handlers`, nothing
73
+ * to register). Mirrors durable's `discoverWorkflows`.
74
+ */
75
+ export declare function discoverWebhookHandlers(dir: string): Promise<DiscoveredWebhookHandler[]>;
76
+ //# sourceMappingURL=webhook_handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook_handlers.d.ts","sourceRoot":"","sources":["../../src/webhook_handlers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG;QAAE,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;CAC/E;AAED,sDAAsD;AACtD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACrC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAKtF;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,cAAc,GAAG,qBAAqB,EAC7C,SAAS,EAAE,gBAAgB,GAC1B,OAAO,CAAC,cAAc,CAAC,CAMzB;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,GAAG,qBAAqB,CAAC;CAC/C;AAED,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,4FAA4F;AAC5F,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,OAAO,GAAG,wBAAwB,GAAG,IAAI,CAa3F;AAED,8FAA8F;AAC9F,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAE3F;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAcrC;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,CAY9E;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAyB9F"}
@@ -0,0 +1,128 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import { extname, join } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ /**
5
+ * Detect a {@link WebhookHandlerService} (a class with a `handle` method) vs a plain
6
+ * handler function. Arrow functions have no prototype; named functions have one without
7
+ * a `handle` member — only a class declaring `handle` matches, so plain handlers are
8
+ * never misrouted.
9
+ */
10
+ export function isWebhookHandlerService(entry) {
11
+ return (typeof entry === 'function' &&
12
+ Object.getOwnPropertyNames(entry.prototype ?? {}).includes('handle'));
13
+ }
14
+ /**
15
+ * Resolve one `billing.handlers` entry (or a folder-discovered handler) into a concrete
16
+ * {@link WebhookHandler}: plain functions pass through; service classes are instantiated
17
+ * through the container and bound to their `handle` method.
18
+ */
19
+ export async function resolveWebhookHandler(entry, container) {
20
+ if (isWebhookHandlerService(entry)) {
21
+ const service = await container.make(entry);
22
+ return (event) => service.handle(event);
23
+ }
24
+ return entry;
25
+ }
26
+ /** Normalize a module's default export into a {@link DiscoveredWebhookHandler}, or null. */
27
+ export function normalizeWebhookHandlerModule(mod) {
28
+ if (typeof mod !== 'function' && (typeof mod !== 'object' || mod === null))
29
+ return null;
30
+ const candidate = mod;
31
+ const type = candidate.type ?? candidate.eventType;
32
+ if (typeof type !== 'string')
33
+ return null;
34
+ if (typeof mod === 'function') {
35
+ // Service class form: `static eventType` + instance `handle`.
36
+ if (isWebhookHandlerService(mod))
37
+ return { type, entry: mod };
38
+ return null;
39
+ }
40
+ // Object form: `{ type, handle }`.
41
+ if (typeof candidate.handle !== 'function')
42
+ return null;
43
+ return { type, entry: candidate.handle };
44
+ }
45
+ /**
46
+ * Load the generated barrel (`.adonisjs/payments/webhook_handlers.js`) — the build-time
47
+ * equivalent of a directory scan, with no runtime `readdir`. Each module's default export
48
+ * is normalized via {@link normalizeWebhookHandlerModule}.
49
+ */
50
+ export async function loadWebhookHandlersFromBarrel(barrel) {
51
+ const found = [];
52
+ const seen = new Set();
53
+ for (const load of Object.values(barrel)) {
54
+ const mod = await load();
55
+ for (const exported of Object.values(mod)) {
56
+ if (seen.has(exported))
57
+ continue;
58
+ const normalized = normalizeWebhookHandlerModule(exported);
59
+ if (!normalized)
60
+ continue;
61
+ seen.add(exported);
62
+ found.push(normalized);
63
+ }
64
+ }
65
+ return found;
66
+ }
67
+ /**
68
+ * Pick the module extension a directory scan should import, from the `readdir` entries
69
+ * already in hand — NOT from this library's own compiled file. A consuming app resolves
70
+ * this library as built `.js`, but its own `app/payment_handlers` are `.ts` in dev;
71
+ * deriving the extension from `import.meta.url` would always pick `.js` and discover
72
+ * nothing. `.d.ts` entries are never importable. `.ts` wins over `.js` when both exist
73
+ * (same module never registered twice). Mirrors durable's `pickModuleExt`.
74
+ */
75
+ export function pickModuleExt(entries) {
76
+ let hasTs = false;
77
+ let hasJs = false;
78
+ for (const entry of entries) {
79
+ if (entry.endsWith('.d.ts'))
80
+ continue;
81
+ const ext = extname(entry);
82
+ if (ext === '.ts')
83
+ hasTs = true;
84
+ else if (ext === '.js')
85
+ hasJs = true;
86
+ }
87
+ if (hasTs)
88
+ return '.ts';
89
+ if (hasJs)
90
+ return '.js';
91
+ return null;
92
+ }
93
+ /**
94
+ * Scan the conventions folder RECURSIVELY for handler modules (default export is a
95
+ * `{ type, handle }` object or a service class with `static eventType`). Missing
96
+ * directory → empty list (the convention is opt-in: no `app/payment_handlers`, nothing
97
+ * to register). Mirrors durable's `discoverWorkflows`.
98
+ */
99
+ export async function discoverWebhookHandlers(dir) {
100
+ let entries;
101
+ try {
102
+ entries = await readdir(dir, { recursive: true });
103
+ }
104
+ catch (err) {
105
+ if (err.code === 'ENOENT')
106
+ return [];
107
+ throw err;
108
+ }
109
+ const moduleExt = pickModuleExt(entries);
110
+ const found = [];
111
+ if (moduleExt === null)
112
+ return found;
113
+ const seen = new Set();
114
+ for (const entry of entries.sort()) {
115
+ if (extname(entry) !== moduleExt || entry.endsWith(`.d${moduleExt}`))
116
+ continue;
117
+ const mod = (await import(pathToFileURL(join(dir, entry)).href));
118
+ const normalized = normalizeWebhookHandlerModule(mod.default);
119
+ if (!normalized)
120
+ continue;
121
+ if (seen.has(normalized.entry))
122
+ continue;
123
+ seen.add(normalized.entry);
124
+ found.push(normalized);
125
+ }
126
+ return found;
127
+ }
128
+ //# sourceMappingURL=webhook_handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook_handlers.js","sourceRoot":"","sources":["../../src/webhook_handlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Shared webhook-auth primitives for the drivers. Every gateway signs webhooks
3
+ * differently (Stripe: SDK HMAC; AbacatePay: HMAC-SHA256; Woovi: HMAC-SHA1 or
4
+ * RSA-SHA256; Asaas: shared token), but the comparison and digest mechanics are the
5
+ * same — they live here so every driver verifies with the same, timing-safe code.
6
+ */
7
+ /** Length-independent, timing-safe string comparison. */
8
+ export declare function safeCompare(received: string, expected: string): boolean;
9
+ /**
10
+ * Compute an HMAC over the raw webhook body and compare it to the signature header,
11
+ * timing-safe. `digest` matches the gateway's encoding (`base64` for AbacatePay and
12
+ * Woovi's HMAC mode).
13
+ */
14
+ export declare function verifyHmacSignature(rawBody: string, signature: string | undefined, secret: string, algorithm: 'sha256' | 'sha1'): boolean;
15
+ /**
16
+ * Verify Woovi's recommended `x-webhook-signature`: an RSA-SHA256 signature made with
17
+ * Woovi's private key, verified here against the public key published at
18
+ * `GET /api/v1/webhook/public-keys`. The key may be pasted as PEM or as the base64 of a
19
+ * PEM document (the dashboard shows it base64-encoded).
20
+ */
21
+ export declare function verifyRsaSha256Signature(rawBody: string, signature: string | undefined, publicKey: string): boolean;
22
+ /**
23
+ * Enforce a configured webhook credential against the request headers. Returns the
24
+ * header value when valid; throws when the driver has a secret configured but the
25
+ * request doesn't carry it or carries a wrong one — fail-closed whenever a secret IS
26
+ * set. Drivers only reach this when their credential is configured.
27
+ */
28
+ export declare function requireMatchingCredential(received: string | undefined, expected: string, provider: string, what: string): void;
29
+ //# sourceMappingURL=webhook_security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook_security.d.ts","sourceRoot":"","sources":["../../src/webhook_security.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAIvE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,QAAQ,GAAG,MAAM,GAC3B,OAAO,CAIT;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,GAChB,OAAO,CAWT;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,IAAI,CAON"}
@@ -0,0 +1,53 @@
1
+ import { createHmac, verify as cryptoVerify, timingSafeEqual } from 'node:crypto';
2
+ /**
3
+ * Shared webhook-auth primitives for the drivers. Every gateway signs webhooks
4
+ * differently (Stripe: SDK HMAC; AbacatePay: HMAC-SHA256; Woovi: HMAC-SHA1 or
5
+ * RSA-SHA256; Asaas: shared token), but the comparison and digest mechanics are the
6
+ * same — they live here so every driver verifies with the same, timing-safe code.
7
+ */
8
+ /** Length-independent, timing-safe string comparison. */
9
+ export function safeCompare(received, expected) {
10
+ const a = Buffer.from(received, 'utf8');
11
+ const b = Buffer.from(expected, 'utf8');
12
+ return a.length === b.length && timingSafeEqual(a, b);
13
+ }
14
+ /**
15
+ * Compute an HMAC over the raw webhook body and compare it to the signature header,
16
+ * timing-safe. `digest` matches the gateway's encoding (`base64` for AbacatePay and
17
+ * Woovi's HMAC mode).
18
+ */
19
+ export function verifyHmacSignature(rawBody, signature, secret, algorithm) {
20
+ if (signature === undefined || signature === '')
21
+ return false;
22
+ const expected = createHmac(algorithm, secret).update(rawBody, 'utf8').digest('base64');
23
+ return safeCompare(signature, expected);
24
+ }
25
+ /**
26
+ * Verify Woovi's recommended `x-webhook-signature`: an RSA-SHA256 signature made with
27
+ * Woovi's private key, verified here against the public key published at
28
+ * `GET /api/v1/webhook/public-keys`. The key may be pasted as PEM or as the base64 of a
29
+ * PEM document (the dashboard shows it base64-encoded).
30
+ */
31
+ export function verifyRsaSha256Signature(rawBody, signature, publicKey) {
32
+ if (signature === undefined || signature === '')
33
+ return false;
34
+ const pem = publicKey.includes('-----BEGIN')
35
+ ? publicKey
36
+ : Buffer.from(publicKey, 'base64').toString('utf8');
37
+ return cryptoVerify('RSA-SHA256', Buffer.from(rawBody, 'utf8'), pem, Buffer.from(signature, 'base64'));
38
+ }
39
+ /**
40
+ * Enforce a configured webhook credential against the request headers. Returns the
41
+ * header value when valid; throws when the driver has a secret configured but the
42
+ * request doesn't carry it or carries a wrong one — fail-closed whenever a secret IS
43
+ * set. Drivers only reach this when their credential is configured.
44
+ */
45
+ export function requireMatchingCredential(received, expected, provider, what) {
46
+ if (received === undefined || received === '') {
47
+ throw new Error(`[payments] Missing webhook ${what} on ${provider} request.`);
48
+ }
49
+ if (!safeCompare(received, expected)) {
50
+ throw new Error(`[payments] Invalid ${provider} webhook ${what}.`);
51
+ }
52
+ }
53
+ //# sourceMappingURL=webhook_security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook_security.js","sourceRoot":"","sources":["../../src/webhook_security.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAElF;;;;;GAKG;AAEH,yDAAyD;AACzD,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,QAAgB;IAC5D,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,SAA6B,EAC7B,MAAc,EACd,SAA4B;IAE5B,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxF,OAAO,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAe,EACf,SAA6B,EAC7B,SAAiB;IAEjB,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC1C,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO,YAAY,CACjB,YAAY,EACZ,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAC5B,GAAG,EACH,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CACjC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAA4B,EAC5B,QAAgB,EAChB,QAAgB,EAChB,IAAY;IAEZ,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,OAAO,QAAQ,WAAW,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,YAAY,IAAI,GAAG,CAAC,CAAC;IACrE,CAAC;AACH,CAAC"}
@@ -0,0 +1,101 @@
1
+ {{{
2
+ exports({ to: app.configPath('payments.ts') })
3
+ }}}
4
+ import env from '#start/env'
5
+ import { defineConfig, payments, invoice } from '@adonis-agora/payments'
6
+
7
+ export default defineConfig({
8
+ /**
9
+ * Default payment provider — a key of `providers`.
10
+ */
11
+ default: 'stripe',
12
+
13
+ /**
14
+ * Named payment providers. Each factory lazily imports its gateway SDK, so only the
15
+ * providers you actually use are loaded.
16
+ */
17
+ providers: {
18
+ stripe: payments.stripe({
19
+ apiKey: env.get('STRIPE_KEY'),
20
+ currency: 'brl',
21
+ // Required to verify webhook signatures (whsec_...):
22
+ webhookSecret: env.get('STRIPE_WEBHOOK_SECRET'),
23
+ }),
24
+ // abacate: payments.abacate({
25
+ // apiKey: env.get('ABACATE_API_KEY'),
26
+ // // HMAC secret that signs webhooks — reject unsigned requests in production:
27
+ // webhookSecret: env.get('ABACATE_PUBLIC_KEY'),
28
+ // }),
29
+ // asaas: payments.asaas({
30
+ // apiKey: env.get('ASAAS_API_KEY'),
31
+ // sandbox: env.get('NODE_ENV') !== 'production',
32
+ // // Shared token set in the Asaas dashboard — reject requests without it:
33
+ // webhookToken: env.get('ASAAS_WEBHOOK_TOKEN'),
34
+ // }),
35
+ // woovi: payments.woovi({
36
+ // appId: env.get('WOOVI_APP_ID'),
37
+ // // Recommended RSA signature (x-webhook-signature):
38
+ // webhookPublicKey: env.get('WOOVI_PUBLIC_KEY'),
39
+ // }),
40
+ },
41
+
42
+ /**
43
+ * Route a payment method to a provider (a key of `providers`). The charge call then
44
+ * resolves the driver per method: `payments.driver('pix').charge(...)`.
45
+ */
46
+ methods: {
47
+ pix: 'stripe',
48
+ credit_card: 'stripe',
49
+ // boleto: 'asaas',
50
+ // debit_card: 'asaas',
51
+ // undefined: 'asaas',
52
+ },
53
+
54
+ /**
55
+ * Invoice (NFe/NFSe) emission. Optional — only needed when you want to emit invoices
56
+ * for charges (e.g. `charge({ ..., invoice: true })`).
57
+ */
58
+ invoice: {
59
+ default: 'focus',
60
+ providers: {
61
+ focus: invoice.focus({
62
+ token: env.get('FOCUS_NFE_TOKEN'),
63
+ }),
64
+ // enotas: invoice.enotas({ apiKey: env.get('ENOTAS_API_KEY') }),
65
+ // plugnotas: invoice.plugnotas({ apiKey: env.get('PLUGNOTAS_API_KEY') }),
66
+ // Asaas NFS-e nativo — invoice: true numa charge Asaas emite pelo próprio Asaas:
67
+ // asaas: invoice.asaas({ apiKey: env.get('ASAAS_API_KEY') }),
68
+ },
69
+ defaults: {
70
+ service: {
71
+ description: 'Software license',
72
+ },
73
+ },
74
+ },
75
+
76
+ /**
77
+ * Billing (subscription) layer.
78
+ */
79
+ billing: {
80
+ enabled: true,
81
+ /**
82
+ * 'auto' uses @adonis-agora/durable to process webhooks when it is installed in the
83
+ * app, falling back to an in-process dispatcher otherwise. Set `false` to always use
84
+ * the in-process dispatcher, or `true` to require durable.
85
+ */
86
+ durable: 'auto',
87
+ /**
88
+ * Business webhook handlers run inside the lib-mounted route (errors mark the event
89
+ * failed + retry). Accepts a DI service class (the lib calls its `.handle`) or a
90
+ * plain function. Alternative: drop files in `app/payment_handlers/` (durable-style
91
+ * discovery, see `@adonis-agora/payments/hooks/webhook_handlers`). Recommended: the
92
+ * handler only dispatches to a durable workflow / queue — never heavy work inline.
93
+ *
94
+ * handlers: {
95
+ * 'payment.succeeded': PaymentSucceededHandler, // DI service → .handle(event)
96
+ * 'payment.refunded': (event) => { ... },
97
+ * },
98
+ */
99
+ handlers: {},
100
+ },
101
+ })