@geekapps/billing-fastify 0.4.3 → 0.6.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/dist/index.d.ts CHANGED
@@ -231,6 +231,19 @@ interface PlanCheckoutInput {
231
231
  billing_period?: BillingPeriod;
232
232
  /** Segundos até a cobrança inicial vencer — opcional, default 1h. Use o helper `expiresIn`. */
233
233
  expires_in?: number;
234
+ /** Código de um cupom ativo da sua org (ver `coupons.create`) — aplica o desconto
235
+ * nativamente na página de pagamento (Stripe exibe "cupom aplicado" e o valor já
236
+ * descontado). Se o código for inválido/expirado/esgotado, a chamada falha com 422. */
237
+ coupon_code?: string;
238
+ }
239
+ /** Desconto efetivamente aplicado num checkout — presente na resposta apenas quando
240
+ * `coupon_code` foi informado e o cupom era válido. */
241
+ interface AppliedDiscount {
242
+ coupon_code: string;
243
+ /** Valor original (cents), antes do desconto. */
244
+ original_amount: number;
245
+ /** Valor final (cents), já com o desconto aplicado — é o que efetivamente será cobrado. */
246
+ final_amount: number;
234
247
  }
235
248
  interface PlanCheckoutResult {
236
249
  checkout_token: string;
@@ -241,6 +254,8 @@ interface PlanCheckoutResult {
241
254
  /** Token permanente — guarde-o (associado ao seu usuário) para depois checar se a
242
255
  * assinatura está ativa e qual item ela cobre via `subscriptions.checkByToken`. */
243
256
  management_token: string;
257
+ /** Presente apenas quando um `coupon_code` válido foi aplicado neste checkout. */
258
+ discount?: AppliedDiscount;
244
259
  }
245
260
  interface CheckoutForCustomerInput {
246
261
  /** Para onde redirecionar o cliente após a confirmação do pagamento. Se omitido, usa o
@@ -248,6 +263,8 @@ interface CheckoutForCustomerInput {
248
263
  return_url?: string;
249
264
  /** Segundos até a cobrança inicial vencer — opcional, default 1h. Use o helper `expiresIn`. */
250
265
  expires_in?: number;
266
+ /** Código de um cupom ativo da sua org — mesma semântica de `PlanCheckoutInput.coupon_code`. */
267
+ coupon_code?: string;
251
268
  }
252
269
  /** Resultado de `plans.checkoutPlan` (`POST /billing-plans/:id/checkout-for-customer`) —
253
270
  * mesma forma de `PlanCheckoutResult`, mas para um `Customer` já existente na sua org
@@ -257,6 +274,38 @@ interface CheckoutForCustomerResult {
257
274
  checkout_url: string;
258
275
  subscription_id: string;
259
276
  management_token: string;
277
+ discount?: AppliedDiscount;
278
+ }
279
+ type CouponType = "PERCENTAGE" | "FIXED";
280
+ type CouponDuration = "ONCE" | "FOREVER" | "REPEATING";
281
+ interface CreateCouponInput {
282
+ code: string;
283
+ type: CouponType;
284
+ /** PERCENTAGE: inteiro de 1 a 100 (ex: `20` = 20% de desconto).
285
+ * FIXED: valor em centavos (ex: `500` = R$5,00 de desconto). */
286
+ value: number;
287
+ duration: CouponDuration;
288
+ /** Obrigatório quando `duration` é `"REPEATING"` — por quantos meses de renovação o
289
+ * desconto se repete. */
290
+ duration_months?: number;
291
+ max_redemptions?: number;
292
+ /** ISO 8601 — após essa data o cupom deixa de ser aceito em novos checkouts. */
293
+ expires_at?: string;
294
+ }
295
+ interface Coupon {
296
+ id: string;
297
+ org_id: string;
298
+ code: string;
299
+ type: CouponType;
300
+ value: number;
301
+ duration: CouponDuration;
302
+ duration_months: number | null;
303
+ max_redemptions: number | null;
304
+ redemptions_count: number;
305
+ expires_at: string | null;
306
+ active: boolean;
307
+ created_at: string;
308
+ updated_at: string;
260
309
  }
261
310
  /** Resultado de `plans.confirmPlanSubscription` (`GET /billing-plans/:id/subscription-status`) —
262
311
  * a assinatura mais recente de um customer_id para um plano específico. */
@@ -279,6 +328,23 @@ interface CheckoutStatusResult {
279
328
  provider_url: string | null;
280
329
  return_url: string | null;
281
330
  }
331
+ /** Fluxo legado de assinatura por `BillingItem` avulso (sem `BillingPlan`) — autenticado,
332
+ * requer que `customer_id` e `item_id` já existam na sua org. Prefira `plans.checkout`/
333
+ * `plans.checkoutPlan` para novos catálogos baseados em `BillingPlan`. */
334
+ interface CreateSubscriptionInput {
335
+ customer_id: string;
336
+ item_id: string;
337
+ interval: BillingRecurringInterval;
338
+ provider?: string;
339
+ description?: string;
340
+ /** Código de um cupom ativo da sua org — mesma semântica de `PlanCheckoutInput.coupon_code`. */
341
+ coupon_code?: string;
342
+ }
343
+ interface CreateSubscriptionResult {
344
+ subscription: Subscription;
345
+ charge: Charge;
346
+ discount?: AppliedDiscount;
347
+ }
282
348
  interface Subscription {
283
349
  id: string;
284
350
  org_id: string;
@@ -413,6 +479,40 @@ declare class CheckoutResource {
413
479
  waitUntilPaid(checkoutToken: string, options?: WaitUntilPaidOptions): Promise<CheckoutStatusResult>;
414
480
  }
415
481
 
482
+ declare class CouponsResource {
483
+ private readonly http;
484
+ constructor(http: HttpClient);
485
+ list(): Promise<Coupon[]>;
486
+ /** `idOrCode` aceita tanto o id interno (`coupon.id`) quanto o `code` legível que você
487
+ * escolheu na criação (ex: `"BEMVINDO20"`) — normalmente é mais prático guardar/usar o
488
+ * `code`, já que é você quem o define e é o que aparece para o cliente final. */
489
+ get(idOrCode: string): Promise<Coupon>;
490
+ /**
491
+ * Cria um cupom de desconto — o `code` é o que o cliente final informa no checkout
492
+ * (`plans.checkout(planId, { coupon_code })`).
493
+ *
494
+ * ```ts
495
+ * // 20% de desconto, aplicado só na primeira cobrança
496
+ * await client.coupons.create({ code: "BEMVINDO20", type: "PERCENTAGE", value: 20, duration: "ONCE" });
497
+ *
498
+ * // R$10 de desconto, repetido pelas 3 primeiras renovações
499
+ * await client.coupons.create({
500
+ * code: "R10X3", type: "FIXED", value: 1000, duration: "REPEATING", duration_months: 3,
501
+ * });
502
+ * ```
503
+ */
504
+ create(input: CreateCouponInput): Promise<Coupon>;
505
+ /** Só permite editar limites/validade/ativação — o desconto em si (type/value/duration)
506
+ * de um cupom já criado é imutável; crie um novo código para mudar o valor do desconto.
507
+ * `idOrCode` aceita id interno ou `code` (ver `get`). */
508
+ update(idOrCode: string, input: Partial<Pick<CreateCouponInput, "max_redemptions" | "expires_at">> & {
509
+ active?: boolean;
510
+ }): Promise<Coupon>;
511
+ /** Desativa o cupom (soft-delete) — códigos já resgatados continuam no histórico.
512
+ * `idOrCode` aceita id interno ou `code` (ver `get`). */
513
+ remove(idOrCode: string): Promise<void>;
514
+ }
515
+
416
516
  declare class CustomersResource {
417
517
  private readonly http;
418
518
  constructor(http: HttpClient);
@@ -503,6 +603,7 @@ declare class PlansResource {
503
603
  * ```ts
504
604
  * const { checkout_url, checkout_token } = await client.plans.checkout(planId, {
505
605
  * customer: { name, email },
606
+ * coupon_code: "PROMO20", // opcional — página já abre com o desconto aplicado
506
607
  * });
507
608
  * // redirecione o cliente (ou abra checkout_url em uma WebView/nova aba)
508
609
  * window.location.href = checkout_url;
@@ -523,6 +624,18 @@ declare class SubscriptionsResource {
523
624
  constructor(http: HttpClient);
524
625
  /** Requer autenticação (service account) — lista todas as assinaturas da sua org. */
525
626
  list(): Promise<Subscription[]>;
627
+ /**
628
+ * Fluxo legado de assinatura por `BillingItem` avulso (sem `BillingPlan`) — requer
629
+ * autenticação (service account) e que `customer_id`/`item_id` já existam na sua org.
630
+ * Prefira `plans.checkout`/`plans.checkoutPlan` para novos catálogos baseados em plano.
631
+ *
632
+ * ```ts
633
+ * await client.subscriptions.create({
634
+ * customer_id, item_id, interval: "MONTHLY", coupon_code: "PROMO20",
635
+ * });
636
+ * ```
637
+ */
638
+ create(input: CreateSubscriptionInput): Promise<CreateSubscriptionResult>;
526
639
  /** Requer autenticação (service account). */
527
640
  get(id: string): Promise<Subscription>;
528
641
  /** Requer autenticação (service account). */
@@ -533,12 +646,21 @@ declare class SubscriptionsResource {
533
646
  * um link de confirmação para o cliente final revisar custo e vigência e confirmar
534
647
  * expressamente antes de qualquer cobrança ou mudança de plano acontecer.
535
648
  *
649
+ * `couponCode`: aplica um cupom na troca — se a assinatura for Stripe, o desconto passa a
650
+ * valer também nas renovações futuras (recorrente, direto na Subscription); se for
651
+ * PIX/boleto, o desconto vale só para a cobrança de proration desta troca.
652
+ *
536
653
  * ```ts
537
- * const { confirmation_url } = await client.subscriptions.requestPlanSwap(subId, newPlanId);
654
+ * const { confirmation_url } = await client.subscriptions.requestPlanSwap(subId, newPlanId, {
655
+ * couponCode: "PROMO20",
656
+ * });
538
657
  * // redirecione o cliente final para confirmation_url
539
658
  * ```
540
659
  */
541
- requestPlanSwap(id: string, newPlanId: string, expiresInSeconds?: number): Promise<{
660
+ requestPlanSwap(id: string, newPlanId: string, options?: {
661
+ expiresInSeconds?: number;
662
+ couponCode?: string;
663
+ }): Promise<{
542
664
  confirmation_url: string;
543
665
  }>;
544
666
  /**
@@ -603,6 +725,7 @@ declare class BillingClient {
603
725
  private readonly http;
604
726
  readonly charges: ChargesResource;
605
727
  readonly checkout: CheckoutResource;
728
+ readonly coupons: CouponsResource;
606
729
  readonly customers: CustomersResource;
607
730
  readonly items: ItemsResource;
608
731
  readonly orders: OrdersResource;
@@ -682,4 +805,4 @@ type ExpirationUnit = "seconds" | "minutes" | "hours" | "days";
682
805
  */
683
806
  declare function expiresIn(value: number, unit: ExpirationUnit): number;
684
807
 
685
- export { BillingApiError, BillingClient, type BillingClientOptions, type BillingItem, type BillingPeriod, type BillingPlanSummary, type BillingPluginOptions, type BillingRecurringInterval, type BillingRecurringStatus, type BillingSubscriptionCancelReason, type Charge, type ChargeStatus, ChargesResource, type CheckoutForCustomerInput, type CheckoutForCustomerResult, CheckoutResource, type CheckoutSessionStatus, type CheckoutStatusResult, type CreateBillingPlanInput, type CreateChargeInput, type CreateChargeResult, type CreateOrderInput, type CreateOrderResult, type Customer, type CustomerInput, CustomersResource, type ExpirationUnit, type GetPublicPlanPageResult, HttpClient, type HttpClientOptions, type ItemInput, ItemsResource, type ListPublicPlansResult, OrdersResource, type OutboundWebhookEventType, type PaymentMethod, type PlanCheckoutCustomerInput, type PlanCheckoutInput, type PlanCheckoutResult, type PlanSubscriptionStatusResult, PlansResource, type ProrationPolicy, type PublicBillingPlan, type PublicOrganization, type PublicPlanBranding, type QuickChargeInput, type QuickChargeResult, type ServiceAccountOptions, ServiceAccountTokenProvider, type Subscription, type SubscriptionItemSummary, type SubscriptionPlanSummary, type SubscriptionStatusResult, SubscriptionsResource, type TokenResolver, type WaitUntilPaidOptions, type WebhookEndpointInput, type WebhookEndpointSummary, WebhooksResource, _default as billingPlugin, createServiceAccountToken, expiresIn };
808
+ export { type AppliedDiscount, BillingApiError, BillingClient, type BillingClientOptions, type BillingItem, type BillingPeriod, type BillingPlanSummary, type BillingPluginOptions, type BillingRecurringInterval, type BillingRecurringStatus, type BillingSubscriptionCancelReason, type Charge, type ChargeStatus, ChargesResource, type CheckoutForCustomerInput, type CheckoutForCustomerResult, CheckoutResource, type CheckoutSessionStatus, type CheckoutStatusResult, type Coupon, type CouponDuration, type CouponType, CouponsResource, type CreateBillingPlanInput, type CreateChargeInput, type CreateChargeResult, type CreateCouponInput, type CreateOrderInput, type CreateOrderResult, type CreateSubscriptionInput, type CreateSubscriptionResult, type Customer, type CustomerInput, CustomersResource, type ExpirationUnit, type GetPublicPlanPageResult, HttpClient, type HttpClientOptions, type ItemInput, ItemsResource, type ListPublicPlansResult, OrdersResource, type OutboundWebhookEventType, type PaymentMethod, type PlanCheckoutCustomerInput, type PlanCheckoutInput, type PlanCheckoutResult, type PlanSubscriptionStatusResult, PlansResource, type ProrationPolicy, type PublicBillingPlan, type PublicOrganization, type PublicPlanBranding, type QuickChargeInput, type QuickChargeResult, type ServiceAccountOptions, ServiceAccountTokenProvider, type Subscription, type SubscriptionItemSummary, type SubscriptionPlanSummary, type SubscriptionStatusResult, SubscriptionsResource, type TokenResolver, type WaitUntilPaidOptions, type WebhookEndpointInput, type WebhookEndpointSummary, WebhooksResource, _default as billingPlugin, createServiceAccountToken, expiresIn };
package/dist/index.js CHANGED
@@ -290,6 +290,50 @@ var CheckoutResource = class {
290
290
  }
291
291
  };
292
292
 
293
+ // src/resources/coupons.ts
294
+ var CouponsResource = class {
295
+ constructor(http) {
296
+ this.http = http;
297
+ }
298
+ list() {
299
+ return this.http.get("/coupons");
300
+ }
301
+ /** `idOrCode` aceita tanto o id interno (`coupon.id`) quanto o `code` legível que você
302
+ * escolheu na criação (ex: `"BEMVINDO20"`) — normalmente é mais prático guardar/usar o
303
+ * `code`, já que é você quem o define e é o que aparece para o cliente final. */
304
+ get(idOrCode) {
305
+ return this.http.get(`/coupons/${idOrCode}`);
306
+ }
307
+ /**
308
+ * Cria um cupom de desconto — o `code` é o que o cliente final informa no checkout
309
+ * (`plans.checkout(planId, { coupon_code })`).
310
+ *
311
+ * ```ts
312
+ * // 20% de desconto, aplicado só na primeira cobrança
313
+ * await client.coupons.create({ code: "BEMVINDO20", type: "PERCENTAGE", value: 20, duration: "ONCE" });
314
+ *
315
+ * // R$10 de desconto, repetido pelas 3 primeiras renovações
316
+ * await client.coupons.create({
317
+ * code: "R10X3", type: "FIXED", value: 1000, duration: "REPEATING", duration_months: 3,
318
+ * });
319
+ * ```
320
+ */
321
+ create(input) {
322
+ return this.http.post("/coupons", input);
323
+ }
324
+ /** Só permite editar limites/validade/ativação — o desconto em si (type/value/duration)
325
+ * de um cupom já criado é imutável; crie um novo código para mudar o valor do desconto.
326
+ * `idOrCode` aceita id interno ou `code` (ver `get`). */
327
+ update(idOrCode, input) {
328
+ return this.http.patch(`/coupons/${idOrCode}`, input);
329
+ }
330
+ /** Desativa o cupom (soft-delete) — códigos já resgatados continuam no histórico.
331
+ * `idOrCode` aceita id interno ou `code` (ver `get`). */
332
+ remove(idOrCode) {
333
+ return this.http.delete(`/coupons/${idOrCode}`);
334
+ }
335
+ };
336
+
293
337
  // src/resources/customers.ts
294
338
  var CustomersResource = class {
295
339
  constructor(http) {
@@ -402,7 +446,8 @@ var PlansResource = class {
402
446
  return this.http.post(`/billing-plans/${planId}/checkout-for-customer`, {
403
447
  customer_id: customerId,
404
448
  ...input?.return_url ? { return_url: input.return_url } : {},
405
- ...input?.expires_in ? { expires_in: input.expires_in } : {}
449
+ ...input?.expires_in ? { expires_in: input.expires_in } : {},
450
+ ...input?.coupon_code ? { coupon_code: input.coupon_code } : {}
406
451
  });
407
452
  }
408
453
  /** Verifica se um `Customer` tem uma assinatura ativa deste plano (a mais recente),
@@ -429,6 +474,7 @@ var PlansResource = class {
429
474
  * ```ts
430
475
  * const { checkout_url, checkout_token } = await client.plans.checkout(planId, {
431
476
  * customer: { name, email },
477
+ * coupon_code: "PROMO20", // opcional — página já abre com o desconto aplicado
432
478
  * });
433
479
  * // redirecione o cliente (ou abra checkout_url em uma WebView/nova aba)
434
480
  * window.location.href = checkout_url;
@@ -455,6 +501,20 @@ var SubscriptionsResource = class {
455
501
  list() {
456
502
  return this.http.get("/billing-subscriptions");
457
503
  }
504
+ /**
505
+ * Fluxo legado de assinatura por `BillingItem` avulso (sem `BillingPlan`) — requer
506
+ * autenticação (service account) e que `customer_id`/`item_id` já existam na sua org.
507
+ * Prefira `plans.checkout`/`plans.checkoutPlan` para novos catálogos baseados em plano.
508
+ *
509
+ * ```ts
510
+ * await client.subscriptions.create({
511
+ * customer_id, item_id, interval: "MONTHLY", coupon_code: "PROMO20",
512
+ * });
513
+ * ```
514
+ */
515
+ create(input) {
516
+ return this.http.post("/billing-subscriptions", input);
517
+ }
458
518
  /** Requer autenticação (service account). */
459
519
  get(id) {
460
520
  return this.http.get(`/billing-subscriptions/${id}`);
@@ -469,15 +529,22 @@ var SubscriptionsResource = class {
469
529
  * um link de confirmação para o cliente final revisar custo e vigência e confirmar
470
530
  * expressamente antes de qualquer cobrança ou mudança de plano acontecer.
471
531
  *
532
+ * `couponCode`: aplica um cupom na troca — se a assinatura for Stripe, o desconto passa a
533
+ * valer também nas renovações futuras (recorrente, direto na Subscription); se for
534
+ * PIX/boleto, o desconto vale só para a cobrança de proration desta troca.
535
+ *
472
536
  * ```ts
473
- * const { confirmation_url } = await client.subscriptions.requestPlanSwap(subId, newPlanId);
537
+ * const { confirmation_url } = await client.subscriptions.requestPlanSwap(subId, newPlanId, {
538
+ * couponCode: "PROMO20",
539
+ * });
474
540
  * // redirecione o cliente final para confirmation_url
475
541
  * ```
476
542
  */
477
- requestPlanSwap(id, newPlanId, expiresInSeconds) {
543
+ requestPlanSwap(id, newPlanId, options) {
478
544
  return this.http.patch(`/billing-subscriptions/${id}/swap`, {
479
545
  new_plan_id: newPlanId,
480
- ...expiresInSeconds ? { expires_in: expiresInSeconds } : {}
546
+ ...options?.expiresInSeconds ? { expires_in: options.expiresInSeconds } : {},
547
+ ...options?.couponCode ? { coupon_code: options.couponCode } : {}
481
548
  });
482
549
  }
483
550
  /**
@@ -544,6 +611,7 @@ var BillingClient = class {
544
611
  this.http = new HttpClient(options);
545
612
  this.charges = new ChargesResource(this.http);
546
613
  this.checkout = new CheckoutResource(this.http);
614
+ this.coupons = new CouponsResource(this.http);
547
615
  this.customers = new CustomersResource(this.http);
548
616
  this.items = new ItemsResource(this.http);
549
617
  this.orders = new OrdersResource(this.http);
@@ -662,6 +730,7 @@ export {
662
730
  BillingClient,
663
731
  ChargesResource,
664
732
  CheckoutResource,
733
+ CouponsResource,
665
734
  CustomersResource,
666
735
  HttpClient,
667
736
  ItemsResource,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/getPluginName.js","../../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/toCamelCase.js","../../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/index.js","../src/errors.ts","../src/http.ts","../src/resources/charges.ts","../src/resources/checkout.ts","../src/resources/customers.ts","../src/resources/items.ts","../src/resources/orders.ts","../src/resources/plans.ts","../src/resources/subscriptions.ts","../src/resources/webhooks.ts","../src/client.ts","../src/plugin.ts","../src/service-account.ts","../src/expiration.ts"],"sourcesContent":["'use strict'\n\nconst fpStackTracePattern = /at\\s(?:.*\\.)?plugin\\s.*\\n\\s*(.*)/\nconst fileNamePattern = /(\\w*(\\.\\w*)*)\\..*/\n\nmodule.exports = function getPluginName (fn) {\n if (fn.name.length > 0) return fn.name\n\n const stackTraceLimit = Error.stackTraceLimit\n Error.stackTraceLimit = 10\n try {\n throw new Error('anonymous function')\n } catch (e) {\n Error.stackTraceLimit = stackTraceLimit\n return extractPluginName(e.stack)\n }\n}\n\nfunction extractPluginName (stack) {\n const m = stack.match(fpStackTracePattern)\n\n // get last section of path and match for filename\n return m ? m[1].split(/[/\\\\]/).slice(-1)[0].match(fileNamePattern)[1] : 'anonymous'\n}\nmodule.exports.extractPluginName = extractPluginName\n","'use strict'\n\nmodule.exports = function toCamelCase (name) {\n if (name[0] === '@') {\n name = name.slice(1).replace('/', '-')\n }\n return name.replace(/-(.)/g, function (match, g1) {\n return g1.toUpperCase()\n })\n}\n","'use strict'\n\nconst getPluginName = require('./lib/getPluginName')\nconst toCamelCase = require('./lib/toCamelCase')\n\nlet count = 0\n\nfunction plugin (fn, options = {}) {\n let autoName = false\n\n if (fn.default !== undefined) {\n // Support for 'export default' behaviour in transpiled ECMAScript module\n fn = fn.default\n }\n\n if (typeof fn !== 'function') {\n throw new TypeError(\n `fastify-plugin expects a function, instead got a '${typeof fn}'`\n )\n }\n\n if (typeof options === 'string') {\n options = {\n fastify: options\n }\n }\n\n if (\n typeof options !== 'object' ||\n Array.isArray(options) ||\n options === null\n ) {\n throw new TypeError('The options object should be an object')\n }\n\n if (options.fastify !== undefined && typeof options.fastify !== 'string') {\n throw new TypeError(`fastify-plugin expects a version string, instead got '${typeof options.fastify}'`)\n }\n\n if (!options.name) {\n autoName = true\n options.name = getPluginName(fn) + '-auto-' + count++\n }\n\n fn[Symbol.for('skip-override')] = options.encapsulate !== true\n fn[Symbol.for('fastify.display-name')] = options.name\n fn[Symbol.for('plugin-meta')] = options\n\n // Faux modules support\n if (!fn.default) {\n fn.default = fn\n }\n\n // TypeScript support for named imports\n // See https://github.com/fastify/fastify/issues/2404 for more details\n // The type definitions would have to be update to match this.\n const camelCase = toCamelCase(options.name)\n if (!autoName && !fn[camelCase]) {\n fn[camelCase] = fn\n }\n\n return fn\n}\n\nmodule.exports = plugin\nmodule.exports.default = plugin\nmodule.exports.fastifyPlugin = plugin\n","export class BillingApiError extends Error {\n constructor(\n public readonly status: number,\n message: string,\n public readonly detail?: string,\n ) {\n super(detail ? `${message}: ${detail}` : message);\n this.name = \"BillingApiError\";\n }\n\n get isNotFound() {\n return this.status === 404;\n }\n\n get isUnauthorized() {\n return this.status === 401;\n }\n\n get isForbidden() {\n return this.status === 403;\n }\n\n get isRateLimited() {\n return this.status === 429;\n }\n\n get isValidationError() {\n return this.status === 400 || this.status === 422;\n }\n}\n","import { BillingApiError } from \"./errors.js\";\n\nexport type TokenResolver = string | (() => string | Promise<string>);\n\nexport interface HttpClientOptions {\n baseUrl: string;\n token: TokenResolver;\n organizationId?: string | (() => string | Promise<string>);\n /**\n * Ambiente de billing (dev/prod) — enviado via header x-billing-mode em toda chamada\n * feita por esta instância. Defina uma vez aqui; os métodos individuais (charges.create,\n * customers.list, etc) nunca precisam recebê-lo de novo. Default: \"prod\".\n */\n mode?: string | (() => string | Promise<string>);\n}\n\nconst DEFAULT_MODE = \"prod\";\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly token: TokenResolver;\n private readonly organizationId?: string | (() => string | Promise<string>);\n private readonly mode: string | (() => string | Promise<string>);\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.token = options.token;\n this.organizationId = options.organizationId;\n this.mode = options.mode ?? DEFAULT_MODE;\n }\n\n private async resolveToken(): Promise<string> {\n return typeof this.token === \"function\" ? await this.token() : this.token;\n }\n\n private async resolveOrgId(): Promise<string | undefined> {\n if (!this.organizationId) return undefined;\n return typeof this.organizationId === \"function\"\n ? await this.organizationId()\n : this.organizationId;\n }\n\n private async resolveMode(): Promise<string> {\n return typeof this.mode === \"function\" ? await this.mode() : this.mode;\n }\n\n async request<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const token = await this.resolveToken();\n const orgId = await this.resolveOrgId();\n const mode = await this.resolveMode();\n\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n ...(orgId ? { \"x-org-id\": orgId } : {}),\n \"x-billing-mode\": mode,\n },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({})) as {\n error?: string;\n message?: string;\n };\n throw new BillingApiError(\n res.status,\n err.error ?? err.message ?? `HTTP ${res.status}`,\n );\n }\n\n if (res.status === 202 || res.status === 204) {\n if (res.status === 204) return undefined as T;\n return res.json().catch(() => undefined) as Promise<T>;\n }\n return res.json() as Promise<T>;\n }\n\n get<T>(path: string) {\n return this.request<T>(\"GET\", path);\n }\n\n post<T>(path: string, body?: unknown) {\n return this.request<T>(\"POST\", path, body);\n }\n\n put<T>(path: string, body?: unknown) {\n return this.request<T>(\"PUT\", path, body);\n }\n\n patch<T>(path: string, body?: unknown) {\n return this.request<T>(\"PATCH\", path, body);\n }\n\n delete<T = void>(path: string) {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { Charge, CreateChargeInput, CreateChargeResult, QuickChargeInput, QuickChargeResult } from \"../types.js\";\n\nexport class ChargesResource {\n constructor(private readonly http: HttpClient) {}\n\n list(params?: { installment_group_id?: string }): Promise<Charge[]> {\n const qs = params?.installment_group_id\n ? `?installment_group_id=${encodeURIComponent(params.installment_group_id)}`\n : \"\";\n return this.http.get<Charge[]>(`/charges${qs}`);\n }\n\n /**\n * Cria uma cobrança (PIX, boleto ou cartão). A geração de fato acontece de forma\n * assíncrona no backend — a resposta volta com a charge em PENDING, sem os campos\n * do método (QR code, boleto, etc) ainda preenchidos. Use `get`/`getStatus` para\n * acompanhar até que estejam prontos.\n */\n create(input: CreateChargeInput): Promise<CreateChargeResult> {\n return this.http.post<CreateChargeResult>(\"/charges\", input);\n }\n\n /**\n * Cobrança avulsa simples, sempre em cartão — cobra direto no cartão padrão já\n * salvo do cliente (sem fricção nenhuma). Se ele ainda não tiver um cartão salvo,\n * retorna `checkout_url` para você abrir (ex: nova aba) e o cliente cadastrar o\n * cartão e pagar.\n *\n * ```ts\n * const result = await client.charges.charge(customerId, 5000); // R$ 50,00\n * if (!result.charged_off_session) {\n * window.open(result.checkout_url!, \"_blank\");\n * }\n * ```\n */\n charge(customerId: string, amountCents: number, options?: Omit<QuickChargeInput, \"customer_id\" | \"amount\">): Promise<QuickChargeResult> {\n return this.http.post<QuickChargeResult>(\"/charges/quick\", {\n customer_id: customerId,\n amount: amountCents,\n ...options,\n });\n }\n\n get(id: string): Promise<Charge> {\n return this.http.get<Charge>(`/charges/${id}`);\n }\n\n getStatus(id: string): Promise<{ status: Charge[\"status\"] }> {\n return this.http.get(`/charges/${id}/status`);\n }\n\n cancel(id: string): Promise<Charge> {\n return this.http.patch<Charge>(`/charges/${id}/cancel`);\n }\n\n refund(id: string): Promise<Charge> {\n return this.http.post<Charge>(`/charges/${id}/refund`);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { CheckoutStatusResult } from \"../types.js\";\n\nexport interface WaitUntilPaidOptions {\n /** Intervalo entre tentativas, em ms. Default: 2000. */\n intervalMs?: number;\n /** Tempo máximo de espera antes de desistir, em ms. Default: 5 minutos. */\n timeoutMs?: number;\n}\n\nexport class CheckoutResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Consulta o status atual de uma cobrança/checkout pelo `checkout_token` retornado\n * por `plans.checkout()` (ou qualquer outro fluxo de cobrança do SDK). Sincroniza com\n * o provedor de pagamento sob o capô quando ainda está PENDING. */\n getStatus(checkoutToken: string): Promise<CheckoutStatusResult> {\n return this.http.get<CheckoutStatusResult>(`/checkout/${checkoutToken}/status`);\n }\n\n /**\n * Faz polling de `getStatus` até o pagamento ser confirmado (ou falhar/expirar) — é\n * a forma recomendada de confirmar, depois de redirecionar o cliente para a\n * `checkout_url`, que a assinatura realmente foi paga antes de liberar acesso.\n *\n * Resolve quando o status deixa de ser PENDING/PROCESSING. Lança um erro se o tempo\n * limite (`timeoutMs`) for atingido antes disso.\n */\n async waitUntilPaid(checkoutToken: string, options: WaitUntilPaidOptions = {}): Promise<CheckoutStatusResult> {\n const intervalMs = options.intervalMs ?? 2000;\n const timeoutMs = options.timeoutMs ?? 5 * 60 * 1000;\n const deadline = Date.now() + timeoutMs;\n\n for (;;) {\n const result = await this.getStatus(checkoutToken);\n if (result.status !== \"PENDING\" && result.status !== \"PROCESSING\") {\n return result;\n }\n if (Date.now() >= deadline) {\n throw new Error(`Tempo limite excedido aguardando confirmação de pagamento (checkout_token=${checkoutToken}).`);\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { Customer, CustomerInput } from \"../types.js\";\n\nexport class CustomersResource {\n constructor(private readonly http: HttpClient) {}\n\n list(): Promise<Customer[]> {\n return this.http.get<Customer[]>(\"/customers\");\n }\n\n create(input: CustomerInput): Promise<Customer> {\n return this.http.post<Customer>(\"/customers\", input);\n }\n\n get(id: string): Promise<Customer> {\n return this.http.get<Customer>(`/customers/${id}`);\n }\n\n update(id: string, input: Partial<CustomerInput>): Promise<Customer> {\n return this.http.patch<Customer>(`/customers/${id}`, input);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { BillingItem } from \"../types.js\";\n\nexport interface ItemInput {\n name: string;\n description?: string;\n amount: number;\n currency?: string;\n}\n\nexport class ItemsResource {\n constructor(private readonly http: HttpClient) {}\n\n list(): Promise<BillingItem[]> {\n return this.http.get<BillingItem[]>(\"/items\");\n }\n\n create(input: ItemInput): Promise<BillingItem> {\n return this.http.post<BillingItem>(\"/items\", input);\n }\n\n get(id: string): Promise<BillingItem> {\n return this.http.get<BillingItem>(`/items/${id}`);\n }\n\n update(id: string, input: Partial<ItemInput>): Promise<BillingItem> {\n return this.http.patch<BillingItem>(`/items/${id}`, input);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { CreateOrderInput, CreateOrderResult } from \"../types.js\";\n\nexport class OrdersResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Cria um pedido parcelado (parcelamento real via cobranças avulsas agendadas,\n * não assinatura). Retorna o `client_secret` da 1ª parcela para o front-end\n * confirmar via Stripe Elements — as parcelas seguintes são cobradas\n * automaticamente pelo backend no cartão salvo.\n */\n create(input: CreateOrderInput): Promise<CreateOrderResult> {\n return this.http.post<CreateOrderResult>(\"/orders\", input);\n }\n\n list(): Promise<unknown[]> {\n return this.http.get(\"/orders\");\n }\n\n get(id: string): Promise<unknown> {\n return this.http.get(`/orders/${id}`);\n }\n}\n","import type { HttpClient } from \"../http.js\";\r\nimport type {\r\n BillingPlanSummary,\r\n CheckoutForCustomerInput,\r\n CheckoutForCustomerResult,\r\n CreateBillingPlanInput,\r\n GetPublicPlanPageResult,\r\n ListPublicPlansResult,\r\n PlanCheckoutInput,\r\n PlanCheckoutResult,\r\n PlanSubscriptionStatusResult,\r\n} from \"../types.js\";\r\n\r\nexport class PlansResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n list(): Promise<BillingPlanSummary[]> {\r\n return this.http.get<BillingPlanSummary[]>(\"/billing-plans\");\r\n }\r\n\r\n get(id: string): Promise<BillingPlanSummary> {\r\n return this.http.get<BillingPlanSummary>(`/billing-plans/${id}`);\r\n }\r\n\r\n create(input: CreateBillingPlanInput): Promise<BillingPlanSummary> {\r\n return this.http.post<BillingPlanSummary>(\"/billing-plans\", input);\r\n }\r\n\r\n update(id: string, input: Partial<CreateBillingPlanInput> & { active?: boolean }): Promise<BillingPlanSummary> {\r\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${id}`, input);\r\n }\r\n\r\n /** Não há hard-delete de planos (assinaturas existentes ainda referenciam) — para\r\n * remover um plano do catálogo público, arquive-o. */\r\n archive(id: string): Promise<BillingPlanSummary> {\r\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${id}`, { active: false });\r\n }\r\n\r\n /** Vincula um plano avulso a uma página de planos existente (mesma org). */\r\n attachToPage(planId: string, pageId: string): Promise<BillingPlanSummary> {\r\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${planId}`, { plan_page_id: pageId });\r\n }\r\n\r\n /** Desvincula um plano da sua página, tornando-o avulso (sem página pública). */\r\n detachFromPage(planId: string): Promise<BillingPlanSummary> {\r\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${planId}`, { plan_page_id: null });\r\n }\r\n\r\n /**\r\n * Fluxo simplificado de assinatura para um `Customer` já cadastrado na sua org\r\n * (autenticado, sem formulário de nome/e-mail): cria a assinatura + cobrança inicial e\r\n * retorna a URL de checkout hospedada.\r\n *\r\n * ```ts\r\n * const { checkout_url } = await client.plans.checkoutPlan(planId, customerId, {\r\n * return_url: \"https://meuapp.com/conta?upgraded=1\",\r\n * });\r\n * // redirecione o cliente para checkout_url; ele paga e volta para sua URL de retorno\r\n *\r\n * // depois que o cliente volta:\r\n * const { active, item } = await client.plans.confirmPlanSubscription(planId, customerId);\r\n * if (active) {\r\n * // ativa o plano real no seu sistema\r\n * }\r\n * ```\r\n */\r\n checkoutPlan(planId: string, customerId: string, input?: CheckoutForCustomerInput): Promise<CheckoutForCustomerResult> {\r\n return this.http.post<CheckoutForCustomerResult>(`/billing-plans/${planId}/checkout-for-customer`, {\r\n customer_id: customerId,\r\n ...(input?.return_url ? { return_url: input.return_url } : {}),\r\n ...(input?.expires_in ? { expires_in: input.expires_in } : {}),\r\n });\r\n }\r\n\r\n /** Verifica se um `Customer` tem uma assinatura ativa deste plano (a mais recente),\r\n * contraparte de `checkoutPlan` no fluxo simplificado autenticado. */\r\n confirmPlanSubscription(planId: string, customerId: string): Promise<PlanSubscriptionStatusResult> {\r\n return this.http.get<PlanSubscriptionStatusResult>(`/billing-plans/${planId}/subscription-status?customer_id=${encodeURIComponent(customerId)}`);\r\n }\r\n\r\n // ─── Rotas públicas (sem auth — usadas para montar sua própria página de preços) ──\r\n\r\n /** Lista os planos ativos de uma org pelo slug público — página fixa legada, sem\r\n * suporte a múltiplas páginas. Prefira `getPublicPage` para orgs com várias páginas. */\r\n listPublic(orgSlug: string): Promise<ListPublicPlansResult> {\r\n return this.http.get<ListPublicPlansResult>(`/public/orgs/${orgSlug}/billing-plans`);\r\n }\r\n\r\n /** Busca uma página de planos pública específica pelo slug da org + slug da página. */\r\n getPublicPage(orgSlug: string, pageSlug: string): Promise<GetPublicPlanPageResult> {\r\n return this.http.get<GetPublicPlanPageResult>(`/public/orgs/${orgSlug}/plan-pages/${pageSlug}`);\r\n }\r\n\r\n /**\r\n * Inicia a assinatura de um plano para um cliente final: cria (ou reaproveita) o\r\n * `Customer` pelo e-mail, cria a `Subscription` e retorna uma URL de checkout hospedada\r\n * pela Geekapps para o cliente confirmar o pagamento.\r\n *\r\n * Fluxo típico:\r\n * ```ts\r\n * const { checkout_url, checkout_token } = await client.plans.checkout(planId, {\r\n * customer: { name, email },\r\n * });\r\n * // redirecione o cliente (ou abra checkout_url em uma WebView/nova aba)\r\n * window.location.href = checkout_url;\r\n *\r\n * // depois do retorno, confirme se realmente foi pago:\r\n * const { status } = await client.checkout.waitUntilPaid(checkout_token);\r\n * if (status === \"PAID\") { /* liberar acesso *\\/ }\r\n * ```\r\n *\r\n * Não requer autenticação — pode ser chamado a partir do backend do dev sem token de\r\n * service account, ou do próprio SDK server-side usando qualquer token válido.\r\n */\r\n checkout(planId: string, input: PlanCheckoutInput): Promise<PlanCheckoutResult> {\r\n return this.http.post<PlanCheckoutResult>(`/public/billing-plans/${planId}/checkout`, input);\r\n }\r\n}\r\n","import type { HttpClient } from \"../http.js\";\r\nimport type { Subscription, SubscriptionStatusResult } from \"../types.js\";\r\n\r\nexport class SubscriptionsResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /** Requer autenticação (service account) — lista todas as assinaturas da sua org. */\r\n list(): Promise<Subscription[]> {\r\n return this.http.get<Subscription[]>(\"/billing-subscriptions\");\r\n }\r\n\r\n /** Requer autenticação (service account). */\r\n get(id: string): Promise<Subscription> {\r\n return this.http.get<Subscription>(`/billing-subscriptions/${id}`);\r\n }\r\n\r\n /** Requer autenticação (service account). */\r\n cancel(id: string): Promise<Subscription> {\r\n return this.http.patch<Subscription>(`/billing-subscriptions/${id}/cancel`);\r\n }\r\n\r\n /**\r\n * Inicia uma troca de plano/item de uma assinatura já existente (upgrade/downgrade de\r\n * tier) — requer autenticação (service account). NÃO executa a troca diretamente: retorna\r\n * um link de confirmação para o cliente final revisar custo e vigência e confirmar\r\n * expressamente antes de qualquer cobrança ou mudança de plano acontecer.\r\n *\r\n * ```ts\r\n * const { confirmation_url } = await client.subscriptions.requestPlanSwap(subId, newPlanId);\r\n * // redirecione o cliente final para confirmation_url\r\n * ```\r\n */\r\n requestPlanSwap(id: string, newPlanId: string, expiresInSeconds?: number): Promise<{ confirmation_url: string }> {\r\n return this.http.patch(`/billing-subscriptions/${id}/swap`, {\r\n new_plan_id: newPlanId,\r\n ...(expiresInSeconds ? { expires_in: expiresInSeconds } : {}),\r\n });\r\n }\r\n\r\n /**\r\n * Verifica se uma assinatura está ativa e qual item ela cobre, usando o\r\n * `management_token` retornado por `plans.checkout()` — rota pública, sem\r\n * autenticação, segura para chamar tanto do seu backend quanto (via fetch direto,\r\n * sem o SDK) do client-side do seu app.\r\n *\r\n * ```ts\r\n * const status = await client.subscriptions.checkByToken(managementToken);\r\n * if (status.subscription.active) {\r\n * console.log(\"cobrando\", status.item.name);\r\n * }\r\n * ```\r\n */\r\n checkByToken(managementToken: string): Promise<SubscriptionStatusResult> {\r\n return this.http.get<SubscriptionStatusResult>(`/public/plan-management/${managementToken}`);\r\n }\r\n}\r\n","import type { HttpClient } from \"../http.js\";\r\n\r\nexport type OutboundWebhookEventType =\r\n | \"SUBSCRIPTION_CREATED\"\r\n | \"SUBSCRIPTION_PLAN_SWAPPED\"\r\n | \"SUBSCRIPTION_CANCELLED\"\r\n | \"CHARGE_PAID\"\r\n | \"CHARGE_FAILED\";\r\n\r\nexport interface WebhookEndpointInput {\r\n url: string;\r\n eventTypes: OutboundWebhookEventType[];\r\n /** Opcional — quando omitido, o servidor gera um secret automaticamente. */\r\n secret?: string;\r\n}\r\n\r\nexport interface WebhookEndpointSummary {\r\n id: string;\r\n url: string;\r\n event_types: OutboundWebhookEventType[];\r\n active: boolean;\r\n /** Segredo completo apenas na primeira criação — em toda resposta subsequente vem mascarado. */\r\n secret: string;\r\n created_at: string;\r\n updated_at: string;\r\n}\r\n\r\nexport class WebhooksResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /** Lista os webhooks outbound cadastrados na sua org (secret sempre mascarado). */\r\n list(): Promise<WebhookEndpointSummary[]> {\r\n return this.http.get<WebhookEndpointSummary[]>(\"/webhook-endpoints\");\r\n }\r\n\r\n /**\r\n * Registra um webhook outbound — idempotente por (org, url): chamar de novo com a\r\n * mesma URL apenas atualiza os `eventTypes`, sem criar duplicata. Guarde o `secret`\r\n * retornado (só vem completo na primeira criação) para validar a assinatura\r\n * `X-Geekapps-Signature` nas entregas recebidas. Passe `secret` para definir o seu\r\n * próprio signing secret; se omitido, um valor aleatório é gerado automaticamente.\r\n */\r\n register(input: WebhookEndpointInput): Promise<WebhookEndpointSummary> {\r\n return this.http.post<WebhookEndpointSummary>(\"/webhook-endpoints\", {\r\n url: input.url,\r\n event_types: input.eventTypes,\r\n ...(input.secret ? { secret: input.secret } : {}),\r\n });\r\n }\r\n\r\n /** Edita um webhook existente — URL, eventos assinados e/ou status ativo/inativo. */\r\n update(id: string, input: Partial<WebhookEndpointInput> & { active?: boolean }): Promise<WebhookEndpointSummary> {\r\n return this.http.patch<WebhookEndpointSummary>(`/webhook-endpoints/${id}`, {\r\n ...(input.url ? { url: input.url } : {}),\r\n ...(input.eventTypes ? { event_types: input.eventTypes } : {}),\r\n ...(input.active !== undefined ? { active: input.active } : {}),\r\n });\r\n }\r\n\r\n /** Gera um novo secret e substitui o atual — a versão antiga deixa de validar imediatamente. */\r\n rotateSecret(id: string): Promise<WebhookEndpointSummary> {\r\n return this.http.post<WebhookEndpointSummary>(`/webhook-endpoints/${id}/rotate-secret`);\r\n }\r\n\r\n remove(id: string): Promise<void> {\r\n return this.http.delete<void>(`/webhook-endpoints/${id}`);\r\n }\r\n}\r\n","import { HttpClient, type HttpClientOptions } from \"./http.js\";\r\nimport { ChargesResource } from \"./resources/charges.js\";\r\nimport { CheckoutResource } from \"./resources/checkout.js\";\r\nimport { CustomersResource } from \"./resources/customers.js\";\r\nimport { ItemsResource } from \"./resources/items.js\";\r\nimport { OrdersResource } from \"./resources/orders.js\";\r\nimport { PlansResource } from \"./resources/plans.js\";\r\nimport { SubscriptionsResource } from \"./resources/subscriptions.js\";\r\nimport { WebhooksResource } from \"./resources/webhooks.js\";\r\n\r\nexport interface BillingClientOptions\r\n extends Omit<HttpClientOptions, \"baseUrl\"> {\r\n baseUrl?: string;\r\n}\r\n\r\nexport class BillingClient {\r\n private readonly http: HttpClient;\r\n\r\n readonly charges: ChargesResource;\r\n readonly checkout: CheckoutResource;\r\n readonly customers: CustomersResource;\r\n readonly items: ItemsResource;\r\n readonly orders: OrdersResource;\r\n readonly plans: PlansResource;\r\n readonly subscriptions: SubscriptionsResource;\r\n readonly webhooks: WebhooksResource;\r\n\r\n constructor(options: HttpClientOptions) {\r\n this.http = new HttpClient(options);\r\n\r\n this.charges = new ChargesResource(this.http);\r\n this.checkout = new CheckoutResource(this.http);\r\n this.customers = new CustomersResource(this.http);\r\n this.items = new ItemsResource(this.http);\r\n this.orders = new OrdersResource(this.http);\r\n this.plans = new PlansResource(this.http);\r\n this.subscriptions = new SubscriptionsResource(this.http);\r\n this.webhooks = new WebhooksResource(this.http);\r\n }\r\n}\r\n","import type { FastifyInstance, FastifyPluginAsync } from \"fastify\";\nimport fp from \"fastify-plugin\";\nimport { BillingClient } from \"./client.js\";\nimport { ServiceAccountTokenProvider, type ServiceAccountOptions } from \"./service-account.js\";\n\nexport interface BillingPluginOptions {\n /** Geekapps Billing API base URL */\n baseUrl: string;\n /** Service account credentials — required */\n serviceAccount: ServiceAccountOptions;\n /** Ambiente de billing (dev/prod). Default: \"prod\". */\n mode?: string;\n}\n\ndeclare module \"fastify\" {\n interface FastifyInstance {\n billingClient: BillingClient;\n }\n}\n\nconst billingPlugin: FastifyPluginAsync<BillingPluginOptions> = async (\n fastify: FastifyInstance,\n options: BillingPluginOptions,\n) => {\n const tokenProvider = new ServiceAccountTokenProvider(options.serviceAccount);\n\n const client = new BillingClient({\n baseUrl: options.baseUrl,\n token: () => tokenProvider.getToken(),\n organizationId: () => tokenProvider.getOrganizationId() as Promise<string>,\n mode: options.mode,\n });\n\n fastify.decorate(\"billingClient\", client);\n};\n\nexport default fp(billingPlugin, {\n fastify: \">=4.0.0\",\n name: \"@geekapps/billing-fastify\",\n});\n","import type { TokenResolver } from \"./http.js\";\n\nexport interface ServiceAccountOptions {\n /** Geekapps Auth issuer base URL (e.g. https://accounts-api.geekapps.com.br) */\n issuerUrl: string;\n clientId: string;\n clientSecret: string;\n /** Seconds before expiry to proactively refresh. Defaults to 30. */\n refreshBeforeExpirySeconds?: number;\n}\n\ninterface CachedToken {\n value: string;\n expiresAt: number; // ms epoch\n organizationId: string | undefined;\n}\n\nfunction decodeJwtPayload(token: string): Record<string, unknown> {\n try {\n const [, payload] = token.split(\".\");\n if (!payload) return {};\n const json = Buffer.from(payload, \"base64url\").toString(\"utf-8\");\n return JSON.parse(json) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\n/**\n * Fetches a short-lived token from the Geekapps Auth service using\n * client_credentials grant and caches it until near expiry.\n *\n * The organizationId claim is extracted automatically from the JWT payload.\n */\nexport class ServiceAccountTokenProvider {\n private readonly issuerUrl: string;\n private readonly clientId: string;\n private readonly clientSecret: string;\n private readonly refreshBeforeMs: number;\n private cached: CachedToken | null = null;\n private inflight: Promise<CachedToken> | null = null;\n\n constructor(options: ServiceAccountOptions) {\n this.issuerUrl = options.issuerUrl.replace(/\\/$/, \"\");\n this.clientId = options.clientId;\n this.clientSecret = options.clientSecret;\n this.refreshBeforeMs = (options.refreshBeforeExpirySeconds ?? 30) * 1000;\n }\n\n private async ensureFresh(): Promise<CachedToken> {\n const now = Date.now();\n\n if (this.cached && this.cached.expiresAt - now > this.refreshBeforeMs) {\n return this.cached;\n }\n\n if (this.inflight) return this.inflight;\n\n this.inflight = this.fetchToken().finally(() => {\n this.inflight = null;\n });\n\n return this.inflight;\n }\n\n /** Returns a valid access token. */\n getToken(): Promise<string> {\n return this.ensureFresh().then((c) => c.value);\n }\n\n /** Returns the organizationId embedded in the service account JWT. */\n getOrganizationId(): Promise<string | undefined> {\n return this.ensureFresh().then((c) => c.organizationId);\n }\n\n private async fetchToken(): Promise<CachedToken> {\n const credentials = Buffer.from(`${this.clientId}:${this.clientSecret}`).toString(\"base64\");\n\n const res = await fetch(`${this.issuerUrl}/auth/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Basic ${credentials}`,\n },\n body: JSON.stringify({ grant_type: \"service_account\" }),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({})) as { error?: string };\n throw new Error(\n `ServiceAccount token fetch failed (${res.status}): ${err.error ?? \"unknown error\"}`,\n );\n }\n\n const data = await res.json() as { access_token: string; expires_in?: number };\n\n const claims = decodeJwtPayload(data.access_token);\n const organizationId =\n typeof claims.organizationId === \"string\" ? claims.organizationId :\n typeof claims.organization_id === \"string\" ? claims.organization_id :\n typeof claims.org_id === \"string\" ? claims.org_id :\n undefined;\n\n const expiresInMs = (data.expires_in ?? 420) * 1000;\n this.cached = {\n value: data.access_token,\n expiresAt: Date.now() + expiresInMs,\n organizationId,\n };\n\n return this.cached;\n }\n\n /** Returns this provider as a TokenResolver to pass directly to BillingClient. */\n asTokenResolver(): TokenResolver {\n return () => this.getToken();\n }\n}\n\n/** Convenience factory. Returns a TokenResolver ready for use in BillingClient. */\nexport function createServiceAccountToken(\n options: ServiceAccountOptions,\n): TokenResolver {\n return new ServiceAccountTokenProvider(options).asTokenResolver();\n}\n","export type ExpirationUnit = \"seconds\" | \"minutes\" | \"hours\" | \"days\";\n\nconst MULTIPLIERS: Record<ExpirationUnit, number> = {\n seconds: 1,\n minutes: 60,\n hours: 3600,\n days: 86400,\n};\n\n/**\n * Converte um valor + unidade para segundos, prontos para usar em `expires_in`.\n *\n * ```ts\n * await client.charges.create({ ..., expires_in: expiresIn(30, \"minutes\") });\n * ```\n */\nexport function expiresIn(value: number, unit: ExpirationUnit): number {\n return value * MULTIPLIERS[unit];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAEA,QAAM,sBAAsB;AAC5B,QAAM,kBAAkB;AAExB,WAAO,UAAU,SAAS,cAAe,IAAI;AAC3C,UAAI,GAAG,KAAK,SAAS,EAAG,QAAO,GAAG;AAElC,YAAM,kBAAkB,MAAM;AAC9B,YAAM,kBAAkB;AACxB,UAAI;AACF,cAAM,IAAI,MAAM,oBAAoB;AAAA,MACtC,SAAS,GAAG;AACV,cAAM,kBAAkB;AACxB,eAAO,kBAAkB,EAAE,KAAK;AAAA,MAClC;AAAA,IACF;AAEA,aAAS,kBAAmB,OAAO;AACjC,YAAM,IAAI,MAAM,MAAM,mBAAmB;AAGzC,aAAO,IAAI,EAAE,CAAC,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC,IAAI;AAAA,IAC1E;AACA,WAAO,QAAQ,oBAAoB;AAAA;AAAA;;;ACxBnC;AAAA;AAAA;AAEA,WAAO,UAAU,SAAS,YAAa,MAAM;AAC3C,UAAI,KAAK,CAAC,MAAM,KAAK;AACnB,eAAO,KAAK,MAAM,CAAC,EAAE,QAAQ,KAAK,GAAG;AAAA,MACvC;AACA,aAAO,KAAK,QAAQ,SAAS,SAAU,OAAO,IAAI;AAChD,eAAO,GAAG,YAAY;AAAA,MACxB,CAAC;AAAA,IACH;AAAA;AAAA;;;ACTA;AAAA;AAAA;AAEA,QAAM,gBAAgB;AACtB,QAAM,cAAc;AAEpB,QAAI,QAAQ;AAEZ,aAAS,OAAQ,IAAI,UAAU,CAAC,GAAG;AACjC,UAAI,WAAW;AAEf,UAAI,GAAG,YAAY,QAAW;AAE5B,aAAK,GAAG;AAAA,MACV;AAEA,UAAI,OAAO,OAAO,YAAY;AAC5B,cAAM,IAAI;AAAA,UACR,qDAAqD,OAAO,EAAE;AAAA,QAChE;AAAA,MACF;AAEA,UAAI,OAAO,YAAY,UAAU;AAC/B,kBAAU;AAAA,UACR,SAAS;AAAA,QACX;AAAA,MACF;AAEA,UACE,OAAO,YAAY,YACnB,MAAM,QAAQ,OAAO,KACrB,YAAY,MACZ;AACA,cAAM,IAAI,UAAU,wCAAwC;AAAA,MAC9D;AAEA,UAAI,QAAQ,YAAY,UAAa,OAAO,QAAQ,YAAY,UAAU;AACxE,cAAM,IAAI,UAAU,yDAAyD,OAAO,QAAQ,OAAO,GAAG;AAAA,MACxG;AAEA,UAAI,CAAC,QAAQ,MAAM;AACjB,mBAAW;AACX,gBAAQ,OAAO,cAAc,EAAE,IAAI,WAAW;AAAA,MAChD;AAEA,SAAG,uBAAO,IAAI,eAAe,CAAC,IAAI,QAAQ,gBAAgB;AAC1D,SAAG,uBAAO,IAAI,sBAAsB,CAAC,IAAI,QAAQ;AACjD,SAAG,uBAAO,IAAI,aAAa,CAAC,IAAI;AAGhC,UAAI,CAAC,GAAG,SAAS;AACf,WAAG,UAAU;AAAA,MACf;AAKA,YAAM,YAAY,YAAY,QAAQ,IAAI;AAC1C,UAAI,CAAC,YAAY,CAAC,GAAG,SAAS,GAAG;AAC/B,WAAG,SAAS,IAAI;AAAA,MAClB;AAEA,aAAO;AAAA,IACT;AAEA,WAAO,UAAU;AACjB,WAAO,QAAQ,UAAU;AACzB,WAAO,QAAQ,gBAAgB;AAAA;AAAA;;;AClExB,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YACkB,QAChB,SACgB,QAChB;AACA,UAAM,SAAS,GAAG,OAAO,KAAK,MAAM,KAAK,OAAO;AAJhC;AAEA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,IAAI,aAAa;AACf,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,iBAAiB;AACnB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,gBAAgB;AAClB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,oBAAoB;AACtB,WAAO,KAAK,WAAW,OAAO,KAAK,WAAW;AAAA,EAChD;AACF;;;ACbA,IAAM,eAAe;AAEd,IAAM,aAAN,MAAiB;AAAA,EAMtB,YAAY,SAA4B;AACtC,SAAK,UAAU,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AAChD,SAAK,QAAQ,QAAQ;AACrB,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,OAAO,QAAQ,QAAQ;AAAA,EAC9B;AAAA,EAEA,MAAc,eAAgC;AAC5C,WAAO,OAAO,KAAK,UAAU,aAAa,MAAM,KAAK,MAAM,IAAI,KAAK;AAAA,EACtE;AAAA,EAEA,MAAc,eAA4C;AACxD,QAAI,CAAC,KAAK,eAAgB,QAAO;AACjC,WAAO,OAAO,KAAK,mBAAmB,aAClC,MAAM,KAAK,eAAe,IAC1B,KAAK;AAAA,EACX;AAAA,EAEA,MAAc,cAA+B;AAC3C,WAAO,OAAO,KAAK,SAAS,aAAa,MAAM,KAAK,KAAK,IAAI,KAAK;AAAA,EACpE;AAAA,EAEA,MAAM,QACJ,QACA,MACA,MACY;AACZ,UAAM,QAAQ,MAAM,KAAK,aAAa;AACtC,UAAM,QAAQ,MAAM,KAAK,aAAa;AACtC,UAAM,OAAO,MAAM,KAAK,YAAY;AAEpC,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD;AAAA,MACA,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,GAAI,SAAS,SAAY,EAAE,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,QACnE,GAAI,QAAQ,EAAE,YAAY,MAAM,IAAI,CAAC;AAAA,QACrC,kBAAkB;AAAA,MACpB;AAAA,MACA,GAAI,SAAS,SAAY,EAAE,MAAM,KAAK,UAAU,IAAI,EAAE,IAAI,CAAC;AAAA,IAC7D,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,MAAM,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAI7C,YAAM,IAAI;AAAA,QACR,IAAI;AAAA,QACJ,IAAI,SAAS,IAAI,WAAW,QAAQ,IAAI,MAAM;AAAA,MAChD;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,UAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,aAAO,IAAI,KAAK,EAAE,MAAM,MAAM,MAAS;AAAA,IACzC;AACA,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA,EAEA,IAAO,MAAc;AACnB,WAAO,KAAK,QAAW,OAAO,IAAI;AAAA,EACpC;AAAA,EAEA,KAAQ,MAAc,MAAgB;AACpC,WAAO,KAAK,QAAW,QAAQ,MAAM,IAAI;AAAA,EAC3C;AAAA,EAEA,IAAO,MAAc,MAAgB;AACnC,WAAO,KAAK,QAAW,OAAO,MAAM,IAAI;AAAA,EAC1C;AAAA,EAEA,MAAS,MAAc,MAAgB;AACrC,WAAO,KAAK,QAAW,SAAS,MAAM,IAAI;AAAA,EAC5C;AAAA,EAEA,OAAiB,MAAc;AAC7B,WAAO,KAAK,QAAW,UAAU,IAAI;AAAA,EACvC;AACF;;;ACpGO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,KAAK,QAA+D;AAClE,UAAM,KAAK,QAAQ,uBACf,yBAAyB,mBAAmB,OAAO,oBAAoB,CAAC,KACxE;AACJ,WAAO,KAAK,KAAK,IAAc,WAAW,EAAE,EAAE;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,OAAuD;AAC5D,WAAO,KAAK,KAAK,KAAyB,YAAY,KAAK;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAO,YAAoB,aAAqB,SAAwF;AACtI,WAAO,KAAK,KAAK,KAAwB,kBAAkB;AAAA,MACzD,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,IAA6B;AAC/B,WAAO,KAAK,KAAK,IAAY,YAAY,EAAE,EAAE;AAAA,EAC/C;AAAA,EAEA,UAAU,IAAmD;AAC3D,WAAO,KAAK,KAAK,IAAI,YAAY,EAAE,SAAS;AAAA,EAC9C;AAAA,EAEA,OAAO,IAA6B;AAClC,WAAO,KAAK,KAAK,MAAc,YAAY,EAAE,SAAS;AAAA,EACxD;AAAA,EAEA,OAAO,IAA6B;AAClC,WAAO,KAAK,KAAK,KAAa,YAAY,EAAE,SAAS;AAAA,EACvD;AACF;;;ACjDO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA,EAKhD,UAAU,eAAsD;AAC9D,WAAO,KAAK,KAAK,IAA0B,aAAa,aAAa,SAAS;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,cAAc,eAAuB,UAAgC,CAAC,GAAkC;AAC5G,UAAM,aAAa,QAAQ,cAAc;AACzC,UAAM,YAAY,QAAQ,aAAa,IAAI,KAAK;AAChD,UAAM,WAAW,KAAK,IAAI,IAAI;AAE9B,eAAS;AACP,YAAM,SAAS,MAAM,KAAK,UAAU,aAAa;AACjD,UAAI,OAAO,WAAW,aAAa,OAAO,WAAW,cAAc;AACjE,eAAO;AAAA,MACT;AACA,UAAI,KAAK,IAAI,KAAK,UAAU;AAC1B,cAAM,IAAI,MAAM,mFAA6E,aAAa,IAAI;AAAA,MAChH;AACA,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,UAAU,CAAC;AAAA,IAChE;AAAA,EACF;AACF;;;ACzCO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,OAA4B;AAC1B,WAAO,KAAK,KAAK,IAAgB,YAAY;AAAA,EAC/C;AAAA,EAEA,OAAO,OAAyC;AAC9C,WAAO,KAAK,KAAK,KAAe,cAAc,KAAK;AAAA,EACrD;AAAA,EAEA,IAAI,IAA+B;AACjC,WAAO,KAAK,KAAK,IAAc,cAAc,EAAE,EAAE;AAAA,EACnD;AAAA,EAEA,OAAO,IAAY,OAAkD;AACnE,WAAO,KAAK,KAAK,MAAgB,cAAc,EAAE,IAAI,KAAK;AAAA,EAC5D;AACF;;;ACXO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,OAA+B;AAC7B,WAAO,KAAK,KAAK,IAAmB,QAAQ;AAAA,EAC9C;AAAA,EAEA,OAAO,OAAwC;AAC7C,WAAO,KAAK,KAAK,KAAkB,UAAU,KAAK;AAAA,EACpD;AAAA,EAEA,IAAI,IAAkC;AACpC,WAAO,KAAK,KAAK,IAAiB,UAAU,EAAE,EAAE;AAAA,EAClD;AAAA,EAEA,OAAO,IAAY,OAAiD;AAClE,WAAO,KAAK,KAAK,MAAmB,UAAU,EAAE,IAAI,KAAK;AAAA,EAC3D;AACF;;;ACzBO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhD,OAAO,OAAqD;AAC1D,WAAO,KAAK,KAAK,KAAwB,WAAW,KAAK;AAAA,EAC3D;AAAA,EAEA,OAA2B;AACzB,WAAO,KAAK,KAAK,IAAI,SAAS;AAAA,EAChC;AAAA,EAEA,IAAI,IAA8B;AAChC,WAAO,KAAK,KAAK,IAAI,WAAW,EAAE,EAAE;AAAA,EACtC;AACF;;;ACVO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,OAAsC;AACpC,WAAO,KAAK,KAAK,IAA0B,gBAAgB;AAAA,EAC7D;AAAA,EAEA,IAAI,IAAyC;AAC3C,WAAO,KAAK,KAAK,IAAwB,kBAAkB,EAAE,EAAE;AAAA,EACjE;AAAA,EAEA,OAAO,OAA4D;AACjE,WAAO,KAAK,KAAK,KAAyB,kBAAkB,KAAK;AAAA,EACnE;AAAA,EAEA,OAAO,IAAY,OAA4F;AAC7G,WAAO,KAAK,KAAK,MAA0B,kBAAkB,EAAE,IAAI,KAAK;AAAA,EAC1E;AAAA;AAAA;AAAA,EAIA,QAAQ,IAAyC;AAC/C,WAAO,KAAK,KAAK,MAA0B,kBAAkB,EAAE,IAAI,EAAE,QAAQ,MAAM,CAAC;AAAA,EACtF;AAAA;AAAA,EAGA,aAAa,QAAgB,QAA6C;AACxE,WAAO,KAAK,KAAK,MAA0B,kBAAkB,MAAM,IAAI,EAAE,cAAc,OAAO,CAAC;AAAA,EACjG;AAAA;AAAA,EAGA,eAAe,QAA6C;AAC1D,WAAO,KAAK,KAAK,MAA0B,kBAAkB,MAAM,IAAI,EAAE,cAAc,KAAK,CAAC;AAAA,EAC/F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,aAAa,QAAgB,YAAoB,OAAsE;AACrH,WAAO,KAAK,KAAK,KAAgC,kBAAkB,MAAM,0BAA0B;AAAA,MACjG,aAAa;AAAA,MACb,GAAI,OAAO,aAAa,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAAA,MAC5D,GAAI,OAAO,aAAa,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAAA,IAC9D,CAAC;AAAA,EACH;AAAA;AAAA;AAAA,EAIA,wBAAwB,QAAgB,YAA2D;AACjG,WAAO,KAAK,KAAK,IAAkC,kBAAkB,MAAM,oCAAoC,mBAAmB,UAAU,CAAC,EAAE;AAAA,EACjJ;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,SAAiD;AAC1D,WAAO,KAAK,KAAK,IAA2B,gBAAgB,OAAO,gBAAgB;AAAA,EACrF;AAAA;AAAA,EAGA,cAAc,SAAiB,UAAoD;AACjF,WAAO,KAAK,KAAK,IAA6B,gBAAgB,OAAO,eAAe,QAAQ,EAAE;AAAA,EAChG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,SAAS,QAAgB,OAAuD;AAC9E,WAAO,KAAK,KAAK,KAAyB,yBAAyB,MAAM,aAAa,KAAK;AAAA,EAC7F;AACF;;;AClHO,IAAM,wBAAN,MAA4B;AAAA,EACjC,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA,EAGhD,OAAgC;AAC9B,WAAO,KAAK,KAAK,IAAoB,wBAAwB;AAAA,EAC/D;AAAA;AAAA,EAGA,IAAI,IAAmC;AACrC,WAAO,KAAK,KAAK,IAAkB,0BAA0B,EAAE,EAAE;AAAA,EACnE;AAAA;AAAA,EAGA,OAAO,IAAmC;AACxC,WAAO,KAAK,KAAK,MAAoB,0BAA0B,EAAE,SAAS;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,gBAAgB,IAAY,WAAmB,kBAAkE;AAC/G,WAAO,KAAK,KAAK,MAAM,0BAA0B,EAAE,SAAS;AAAA,MAC1D,aAAa;AAAA,MACb,GAAI,mBAAmB,EAAE,YAAY,iBAAiB,IAAI,CAAC;AAAA,IAC7D,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,aAAa,iBAA4D;AACvE,WAAO,KAAK,KAAK,IAA8B,2BAA2B,eAAe,EAAE;AAAA,EAC7F;AACF;;;AC5BO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA,EAGhD,OAA0C;AACxC,WAAO,KAAK,KAAK,IAA8B,oBAAoB;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAS,OAA8D;AACrE,WAAO,KAAK,KAAK,KAA6B,sBAAsB;AAAA,MAClE,KAAK,MAAM;AAAA,MACX,aAAa,MAAM;AAAA,MACnB,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IACjD,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,OAAO,IAAY,OAA8F;AAC/G,WAAO,KAAK,KAAK,MAA8B,sBAAsB,EAAE,IAAI;AAAA,MACzE,GAAI,MAAM,MAAM,EAAE,KAAK,MAAM,IAAI,IAAI,CAAC;AAAA,MACtC,GAAI,MAAM,aAAa,EAAE,aAAa,MAAM,WAAW,IAAI,CAAC;AAAA,MAC5D,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IAC/D,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,aAAa,IAA6C;AACxD,WAAO,KAAK,KAAK,KAA6B,sBAAsB,EAAE,gBAAgB;AAAA,EACxF;AAAA,EAEA,OAAO,IAA2B;AAChC,WAAO,KAAK,KAAK,OAAa,sBAAsB,EAAE,EAAE;AAAA,EAC1D;AACF;;;ACpDO,IAAM,gBAAN,MAAoB;AAAA,EAYzB,YAAY,SAA4B;AACtC,SAAK,OAAO,IAAI,WAAW,OAAO;AAElC,SAAK,UAAU,IAAI,gBAAgB,KAAK,IAAI;AAC5C,SAAK,WAAW,IAAI,iBAAiB,KAAK,IAAI;AAC9C,SAAK,YAAY,IAAI,kBAAkB,KAAK,IAAI;AAChD,SAAK,QAAQ,IAAI,cAAc,KAAK,IAAI;AACxC,SAAK,SAAS,IAAI,eAAe,KAAK,IAAI;AAC1C,SAAK,QAAQ,IAAI,cAAc,KAAK,IAAI;AACxC,SAAK,gBAAgB,IAAI,sBAAsB,KAAK,IAAI;AACxD,SAAK,WAAW,IAAI,iBAAiB,KAAK,IAAI;AAAA,EAChD;AACF;;;ACtCA,4BAAe;;;ACgBf,SAAS,iBAAiB,OAAwC;AAChE,MAAI;AACF,UAAM,CAAC,EAAE,OAAO,IAAI,MAAM,MAAM,GAAG;AACnC,QAAI,CAAC,QAAS,QAAO,CAAC;AACtB,UAAM,OAAO,OAAO,KAAK,SAAS,WAAW,EAAE,SAAS,OAAO;AAC/D,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAQO,IAAM,8BAAN,MAAkC;AAAA,EAQvC,YAAY,SAAgC;AAH5C,SAAQ,SAA6B;AACrC,SAAQ,WAAwC;AAG9C,SAAK,YAAY,QAAQ,UAAU,QAAQ,OAAO,EAAE;AACpD,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe,QAAQ;AAC5B,SAAK,mBAAmB,QAAQ,8BAA8B,MAAM;AAAA,EACtE;AAAA,EAEA,MAAc,cAAoC;AAChD,UAAM,MAAM,KAAK,IAAI;AAErB,QAAI,KAAK,UAAU,KAAK,OAAO,YAAY,MAAM,KAAK,iBAAiB;AACrE,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,KAAK,SAAU,QAAO,KAAK;AAE/B,SAAK,WAAW,KAAK,WAAW,EAAE,QAAQ,MAAM;AAC9C,WAAK,WAAW;AAAA,IAClB,CAAC;AAED,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,WAA4B;AAC1B,WAAO,KAAK,YAAY,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK;AAAA,EAC/C;AAAA;AAAA,EAGA,oBAAiD;AAC/C,WAAO,KAAK,YAAY,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc;AAAA,EACxD;AAAA,EAEA,MAAc,aAAmC;AAC/C,UAAM,cAAc,OAAO,KAAK,GAAG,KAAK,QAAQ,IAAI,KAAK,YAAY,EAAE,EAAE,SAAS,QAAQ;AAE1F,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,SAAS,eAAe;AAAA,MACtD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,SAAS,WAAW;AAAA,MACrC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,YAAY,kBAAkB,CAAC;AAAA,IACxD,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,MAAM,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC7C,YAAM,IAAI;AAAA,QACR,sCAAsC,IAAI,MAAM,MAAM,IAAI,SAAS,eAAe;AAAA,MACpF;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,IAAI,KAAK;AAE5B,UAAM,SAAS,iBAAiB,KAAK,YAAY;AACjD,UAAM,iBACJ,OAAO,OAAO,mBAAmB,WAAW,OAAO,iBACnD,OAAO,OAAO,oBAAoB,WAAW,OAAO,kBACpD,OAAO,OAAO,WAAW,WAAW,OAAO,SAC3C;AAEF,UAAM,eAAe,KAAK,cAAc,OAAO;AAC/C,SAAK,SAAS;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK,IAAI,IAAI;AAAA,MACxB;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,kBAAiC;AAC/B,WAAO,MAAM,KAAK,SAAS;AAAA,EAC7B;AACF;AAGO,SAAS,0BACd,SACe;AACf,SAAO,IAAI,4BAA4B,OAAO,EAAE,gBAAgB;AAClE;;;ADxGA,IAAM,gBAA0D,OAC9D,SACA,YACG;AACH,QAAM,gBAAgB,IAAI,4BAA4B,QAAQ,cAAc;AAE5E,QAAM,SAAS,IAAI,cAAc;AAAA,IAC/B,SAAS,QAAQ;AAAA,IACjB,OAAO,MAAM,cAAc,SAAS;AAAA,IACpC,gBAAgB,MAAM,cAAc,kBAAkB;AAAA,IACtD,MAAM,QAAQ;AAAA,EAChB,CAAC;AAED,UAAQ,SAAS,iBAAiB,MAAM;AAC1C;AAEA,IAAO,qBAAQ,sBAAAA,SAAG,eAAe;AAAA,EAC/B,SAAS;AAAA,EACT,MAAM;AACR,CAAC;;;AErCD,IAAM,cAA8C;AAAA,EAClD,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AACR;AASO,SAAS,UAAU,OAAe,MAA8B;AACrE,SAAO,QAAQ,YAAY,IAAI;AACjC;","names":["fp"]}
1
+ {"version":3,"sources":["../../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/getPluginName.js","../../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/toCamelCase.js","../../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/index.js","../src/errors.ts","../src/http.ts","../src/resources/charges.ts","../src/resources/checkout.ts","../src/resources/coupons.ts","../src/resources/customers.ts","../src/resources/items.ts","../src/resources/orders.ts","../src/resources/plans.ts","../src/resources/subscriptions.ts","../src/resources/webhooks.ts","../src/client.ts","../src/plugin.ts","../src/service-account.ts","../src/expiration.ts"],"sourcesContent":["'use strict'\n\nconst fpStackTracePattern = /at\\s(?:.*\\.)?plugin\\s.*\\n\\s*(.*)/\nconst fileNamePattern = /(\\w*(\\.\\w*)*)\\..*/\n\nmodule.exports = function getPluginName (fn) {\n if (fn.name.length > 0) return fn.name\n\n const stackTraceLimit = Error.stackTraceLimit\n Error.stackTraceLimit = 10\n try {\n throw new Error('anonymous function')\n } catch (e) {\n Error.stackTraceLimit = stackTraceLimit\n return extractPluginName(e.stack)\n }\n}\n\nfunction extractPluginName (stack) {\n const m = stack.match(fpStackTracePattern)\n\n // get last section of path and match for filename\n return m ? m[1].split(/[/\\\\]/).slice(-1)[0].match(fileNamePattern)[1] : 'anonymous'\n}\nmodule.exports.extractPluginName = extractPluginName\n","'use strict'\n\nmodule.exports = function toCamelCase (name) {\n if (name[0] === '@') {\n name = name.slice(1).replace('/', '-')\n }\n return name.replace(/-(.)/g, function (match, g1) {\n return g1.toUpperCase()\n })\n}\n","'use strict'\n\nconst getPluginName = require('./lib/getPluginName')\nconst toCamelCase = require('./lib/toCamelCase')\n\nlet count = 0\n\nfunction plugin (fn, options = {}) {\n let autoName = false\n\n if (fn.default !== undefined) {\n // Support for 'export default' behaviour in transpiled ECMAScript module\n fn = fn.default\n }\n\n if (typeof fn !== 'function') {\n throw new TypeError(\n `fastify-plugin expects a function, instead got a '${typeof fn}'`\n )\n }\n\n if (typeof options === 'string') {\n options = {\n fastify: options\n }\n }\n\n if (\n typeof options !== 'object' ||\n Array.isArray(options) ||\n options === null\n ) {\n throw new TypeError('The options object should be an object')\n }\n\n if (options.fastify !== undefined && typeof options.fastify !== 'string') {\n throw new TypeError(`fastify-plugin expects a version string, instead got '${typeof options.fastify}'`)\n }\n\n if (!options.name) {\n autoName = true\n options.name = getPluginName(fn) + '-auto-' + count++\n }\n\n fn[Symbol.for('skip-override')] = options.encapsulate !== true\n fn[Symbol.for('fastify.display-name')] = options.name\n fn[Symbol.for('plugin-meta')] = options\n\n // Faux modules support\n if (!fn.default) {\n fn.default = fn\n }\n\n // TypeScript support for named imports\n // See https://github.com/fastify/fastify/issues/2404 for more details\n // The type definitions would have to be update to match this.\n const camelCase = toCamelCase(options.name)\n if (!autoName && !fn[camelCase]) {\n fn[camelCase] = fn\n }\n\n return fn\n}\n\nmodule.exports = plugin\nmodule.exports.default = plugin\nmodule.exports.fastifyPlugin = plugin\n","export class BillingApiError extends Error {\n constructor(\n public readonly status: number,\n message: string,\n public readonly detail?: string,\n ) {\n super(detail ? `${message}: ${detail}` : message);\n this.name = \"BillingApiError\";\n }\n\n get isNotFound() {\n return this.status === 404;\n }\n\n get isUnauthorized() {\n return this.status === 401;\n }\n\n get isForbidden() {\n return this.status === 403;\n }\n\n get isRateLimited() {\n return this.status === 429;\n }\n\n get isValidationError() {\n return this.status === 400 || this.status === 422;\n }\n}\n","import { BillingApiError } from \"./errors.js\";\n\nexport type TokenResolver = string | (() => string | Promise<string>);\n\nexport interface HttpClientOptions {\n baseUrl: string;\n token: TokenResolver;\n organizationId?: string | (() => string | Promise<string>);\n /**\n * Ambiente de billing (dev/prod) — enviado via header x-billing-mode em toda chamada\n * feita por esta instância. Defina uma vez aqui; os métodos individuais (charges.create,\n * customers.list, etc) nunca precisam recebê-lo de novo. Default: \"prod\".\n */\n mode?: string | (() => string | Promise<string>);\n}\n\nconst DEFAULT_MODE = \"prod\";\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly token: TokenResolver;\n private readonly organizationId?: string | (() => string | Promise<string>);\n private readonly mode: string | (() => string | Promise<string>);\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.token = options.token;\n this.organizationId = options.organizationId;\n this.mode = options.mode ?? DEFAULT_MODE;\n }\n\n private async resolveToken(): Promise<string> {\n return typeof this.token === \"function\" ? await this.token() : this.token;\n }\n\n private async resolveOrgId(): Promise<string | undefined> {\n if (!this.organizationId) return undefined;\n return typeof this.organizationId === \"function\"\n ? await this.organizationId()\n : this.organizationId;\n }\n\n private async resolveMode(): Promise<string> {\n return typeof this.mode === \"function\" ? await this.mode() : this.mode;\n }\n\n async request<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const token = await this.resolveToken();\n const orgId = await this.resolveOrgId();\n const mode = await this.resolveMode();\n\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n ...(orgId ? { \"x-org-id\": orgId } : {}),\n \"x-billing-mode\": mode,\n },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({})) as {\n error?: string;\n message?: string;\n };\n throw new BillingApiError(\n res.status,\n err.error ?? err.message ?? `HTTP ${res.status}`,\n );\n }\n\n if (res.status === 202 || res.status === 204) {\n if (res.status === 204) return undefined as T;\n return res.json().catch(() => undefined) as Promise<T>;\n }\n return res.json() as Promise<T>;\n }\n\n get<T>(path: string) {\n return this.request<T>(\"GET\", path);\n }\n\n post<T>(path: string, body?: unknown) {\n return this.request<T>(\"POST\", path, body);\n }\n\n put<T>(path: string, body?: unknown) {\n return this.request<T>(\"PUT\", path, body);\n }\n\n patch<T>(path: string, body?: unknown) {\n return this.request<T>(\"PATCH\", path, body);\n }\n\n delete<T = void>(path: string) {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { Charge, CreateChargeInput, CreateChargeResult, QuickChargeInput, QuickChargeResult } from \"../types.js\";\n\nexport class ChargesResource {\n constructor(private readonly http: HttpClient) {}\n\n list(params?: { installment_group_id?: string }): Promise<Charge[]> {\n const qs = params?.installment_group_id\n ? `?installment_group_id=${encodeURIComponent(params.installment_group_id)}`\n : \"\";\n return this.http.get<Charge[]>(`/charges${qs}`);\n }\n\n /**\n * Cria uma cobrança (PIX, boleto ou cartão). A geração de fato acontece de forma\n * assíncrona no backend — a resposta volta com a charge em PENDING, sem os campos\n * do método (QR code, boleto, etc) ainda preenchidos. Use `get`/`getStatus` para\n * acompanhar até que estejam prontos.\n */\n create(input: CreateChargeInput): Promise<CreateChargeResult> {\n return this.http.post<CreateChargeResult>(\"/charges\", input);\n }\n\n /**\n * Cobrança avulsa simples, sempre em cartão — cobra direto no cartão padrão já\n * salvo do cliente (sem fricção nenhuma). Se ele ainda não tiver um cartão salvo,\n * retorna `checkout_url` para você abrir (ex: nova aba) e o cliente cadastrar o\n * cartão e pagar.\n *\n * ```ts\n * const result = await client.charges.charge(customerId, 5000); // R$ 50,00\n * if (!result.charged_off_session) {\n * window.open(result.checkout_url!, \"_blank\");\n * }\n * ```\n */\n charge(customerId: string, amountCents: number, options?: Omit<QuickChargeInput, \"customer_id\" | \"amount\">): Promise<QuickChargeResult> {\n return this.http.post<QuickChargeResult>(\"/charges/quick\", {\n customer_id: customerId,\n amount: amountCents,\n ...options,\n });\n }\n\n get(id: string): Promise<Charge> {\n return this.http.get<Charge>(`/charges/${id}`);\n }\n\n getStatus(id: string): Promise<{ status: Charge[\"status\"] }> {\n return this.http.get(`/charges/${id}/status`);\n }\n\n cancel(id: string): Promise<Charge> {\n return this.http.patch<Charge>(`/charges/${id}/cancel`);\n }\n\n refund(id: string): Promise<Charge> {\n return this.http.post<Charge>(`/charges/${id}/refund`);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { CheckoutStatusResult } from \"../types.js\";\n\nexport interface WaitUntilPaidOptions {\n /** Intervalo entre tentativas, em ms. Default: 2000. */\n intervalMs?: number;\n /** Tempo máximo de espera antes de desistir, em ms. Default: 5 minutos. */\n timeoutMs?: number;\n}\n\nexport class CheckoutResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Consulta o status atual de uma cobrança/checkout pelo `checkout_token` retornado\n * por `plans.checkout()` (ou qualquer outro fluxo de cobrança do SDK). Sincroniza com\n * o provedor de pagamento sob o capô quando ainda está PENDING. */\n getStatus(checkoutToken: string): Promise<CheckoutStatusResult> {\n return this.http.get<CheckoutStatusResult>(`/checkout/${checkoutToken}/status`);\n }\n\n /**\n * Faz polling de `getStatus` até o pagamento ser confirmado (ou falhar/expirar) — é\n * a forma recomendada de confirmar, depois de redirecionar o cliente para a\n * `checkout_url`, que a assinatura realmente foi paga antes de liberar acesso.\n *\n * Resolve quando o status deixa de ser PENDING/PROCESSING. Lança um erro se o tempo\n * limite (`timeoutMs`) for atingido antes disso.\n */\n async waitUntilPaid(checkoutToken: string, options: WaitUntilPaidOptions = {}): Promise<CheckoutStatusResult> {\n const intervalMs = options.intervalMs ?? 2000;\n const timeoutMs = options.timeoutMs ?? 5 * 60 * 1000;\n const deadline = Date.now() + timeoutMs;\n\n for (;;) {\n const result = await this.getStatus(checkoutToken);\n if (result.status !== \"PENDING\" && result.status !== \"PROCESSING\") {\n return result;\n }\n if (Date.now() >= deadline) {\n throw new Error(`Tempo limite excedido aguardando confirmação de pagamento (checkout_token=${checkoutToken}).`);\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { Coupon, CreateCouponInput } from \"../types.js\";\n\nexport class CouponsResource {\n constructor(private readonly http: HttpClient) {}\n\n list(): Promise<Coupon[]> {\n return this.http.get<Coupon[]>(\"/coupons\");\n }\n\n /** `idOrCode` aceita tanto o id interno (`coupon.id`) quanto o `code` legível que você\n * escolheu na criação (ex: `\"BEMVINDO20\"`) — normalmente é mais prático guardar/usar o\n * `code`, já que é você quem o define e é o que aparece para o cliente final. */\n get(idOrCode: string): Promise<Coupon> {\n return this.http.get<Coupon>(`/coupons/${idOrCode}`);\n }\n\n /**\n * Cria um cupom de desconto — o `code` é o que o cliente final informa no checkout\n * (`plans.checkout(planId, { coupon_code })`).\n *\n * ```ts\n * // 20% de desconto, aplicado só na primeira cobrança\n * await client.coupons.create({ code: \"BEMVINDO20\", type: \"PERCENTAGE\", value: 20, duration: \"ONCE\" });\n *\n * // R$10 de desconto, repetido pelas 3 primeiras renovações\n * await client.coupons.create({\n * code: \"R10X3\", type: \"FIXED\", value: 1000, duration: \"REPEATING\", duration_months: 3,\n * });\n * ```\n */\n create(input: CreateCouponInput): Promise<Coupon> {\n return this.http.post<Coupon>(\"/coupons\", input);\n }\n\n /** Só permite editar limites/validade/ativação — o desconto em si (type/value/duration)\n * de um cupom já criado é imutável; crie um novo código para mudar o valor do desconto.\n * `idOrCode` aceita id interno ou `code` (ver `get`). */\n update(idOrCode: string, input: Partial<Pick<CreateCouponInput, \"max_redemptions\" | \"expires_at\">> & { active?: boolean }): Promise<Coupon> {\n return this.http.patch<Coupon>(`/coupons/${idOrCode}`, input);\n }\n\n /** Desativa o cupom (soft-delete) — códigos já resgatados continuam no histórico.\n * `idOrCode` aceita id interno ou `code` (ver `get`). */\n remove(idOrCode: string): Promise<void> {\n return this.http.delete<void>(`/coupons/${idOrCode}`);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { Customer, CustomerInput } from \"../types.js\";\n\nexport class CustomersResource {\n constructor(private readonly http: HttpClient) {}\n\n list(): Promise<Customer[]> {\n return this.http.get<Customer[]>(\"/customers\");\n }\n\n create(input: CustomerInput): Promise<Customer> {\n return this.http.post<Customer>(\"/customers\", input);\n }\n\n get(id: string): Promise<Customer> {\n return this.http.get<Customer>(`/customers/${id}`);\n }\n\n update(id: string, input: Partial<CustomerInput>): Promise<Customer> {\n return this.http.patch<Customer>(`/customers/${id}`, input);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { BillingItem } from \"../types.js\";\n\nexport interface ItemInput {\n name: string;\n description?: string;\n amount: number;\n currency?: string;\n}\n\nexport class ItemsResource {\n constructor(private readonly http: HttpClient) {}\n\n list(): Promise<BillingItem[]> {\n return this.http.get<BillingItem[]>(\"/items\");\n }\n\n create(input: ItemInput): Promise<BillingItem> {\n return this.http.post<BillingItem>(\"/items\", input);\n }\n\n get(id: string): Promise<BillingItem> {\n return this.http.get<BillingItem>(`/items/${id}`);\n }\n\n update(id: string, input: Partial<ItemInput>): Promise<BillingItem> {\n return this.http.patch<BillingItem>(`/items/${id}`, input);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { CreateOrderInput, CreateOrderResult } from \"../types.js\";\n\nexport class OrdersResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Cria um pedido parcelado (parcelamento real via cobranças avulsas agendadas,\n * não assinatura). Retorna o `client_secret` da 1ª parcela para o front-end\n * confirmar via Stripe Elements — as parcelas seguintes são cobradas\n * automaticamente pelo backend no cartão salvo.\n */\n create(input: CreateOrderInput): Promise<CreateOrderResult> {\n return this.http.post<CreateOrderResult>(\"/orders\", input);\n }\n\n list(): Promise<unknown[]> {\n return this.http.get(\"/orders\");\n }\n\n get(id: string): Promise<unknown> {\n return this.http.get(`/orders/${id}`);\n }\n}\n","import type { HttpClient } from \"../http.js\";\r\nimport type {\r\n BillingPlanSummary,\r\n CheckoutForCustomerInput,\r\n CheckoutForCustomerResult,\r\n CreateBillingPlanInput,\r\n GetPublicPlanPageResult,\r\n ListPublicPlansResult,\r\n PlanCheckoutInput,\r\n PlanCheckoutResult,\r\n PlanSubscriptionStatusResult,\r\n} from \"../types.js\";\r\n\r\nexport class PlansResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n list(): Promise<BillingPlanSummary[]> {\r\n return this.http.get<BillingPlanSummary[]>(\"/billing-plans\");\r\n }\r\n\r\n get(id: string): Promise<BillingPlanSummary> {\r\n return this.http.get<BillingPlanSummary>(`/billing-plans/${id}`);\r\n }\r\n\r\n create(input: CreateBillingPlanInput): Promise<BillingPlanSummary> {\r\n return this.http.post<BillingPlanSummary>(\"/billing-plans\", input);\r\n }\r\n\r\n update(id: string, input: Partial<CreateBillingPlanInput> & { active?: boolean }): Promise<BillingPlanSummary> {\r\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${id}`, input);\r\n }\r\n\r\n /** Não há hard-delete de planos (assinaturas existentes ainda referenciam) — para\r\n * remover um plano do catálogo público, arquive-o. */\r\n archive(id: string): Promise<BillingPlanSummary> {\r\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${id}`, { active: false });\r\n }\r\n\r\n /** Vincula um plano avulso a uma página de planos existente (mesma org). */\r\n attachToPage(planId: string, pageId: string): Promise<BillingPlanSummary> {\r\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${planId}`, { plan_page_id: pageId });\r\n }\r\n\r\n /** Desvincula um plano da sua página, tornando-o avulso (sem página pública). */\r\n detachFromPage(planId: string): Promise<BillingPlanSummary> {\r\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${planId}`, { plan_page_id: null });\r\n }\r\n\r\n /**\r\n * Fluxo simplificado de assinatura para um `Customer` já cadastrado na sua org\r\n * (autenticado, sem formulário de nome/e-mail): cria a assinatura + cobrança inicial e\r\n * retorna a URL de checkout hospedada.\r\n *\r\n * ```ts\r\n * const { checkout_url } = await client.plans.checkoutPlan(planId, customerId, {\r\n * return_url: \"https://meuapp.com/conta?upgraded=1\",\r\n * });\r\n * // redirecione o cliente para checkout_url; ele paga e volta para sua URL de retorno\r\n *\r\n * // depois que o cliente volta:\r\n * const { active, item } = await client.plans.confirmPlanSubscription(planId, customerId);\r\n * if (active) {\r\n * // ativa o plano real no seu sistema\r\n * }\r\n * ```\r\n */\r\n checkoutPlan(planId: string, customerId: string, input?: CheckoutForCustomerInput): Promise<CheckoutForCustomerResult> {\r\n return this.http.post<CheckoutForCustomerResult>(`/billing-plans/${planId}/checkout-for-customer`, {\r\n customer_id: customerId,\r\n ...(input?.return_url ? { return_url: input.return_url } : {}),\r\n ...(input?.expires_in ? { expires_in: input.expires_in } : {}),\r\n ...(input?.coupon_code ? { coupon_code: input.coupon_code } : {}),\r\n });\r\n }\r\n\r\n /** Verifica se um `Customer` tem uma assinatura ativa deste plano (a mais recente),\r\n * contraparte de `checkoutPlan` no fluxo simplificado autenticado. */\r\n confirmPlanSubscription(planId: string, customerId: string): Promise<PlanSubscriptionStatusResult> {\r\n return this.http.get<PlanSubscriptionStatusResult>(`/billing-plans/${planId}/subscription-status?customer_id=${encodeURIComponent(customerId)}`);\r\n }\r\n\r\n // ─── Rotas públicas (sem auth — usadas para montar sua própria página de preços) ──\r\n\r\n /** Lista os planos ativos de uma org pelo slug público — página fixa legada, sem\r\n * suporte a múltiplas páginas. Prefira `getPublicPage` para orgs com várias páginas. */\r\n listPublic(orgSlug: string): Promise<ListPublicPlansResult> {\r\n return this.http.get<ListPublicPlansResult>(`/public/orgs/${orgSlug}/billing-plans`);\r\n }\r\n\r\n /** Busca uma página de planos pública específica pelo slug da org + slug da página. */\r\n getPublicPage(orgSlug: string, pageSlug: string): Promise<GetPublicPlanPageResult> {\r\n return this.http.get<GetPublicPlanPageResult>(`/public/orgs/${orgSlug}/plan-pages/${pageSlug}`);\r\n }\r\n\r\n /**\r\n * Inicia a assinatura de um plano para um cliente final: cria (ou reaproveita) o\r\n * `Customer` pelo e-mail, cria a `Subscription` e retorna uma URL de checkout hospedada\r\n * pela Geekapps para o cliente confirmar o pagamento.\r\n *\r\n * Fluxo típico:\r\n * ```ts\r\n * const { checkout_url, checkout_token } = await client.plans.checkout(planId, {\r\n * customer: { name, email },\r\n * coupon_code: \"PROMO20\", // opcional — página já abre com o desconto aplicado\r\n * });\r\n * // redirecione o cliente (ou abra checkout_url em uma WebView/nova aba)\r\n * window.location.href = checkout_url;\r\n *\r\n * // depois do retorno, confirme se realmente foi pago:\r\n * const { status } = await client.checkout.waitUntilPaid(checkout_token);\r\n * if (status === \"PAID\") { /* liberar acesso *\\/ }\r\n * ```\r\n *\r\n * Não requer autenticação — pode ser chamado a partir do backend do dev sem token de\r\n * service account, ou do próprio SDK server-side usando qualquer token válido.\r\n */\r\n checkout(planId: string, input: PlanCheckoutInput): Promise<PlanCheckoutResult> {\r\n return this.http.post<PlanCheckoutResult>(`/public/billing-plans/${planId}/checkout`, input);\r\n }\r\n}\r\n","import type { HttpClient } from \"../http.js\";\r\nimport type { CreateSubscriptionInput, CreateSubscriptionResult, Subscription, SubscriptionStatusResult } from \"../types.js\";\r\n\r\nexport class SubscriptionsResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /** Requer autenticação (service account) — lista todas as assinaturas da sua org. */\r\n list(): Promise<Subscription[]> {\r\n return this.http.get<Subscription[]>(\"/billing-subscriptions\");\r\n }\r\n\r\n /**\r\n * Fluxo legado de assinatura por `BillingItem` avulso (sem `BillingPlan`) — requer\r\n * autenticação (service account) e que `customer_id`/`item_id` já existam na sua org.\r\n * Prefira `plans.checkout`/`plans.checkoutPlan` para novos catálogos baseados em plano.\r\n *\r\n * ```ts\r\n * await client.subscriptions.create({\r\n * customer_id, item_id, interval: \"MONTHLY\", coupon_code: \"PROMO20\",\r\n * });\r\n * ```\r\n */\r\n create(input: CreateSubscriptionInput): Promise<CreateSubscriptionResult> {\r\n return this.http.post<CreateSubscriptionResult>(\"/billing-subscriptions\", input);\r\n }\r\n\r\n /** Requer autenticação (service account). */\r\n get(id: string): Promise<Subscription> {\r\n return this.http.get<Subscription>(`/billing-subscriptions/${id}`);\r\n }\r\n\r\n /** Requer autenticação (service account). */\r\n cancel(id: string): Promise<Subscription> {\r\n return this.http.patch<Subscription>(`/billing-subscriptions/${id}/cancel`);\r\n }\r\n\r\n /**\r\n * Inicia uma troca de plano/item de uma assinatura já existente (upgrade/downgrade de\r\n * tier) — requer autenticação (service account). NÃO executa a troca diretamente: retorna\r\n * um link de confirmação para o cliente final revisar custo e vigência e confirmar\r\n * expressamente antes de qualquer cobrança ou mudança de plano acontecer.\r\n *\r\n * `couponCode`: aplica um cupom na troca — se a assinatura for Stripe, o desconto passa a\r\n * valer também nas renovações futuras (recorrente, direto na Subscription); se for\r\n * PIX/boleto, o desconto vale só para a cobrança de proration desta troca.\r\n *\r\n * ```ts\r\n * const { confirmation_url } = await client.subscriptions.requestPlanSwap(subId, newPlanId, {\r\n * couponCode: \"PROMO20\",\r\n * });\r\n * // redirecione o cliente final para confirmation_url\r\n * ```\r\n */\r\n requestPlanSwap(\r\n id: string,\r\n newPlanId: string,\r\n options?: { expiresInSeconds?: number; couponCode?: string },\r\n ): Promise<{ confirmation_url: string }> {\r\n return this.http.patch(`/billing-subscriptions/${id}/swap`, {\r\n new_plan_id: newPlanId,\r\n ...(options?.expiresInSeconds ? { expires_in: options.expiresInSeconds } : {}),\r\n ...(options?.couponCode ? { coupon_code: options.couponCode } : {}),\r\n });\r\n }\r\n\r\n /**\r\n * Verifica se uma assinatura está ativa e qual item ela cobre, usando o\r\n * `management_token` retornado por `plans.checkout()` — rota pública, sem\r\n * autenticação, segura para chamar tanto do seu backend quanto (via fetch direto,\r\n * sem o SDK) do client-side do seu app.\r\n *\r\n * ```ts\r\n * const status = await client.subscriptions.checkByToken(managementToken);\r\n * if (status.subscription.active) {\r\n * console.log(\"cobrando\", status.item.name);\r\n * }\r\n * ```\r\n */\r\n checkByToken(managementToken: string): Promise<SubscriptionStatusResult> {\r\n return this.http.get<SubscriptionStatusResult>(`/public/plan-management/${managementToken}`);\r\n }\r\n}\r\n","import type { HttpClient } from \"../http.js\";\r\n\r\nexport type OutboundWebhookEventType =\r\n | \"SUBSCRIPTION_CREATED\"\r\n | \"SUBSCRIPTION_PLAN_SWAPPED\"\r\n | \"SUBSCRIPTION_CANCELLED\"\r\n | \"CHARGE_PAID\"\r\n | \"CHARGE_FAILED\";\r\n\r\nexport interface WebhookEndpointInput {\r\n url: string;\r\n eventTypes: OutboundWebhookEventType[];\r\n /** Opcional — quando omitido, o servidor gera um secret automaticamente. */\r\n secret?: string;\r\n}\r\n\r\nexport interface WebhookEndpointSummary {\r\n id: string;\r\n url: string;\r\n event_types: OutboundWebhookEventType[];\r\n active: boolean;\r\n /** Segredo completo apenas na primeira criação — em toda resposta subsequente vem mascarado. */\r\n secret: string;\r\n created_at: string;\r\n updated_at: string;\r\n}\r\n\r\nexport class WebhooksResource {\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /** Lista os webhooks outbound cadastrados na sua org (secret sempre mascarado). */\r\n list(): Promise<WebhookEndpointSummary[]> {\r\n return this.http.get<WebhookEndpointSummary[]>(\"/webhook-endpoints\");\r\n }\r\n\r\n /**\r\n * Registra um webhook outbound — idempotente por (org, url): chamar de novo com a\r\n * mesma URL apenas atualiza os `eventTypes`, sem criar duplicata. Guarde o `secret`\r\n * retornado (só vem completo na primeira criação) para validar a assinatura\r\n * `X-Geekapps-Signature` nas entregas recebidas. Passe `secret` para definir o seu\r\n * próprio signing secret; se omitido, um valor aleatório é gerado automaticamente.\r\n */\r\n register(input: WebhookEndpointInput): Promise<WebhookEndpointSummary> {\r\n return this.http.post<WebhookEndpointSummary>(\"/webhook-endpoints\", {\r\n url: input.url,\r\n event_types: input.eventTypes,\r\n ...(input.secret ? { secret: input.secret } : {}),\r\n });\r\n }\r\n\r\n /** Edita um webhook existente — URL, eventos assinados e/ou status ativo/inativo. */\r\n update(id: string, input: Partial<WebhookEndpointInput> & { active?: boolean }): Promise<WebhookEndpointSummary> {\r\n return this.http.patch<WebhookEndpointSummary>(`/webhook-endpoints/${id}`, {\r\n ...(input.url ? { url: input.url } : {}),\r\n ...(input.eventTypes ? { event_types: input.eventTypes } : {}),\r\n ...(input.active !== undefined ? { active: input.active } : {}),\r\n });\r\n }\r\n\r\n /** Gera um novo secret e substitui o atual — a versão antiga deixa de validar imediatamente. */\r\n rotateSecret(id: string): Promise<WebhookEndpointSummary> {\r\n return this.http.post<WebhookEndpointSummary>(`/webhook-endpoints/${id}/rotate-secret`);\r\n }\r\n\r\n remove(id: string): Promise<void> {\r\n return this.http.delete<void>(`/webhook-endpoints/${id}`);\r\n }\r\n}\r\n","import { HttpClient, type HttpClientOptions } from \"./http.js\";\r\nimport { ChargesResource } from \"./resources/charges.js\";\r\nimport { CheckoutResource } from \"./resources/checkout.js\";\r\nimport { CouponsResource } from \"./resources/coupons.js\";\r\nimport { CustomersResource } from \"./resources/customers.js\";\r\nimport { ItemsResource } from \"./resources/items.js\";\r\nimport { OrdersResource } from \"./resources/orders.js\";\r\nimport { PlansResource } from \"./resources/plans.js\";\r\nimport { SubscriptionsResource } from \"./resources/subscriptions.js\";\r\nimport { WebhooksResource } from \"./resources/webhooks.js\";\r\n\r\nexport interface BillingClientOptions\r\n extends Omit<HttpClientOptions, \"baseUrl\"> {\r\n baseUrl?: string;\r\n}\r\n\r\nexport class BillingClient {\r\n private readonly http: HttpClient;\r\n\r\n readonly charges: ChargesResource;\r\n readonly checkout: CheckoutResource;\r\n readonly coupons: CouponsResource;\r\n readonly customers: CustomersResource;\r\n readonly items: ItemsResource;\r\n readonly orders: OrdersResource;\r\n readonly plans: PlansResource;\r\n readonly subscriptions: SubscriptionsResource;\r\n readonly webhooks: WebhooksResource;\r\n\r\n constructor(options: HttpClientOptions) {\r\n this.http = new HttpClient(options);\r\n\r\n this.charges = new ChargesResource(this.http);\r\n this.checkout = new CheckoutResource(this.http);\r\n this.coupons = new CouponsResource(this.http);\r\n this.customers = new CustomersResource(this.http);\r\n this.items = new ItemsResource(this.http);\r\n this.orders = new OrdersResource(this.http);\r\n this.plans = new PlansResource(this.http);\r\n this.subscriptions = new SubscriptionsResource(this.http);\r\n this.webhooks = new WebhooksResource(this.http);\r\n }\r\n}\r\n","import type { FastifyInstance, FastifyPluginAsync } from \"fastify\";\nimport fp from \"fastify-plugin\";\nimport { BillingClient } from \"./client.js\";\nimport { ServiceAccountTokenProvider, type ServiceAccountOptions } from \"./service-account.js\";\n\nexport interface BillingPluginOptions {\n /** Geekapps Billing API base URL */\n baseUrl: string;\n /** Service account credentials — required */\n serviceAccount: ServiceAccountOptions;\n /** Ambiente de billing (dev/prod). Default: \"prod\". */\n mode?: string;\n}\n\ndeclare module \"fastify\" {\n interface FastifyInstance {\n billingClient: BillingClient;\n }\n}\n\nconst billingPlugin: FastifyPluginAsync<BillingPluginOptions> = async (\n fastify: FastifyInstance,\n options: BillingPluginOptions,\n) => {\n const tokenProvider = new ServiceAccountTokenProvider(options.serviceAccount);\n\n const client = new BillingClient({\n baseUrl: options.baseUrl,\n token: () => tokenProvider.getToken(),\n organizationId: () => tokenProvider.getOrganizationId() as Promise<string>,\n mode: options.mode,\n });\n\n fastify.decorate(\"billingClient\", client);\n};\n\nexport default fp(billingPlugin, {\n fastify: \">=4.0.0\",\n name: \"@geekapps/billing-fastify\",\n});\n","import type { TokenResolver } from \"./http.js\";\n\nexport interface ServiceAccountOptions {\n /** Geekapps Auth issuer base URL (e.g. https://accounts-api.geekapps.com.br) */\n issuerUrl: string;\n clientId: string;\n clientSecret: string;\n /** Seconds before expiry to proactively refresh. Defaults to 30. */\n refreshBeforeExpirySeconds?: number;\n}\n\ninterface CachedToken {\n value: string;\n expiresAt: number; // ms epoch\n organizationId: string | undefined;\n}\n\nfunction decodeJwtPayload(token: string): Record<string, unknown> {\n try {\n const [, payload] = token.split(\".\");\n if (!payload) return {};\n const json = Buffer.from(payload, \"base64url\").toString(\"utf-8\");\n return JSON.parse(json) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\n/**\n * Fetches a short-lived token from the Geekapps Auth service using\n * client_credentials grant and caches it until near expiry.\n *\n * The organizationId claim is extracted automatically from the JWT payload.\n */\nexport class ServiceAccountTokenProvider {\n private readonly issuerUrl: string;\n private readonly clientId: string;\n private readonly clientSecret: string;\n private readonly refreshBeforeMs: number;\n private cached: CachedToken | null = null;\n private inflight: Promise<CachedToken> | null = null;\n\n constructor(options: ServiceAccountOptions) {\n this.issuerUrl = options.issuerUrl.replace(/\\/$/, \"\");\n this.clientId = options.clientId;\n this.clientSecret = options.clientSecret;\n this.refreshBeforeMs = (options.refreshBeforeExpirySeconds ?? 30) * 1000;\n }\n\n private async ensureFresh(): Promise<CachedToken> {\n const now = Date.now();\n\n if (this.cached && this.cached.expiresAt - now > this.refreshBeforeMs) {\n return this.cached;\n }\n\n if (this.inflight) return this.inflight;\n\n this.inflight = this.fetchToken().finally(() => {\n this.inflight = null;\n });\n\n return this.inflight;\n }\n\n /** Returns a valid access token. */\n getToken(): Promise<string> {\n return this.ensureFresh().then((c) => c.value);\n }\n\n /** Returns the organizationId embedded in the service account JWT. */\n getOrganizationId(): Promise<string | undefined> {\n return this.ensureFresh().then((c) => c.organizationId);\n }\n\n private async fetchToken(): Promise<CachedToken> {\n const credentials = Buffer.from(`${this.clientId}:${this.clientSecret}`).toString(\"base64\");\n\n const res = await fetch(`${this.issuerUrl}/auth/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Basic ${credentials}`,\n },\n body: JSON.stringify({ grant_type: \"service_account\" }),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({})) as { error?: string };\n throw new Error(\n `ServiceAccount token fetch failed (${res.status}): ${err.error ?? \"unknown error\"}`,\n );\n }\n\n const data = await res.json() as { access_token: string; expires_in?: number };\n\n const claims = decodeJwtPayload(data.access_token);\n const organizationId =\n typeof claims.organizationId === \"string\" ? claims.organizationId :\n typeof claims.organization_id === \"string\" ? claims.organization_id :\n typeof claims.org_id === \"string\" ? claims.org_id :\n undefined;\n\n const expiresInMs = (data.expires_in ?? 420) * 1000;\n this.cached = {\n value: data.access_token,\n expiresAt: Date.now() + expiresInMs,\n organizationId,\n };\n\n return this.cached;\n }\n\n /** Returns this provider as a TokenResolver to pass directly to BillingClient. */\n asTokenResolver(): TokenResolver {\n return () => this.getToken();\n }\n}\n\n/** Convenience factory. Returns a TokenResolver ready for use in BillingClient. */\nexport function createServiceAccountToken(\n options: ServiceAccountOptions,\n): TokenResolver {\n return new ServiceAccountTokenProvider(options).asTokenResolver();\n}\n","export type ExpirationUnit = \"seconds\" | \"minutes\" | \"hours\" | \"days\";\n\nconst MULTIPLIERS: Record<ExpirationUnit, number> = {\n seconds: 1,\n minutes: 60,\n hours: 3600,\n days: 86400,\n};\n\n/**\n * Converte um valor + unidade para segundos, prontos para usar em `expires_in`.\n *\n * ```ts\n * await client.charges.create({ ..., expires_in: expiresIn(30, \"minutes\") });\n * ```\n */\nexport function expiresIn(value: number, unit: ExpirationUnit): number {\n return value * MULTIPLIERS[unit];\n}\n"],"mappings":"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","names":["fp"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekapps/billing-fastify",
3
- "version": "0.4.3",
3
+ "version": "0.6.0",
4
4
  "description": "Geekapps Billing SDK for Fastify",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",