@geekapps/billing-fastify 0.4.3 → 0.5.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 +81 -1
- package/dist/index.js +44 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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. */
|
|
@@ -413,6 +462,35 @@ declare class CheckoutResource {
|
|
|
413
462
|
waitUntilPaid(checkoutToken: string, options?: WaitUntilPaidOptions): Promise<CheckoutStatusResult>;
|
|
414
463
|
}
|
|
415
464
|
|
|
465
|
+
declare class CouponsResource {
|
|
466
|
+
private readonly http;
|
|
467
|
+
constructor(http: HttpClient);
|
|
468
|
+
list(): Promise<Coupon[]>;
|
|
469
|
+
get(id: string): Promise<Coupon>;
|
|
470
|
+
/**
|
|
471
|
+
* Cria um cupom de desconto — o `code` é o que o cliente final informa no checkout
|
|
472
|
+
* (`plans.checkout(planId, { coupon_code })`).
|
|
473
|
+
*
|
|
474
|
+
* ```ts
|
|
475
|
+
* // 20% de desconto, aplicado só na primeira cobrança
|
|
476
|
+
* await client.coupons.create({ code: "BEMVINDO20", type: "PERCENTAGE", value: 20, duration: "ONCE" });
|
|
477
|
+
*
|
|
478
|
+
* // R$10 de desconto, repetido pelas 3 primeiras renovações
|
|
479
|
+
* await client.coupons.create({
|
|
480
|
+
* code: "R10X3", type: "FIXED", value: 1000, duration: "REPEATING", duration_months: 3,
|
|
481
|
+
* });
|
|
482
|
+
* ```
|
|
483
|
+
*/
|
|
484
|
+
create(input: CreateCouponInput): Promise<Coupon>;
|
|
485
|
+
/** Só permite editar limites/validade/ativação — o desconto em si (type/value/duration)
|
|
486
|
+
* de um cupom já criado é imutável; crie um novo código para mudar o valor do desconto. */
|
|
487
|
+
update(id: string, input: Partial<Pick<CreateCouponInput, "max_redemptions" | "expires_at">> & {
|
|
488
|
+
active?: boolean;
|
|
489
|
+
}): Promise<Coupon>;
|
|
490
|
+
/** Desativa o cupom (soft-delete) — códigos já resgatados continuam no histórico. */
|
|
491
|
+
remove(id: string): Promise<void>;
|
|
492
|
+
}
|
|
493
|
+
|
|
416
494
|
declare class CustomersResource {
|
|
417
495
|
private readonly http;
|
|
418
496
|
constructor(http: HttpClient);
|
|
@@ -503,6 +581,7 @@ declare class PlansResource {
|
|
|
503
581
|
* ```ts
|
|
504
582
|
* const { checkout_url, checkout_token } = await client.plans.checkout(planId, {
|
|
505
583
|
* customer: { name, email },
|
|
584
|
+
* coupon_code: "PROMO20", // opcional — página já abre com o desconto aplicado
|
|
506
585
|
* });
|
|
507
586
|
* // redirecione o cliente (ou abra checkout_url em uma WebView/nova aba)
|
|
508
587
|
* window.location.href = checkout_url;
|
|
@@ -603,6 +682,7 @@ declare class BillingClient {
|
|
|
603
682
|
private readonly http;
|
|
604
683
|
readonly charges: ChargesResource;
|
|
605
684
|
readonly checkout: CheckoutResource;
|
|
685
|
+
readonly coupons: CouponsResource;
|
|
606
686
|
readonly customers: CustomersResource;
|
|
607
687
|
readonly items: ItemsResource;
|
|
608
688
|
readonly orders: OrdersResource;
|
|
@@ -682,4 +762,4 @@ type ExpirationUnit = "seconds" | "minutes" | "hours" | "days";
|
|
|
682
762
|
*/
|
|
683
763
|
declare function expiresIn(value: number, unit: ExpirationUnit): number;
|
|
684
764
|
|
|
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 };
|
|
765
|
+
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 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,45 @@ 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
|
+
get(id) {
|
|
302
|
+
return this.http.get(`/coupons/${id}`);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Cria um cupom de desconto — o `code` é o que o cliente final informa no checkout
|
|
306
|
+
* (`plans.checkout(planId, { coupon_code })`).
|
|
307
|
+
*
|
|
308
|
+
* ```ts
|
|
309
|
+
* // 20% de desconto, aplicado só na primeira cobrança
|
|
310
|
+
* await client.coupons.create({ code: "BEMVINDO20", type: "PERCENTAGE", value: 20, duration: "ONCE" });
|
|
311
|
+
*
|
|
312
|
+
* // R$10 de desconto, repetido pelas 3 primeiras renovações
|
|
313
|
+
* await client.coupons.create({
|
|
314
|
+
* code: "R10X3", type: "FIXED", value: 1000, duration: "REPEATING", duration_months: 3,
|
|
315
|
+
* });
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
create(input) {
|
|
319
|
+
return this.http.post("/coupons", input);
|
|
320
|
+
}
|
|
321
|
+
/** Só permite editar limites/validade/ativação — o desconto em si (type/value/duration)
|
|
322
|
+
* de um cupom já criado é imutável; crie um novo código para mudar o valor do desconto. */
|
|
323
|
+
update(id, input) {
|
|
324
|
+
return this.http.patch(`/coupons/${id}`, input);
|
|
325
|
+
}
|
|
326
|
+
/** Desativa o cupom (soft-delete) — códigos já resgatados continuam no histórico. */
|
|
327
|
+
remove(id) {
|
|
328
|
+
return this.http.delete(`/coupons/${id}`);
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
|
|
293
332
|
// src/resources/customers.ts
|
|
294
333
|
var CustomersResource = class {
|
|
295
334
|
constructor(http) {
|
|
@@ -402,7 +441,8 @@ var PlansResource = class {
|
|
|
402
441
|
return this.http.post(`/billing-plans/${planId}/checkout-for-customer`, {
|
|
403
442
|
customer_id: customerId,
|
|
404
443
|
...input?.return_url ? { return_url: input.return_url } : {},
|
|
405
|
-
...input?.expires_in ? { expires_in: input.expires_in } : {}
|
|
444
|
+
...input?.expires_in ? { expires_in: input.expires_in } : {},
|
|
445
|
+
...input?.coupon_code ? { coupon_code: input.coupon_code } : {}
|
|
406
446
|
});
|
|
407
447
|
}
|
|
408
448
|
/** Verifica se um `Customer` tem uma assinatura ativa deste plano (a mais recente),
|
|
@@ -429,6 +469,7 @@ var PlansResource = class {
|
|
|
429
469
|
* ```ts
|
|
430
470
|
* const { checkout_url, checkout_token } = await client.plans.checkout(planId, {
|
|
431
471
|
* customer: { name, email },
|
|
472
|
+
* coupon_code: "PROMO20", // opcional — página já abre com o desconto aplicado
|
|
432
473
|
* });
|
|
433
474
|
* // redirecione o cliente (ou abra checkout_url em uma WebView/nova aba)
|
|
434
475
|
* window.location.href = checkout_url;
|
|
@@ -544,6 +585,7 @@ var BillingClient = class {
|
|
|
544
585
|
this.http = new HttpClient(options);
|
|
545
586
|
this.charges = new ChargesResource(this.http);
|
|
546
587
|
this.checkout = new CheckoutResource(this.http);
|
|
588
|
+
this.coupons = new CouponsResource(this.http);
|
|
547
589
|
this.customers = new CustomersResource(this.http);
|
|
548
590
|
this.items = new ItemsResource(this.http);
|
|
549
591
|
this.orders = new OrdersResource(this.http);
|
|
@@ -662,6 +704,7 @@ export {
|
|
|
662
704
|
BillingClient,
|
|
663
705
|
ChargesResource,
|
|
664
706
|
CheckoutResource,
|
|
707
|
+
CouponsResource,
|
|
665
708
|
CustomersResource,
|
|
666
709
|
HttpClient,
|
|
667
710
|
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":"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","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 get(id: string): Promise<Coupon> {\n return this.http.get<Coupon>(`/coupons/${id}`);\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 update(id: string, input: Partial<Pick<CreateCouponInput, \"max_redemptions\" | \"expires_at\">> & { active?: boolean }): Promise<Coupon> {\n return this.http.patch<Coupon>(`/coupons/${id}`, input);\n }\n\n /** Desativa o cupom (soft-delete) — códigos já resgatados continuam no histórico. */\n remove(id: string): Promise<void> {\n return this.http.delete<void>(`/coupons/${id}`);\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 { 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 { 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"]}
|