@geekapps/billing-fastify 0.4.2 → 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 +112 -15
- package/dist/index.js +71 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -129,7 +129,8 @@ interface BillingItem {
|
|
|
129
129
|
updated_at: string;
|
|
130
130
|
}
|
|
131
131
|
type BillingRecurringInterval = "WEEKLY" | "MONTHLY" | "QUARTERLY" | "YEARLY";
|
|
132
|
-
type BillingRecurringStatus = "
|
|
132
|
+
type BillingRecurringStatus = "ON_HOLD" | "ACTIVE" | "CANCELLED";
|
|
133
|
+
type BillingSubscriptionCancelReason = "OVERDUE" | "USER_REQUESTED" | "CHECKOUT_EXPIRED";
|
|
133
134
|
type ProrationPolicy = "IMMEDIATE" | "AT_RENEWAL";
|
|
134
135
|
interface CreateBillingPlanInput {
|
|
135
136
|
/** Página de planos (BillingPlanPage) à qual este plano pertence — opcional: omita para
|
|
@@ -228,6 +229,21 @@ interface PlanCheckoutInput {
|
|
|
228
229
|
/** Cobrar no ciclo mensal (padrão) ou anual — anual só é aceito se o plano tiver
|
|
229
230
|
* `annual_amount` configurado, senão a API retorna 422. */
|
|
230
231
|
billing_period?: BillingPeriod;
|
|
232
|
+
/** Segundos até a cobrança inicial vencer — opcional, default 1h. Use o helper `expiresIn`. */
|
|
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;
|
|
231
247
|
}
|
|
232
248
|
interface PlanCheckoutResult {
|
|
233
249
|
checkout_token: string;
|
|
@@ -238,11 +254,17 @@ interface PlanCheckoutResult {
|
|
|
238
254
|
/** Token permanente — guarde-o (associado ao seu usuário) para depois checar se a
|
|
239
255
|
* assinatura está ativa e qual item ela cobre via `subscriptions.checkByToken`. */
|
|
240
256
|
management_token: string;
|
|
257
|
+
/** Presente apenas quando um `coupon_code` válido foi aplicado neste checkout. */
|
|
258
|
+
discount?: AppliedDiscount;
|
|
241
259
|
}
|
|
242
260
|
interface CheckoutForCustomerInput {
|
|
243
261
|
/** Para onde redirecionar o cliente após a confirmação do pagamento. Se omitido, usa o
|
|
244
262
|
* `return_url` do plano ou o `default_plan_return_url` da org. */
|
|
245
263
|
return_url?: string;
|
|
264
|
+
/** Segundos até a cobrança inicial vencer — opcional, default 1h. Use o helper `expiresIn`. */
|
|
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;
|
|
246
268
|
}
|
|
247
269
|
/** Resultado de `plans.checkoutPlan` (`POST /billing-plans/:id/checkout-for-customer`) —
|
|
248
270
|
* mesma forma de `PlanCheckoutResult`, mas para um `Customer` já existente na sua org
|
|
@@ -252,6 +274,38 @@ interface CheckoutForCustomerResult {
|
|
|
252
274
|
checkout_url: string;
|
|
253
275
|
subscription_id: string;
|
|
254
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;
|
|
255
309
|
}
|
|
256
310
|
/** Resultado de `plans.confirmPlanSubscription` (`GET /billing-plans/:id/subscription-status`) —
|
|
257
311
|
* a assinatura mais recente de um customer_id para um plano específico. */
|
|
@@ -259,7 +313,7 @@ interface PlanSubscriptionStatusResult {
|
|
|
259
313
|
subscription: {
|
|
260
314
|
id: string;
|
|
261
315
|
status: BillingRecurringStatus;
|
|
262
|
-
/** true quando status é ACTIVE
|
|
316
|
+
/** true quando status é ACTIVE ou ON_HOLD — só CANCELLED não é considerado em uso. */
|
|
263
317
|
active: boolean;
|
|
264
318
|
cancel_at_period_end: boolean;
|
|
265
319
|
current_period_end: string | null;
|
|
@@ -282,6 +336,8 @@ interface Subscription {
|
|
|
282
336
|
plan_id: string | null;
|
|
283
337
|
interval: BillingRecurringInterval;
|
|
284
338
|
status: BillingRecurringStatus;
|
|
339
|
+
/** Motivo do cancelamento — presente apenas quando status é CANCELLED. */
|
|
340
|
+
cancel_reason: BillingSubscriptionCancelReason | null;
|
|
285
341
|
cancel_at_period_end: boolean;
|
|
286
342
|
current_period_start: string | null;
|
|
287
343
|
current_period_end: string | null;
|
|
@@ -315,8 +371,8 @@ interface SubscriptionStatusResult {
|
|
|
315
371
|
subscription: {
|
|
316
372
|
id: string;
|
|
317
373
|
status: BillingRecurringStatus;
|
|
318
|
-
/** true quando status é ACTIVE
|
|
319
|
-
* apps quer pra decidir se libera acesso ou não. */
|
|
374
|
+
/** true quando status é ACTIVE ou ON_HOLD — o atalho que a maioria dos
|
|
375
|
+
* apps quer pra decidir se libera acesso ou não. Só CANCELLED não é considerado ativo. */
|
|
320
376
|
active: boolean;
|
|
321
377
|
cancel_at_period_end: boolean;
|
|
322
378
|
current_period_end: string | null;
|
|
@@ -406,6 +462,35 @@ declare class CheckoutResource {
|
|
|
406
462
|
waitUntilPaid(checkoutToken: string, options?: WaitUntilPaidOptions): Promise<CheckoutStatusResult>;
|
|
407
463
|
}
|
|
408
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
|
+
|
|
409
494
|
declare class CustomersResource {
|
|
410
495
|
private readonly http;
|
|
411
496
|
constructor(http: HttpClient);
|
|
@@ -496,6 +581,7 @@ declare class PlansResource {
|
|
|
496
581
|
* ```ts
|
|
497
582
|
* const { checkout_url, checkout_token } = await client.plans.checkout(planId, {
|
|
498
583
|
* customer: { name, email },
|
|
584
|
+
* coupon_code: "PROMO20", // opcional — página já abre com o desconto aplicado
|
|
499
585
|
* });
|
|
500
586
|
* // redirecione o cliente (ou abra checkout_url em uma WebView/nova aba)
|
|
501
587
|
* window.location.href = checkout_url;
|
|
@@ -521,19 +607,18 @@ declare class SubscriptionsResource {
|
|
|
521
607
|
/** Requer autenticação (service account). */
|
|
522
608
|
cancel(id: string): Promise<Subscription>;
|
|
523
609
|
/**
|
|
524
|
-
*
|
|
525
|
-
*
|
|
610
|
+
* Inicia uma troca de plano/item de uma assinatura já existente (upgrade/downgrade de
|
|
611
|
+
* tier) — requer autenticação (service account). NÃO executa a troca diretamente: retorna
|
|
612
|
+
* um link de confirmação para o cliente final revisar custo e vigência e confirmar
|
|
613
|
+
* expressamente antes de qualquer cobrança ou mudança de plano acontecer.
|
|
526
614
|
*
|
|
527
615
|
* ```ts
|
|
528
|
-
* const {
|
|
529
|
-
*
|
|
530
|
-
* // proration IMMEDIATE gerou uma cobrança adicional (PIX/boleto) — envie o cliente para pagar
|
|
531
|
-
* }
|
|
616
|
+
* const { confirmation_url } = await client.subscriptions.requestPlanSwap(subId, newPlanId);
|
|
617
|
+
* // redirecione o cliente final para confirmation_url
|
|
532
618
|
* ```
|
|
533
619
|
*/
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
checkout_url: string | null;
|
|
620
|
+
requestPlanSwap(id: string, newPlanId: string, expiresInSeconds?: number): Promise<{
|
|
621
|
+
confirmation_url: string;
|
|
537
622
|
}>;
|
|
538
623
|
/**
|
|
539
624
|
* Verifica se uma assinatura está ativa e qual item ela cobre, usando o
|
|
@@ -551,7 +636,7 @@ declare class SubscriptionsResource {
|
|
|
551
636
|
checkByToken(managementToken: string): Promise<SubscriptionStatusResult>;
|
|
552
637
|
}
|
|
553
638
|
|
|
554
|
-
type OutboundWebhookEventType = "SUBSCRIPTION_CREATED" | "SUBSCRIPTION_PLAN_SWAPPED" | "SUBSCRIPTION_CANCELLED" | "
|
|
639
|
+
type OutboundWebhookEventType = "SUBSCRIPTION_CREATED" | "SUBSCRIPTION_PLAN_SWAPPED" | "SUBSCRIPTION_CANCELLED" | "CHARGE_PAID" | "CHARGE_FAILED";
|
|
555
640
|
interface WebhookEndpointInput {
|
|
556
641
|
url: string;
|
|
557
642
|
eventTypes: OutboundWebhookEventType[];
|
|
@@ -581,6 +666,7 @@ declare class WebhooksResource {
|
|
|
581
666
|
* próprio signing secret; se omitido, um valor aleatório é gerado automaticamente.
|
|
582
667
|
*/
|
|
583
668
|
register(input: WebhookEndpointInput): Promise<WebhookEndpointSummary>;
|
|
669
|
+
/** Edita um webhook existente — URL, eventos assinados e/ou status ativo/inativo. */
|
|
584
670
|
update(id: string, input: Partial<WebhookEndpointInput> & {
|
|
585
671
|
active?: boolean;
|
|
586
672
|
}): Promise<WebhookEndpointSummary>;
|
|
@@ -596,6 +682,7 @@ declare class BillingClient {
|
|
|
596
682
|
private readonly http;
|
|
597
683
|
readonly charges: ChargesResource;
|
|
598
684
|
readonly checkout: CheckoutResource;
|
|
685
|
+
readonly coupons: CouponsResource;
|
|
599
686
|
readonly customers: CustomersResource;
|
|
600
687
|
readonly items: ItemsResource;
|
|
601
688
|
readonly orders: OrdersResource;
|
|
@@ -665,4 +752,14 @@ declare module "fastify" {
|
|
|
665
752
|
}
|
|
666
753
|
declare const _default: FastifyPluginAsync<BillingPluginOptions>;
|
|
667
754
|
|
|
668
|
-
|
|
755
|
+
type ExpirationUnit = "seconds" | "minutes" | "hours" | "days";
|
|
756
|
+
/**
|
|
757
|
+
* Converte um valor + unidade para segundos, prontos para usar em `expires_in`.
|
|
758
|
+
*
|
|
759
|
+
* ```ts
|
|
760
|
+
* await client.charges.create({ ..., expires_in: expiresIn(30, "minutes") });
|
|
761
|
+
* ```
|
|
762
|
+
*/
|
|
763
|
+
declare function expiresIn(value: number, unit: ExpirationUnit): number;
|
|
764
|
+
|
|
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) {
|
|
@@ -401,7 +440,9 @@ var PlansResource = class {
|
|
|
401
440
|
checkoutPlan(planId, customerId, input) {
|
|
402
441
|
return this.http.post(`/billing-plans/${planId}/checkout-for-customer`, {
|
|
403
442
|
customer_id: customerId,
|
|
404
|
-
...input?.return_url ? { return_url: input.return_url } : {}
|
|
443
|
+
...input?.return_url ? { return_url: input.return_url } : {},
|
|
444
|
+
...input?.expires_in ? { expires_in: input.expires_in } : {},
|
|
445
|
+
...input?.coupon_code ? { coupon_code: input.coupon_code } : {}
|
|
405
446
|
});
|
|
406
447
|
}
|
|
407
448
|
/** Verifica se um `Customer` tem uma assinatura ativa deste plano (a mais recente),
|
|
@@ -428,6 +469,7 @@ var PlansResource = class {
|
|
|
428
469
|
* ```ts
|
|
429
470
|
* const { checkout_url, checkout_token } = await client.plans.checkout(planId, {
|
|
430
471
|
* customer: { name, email },
|
|
472
|
+
* coupon_code: "PROMO20", // opcional — página já abre com o desconto aplicado
|
|
431
473
|
* });
|
|
432
474
|
* // redirecione o cliente (ou abra checkout_url em uma WebView/nova aba)
|
|
433
475
|
* window.location.href = checkout_url;
|
|
@@ -463,18 +505,21 @@ var SubscriptionsResource = class {
|
|
|
463
505
|
return this.http.patch(`/billing-subscriptions/${id}/cancel`);
|
|
464
506
|
}
|
|
465
507
|
/**
|
|
466
|
-
*
|
|
467
|
-
*
|
|
508
|
+
* Inicia uma troca de plano/item de uma assinatura já existente (upgrade/downgrade de
|
|
509
|
+
* tier) — requer autenticação (service account). NÃO executa a troca diretamente: retorna
|
|
510
|
+
* um link de confirmação para o cliente final revisar custo e vigência e confirmar
|
|
511
|
+
* expressamente antes de qualquer cobrança ou mudança de plano acontecer.
|
|
468
512
|
*
|
|
469
513
|
* ```ts
|
|
470
|
-
* const {
|
|
471
|
-
*
|
|
472
|
-
* // proration IMMEDIATE gerou uma cobrança adicional (PIX/boleto) — envie o cliente para pagar
|
|
473
|
-
* }
|
|
514
|
+
* const { confirmation_url } = await client.subscriptions.requestPlanSwap(subId, newPlanId);
|
|
515
|
+
* // redirecione o cliente final para confirmation_url
|
|
474
516
|
* ```
|
|
475
517
|
*/
|
|
476
|
-
|
|
477
|
-
return this.http.patch(`/billing-subscriptions/${id}/swap`, {
|
|
518
|
+
requestPlanSwap(id, newPlanId, expiresInSeconds) {
|
|
519
|
+
return this.http.patch(`/billing-subscriptions/${id}/swap`, {
|
|
520
|
+
new_plan_id: newPlanId,
|
|
521
|
+
...expiresInSeconds ? { expires_in: expiresInSeconds } : {}
|
|
522
|
+
});
|
|
478
523
|
}
|
|
479
524
|
/**
|
|
480
525
|
* Verifica se uma assinatura está ativa e qual item ela cobre, usando o
|
|
@@ -517,8 +562,10 @@ var WebhooksResource = class {
|
|
|
517
562
|
...input.secret ? { secret: input.secret } : {}
|
|
518
563
|
});
|
|
519
564
|
}
|
|
565
|
+
/** Edita um webhook existente — URL, eventos assinados e/ou status ativo/inativo. */
|
|
520
566
|
update(id, input) {
|
|
521
567
|
return this.http.patch(`/webhook-endpoints/${id}`, {
|
|
568
|
+
...input.url ? { url: input.url } : {},
|
|
522
569
|
...input.eventTypes ? { event_types: input.eventTypes } : {},
|
|
523
570
|
...input.active !== void 0 ? { active: input.active } : {}
|
|
524
571
|
});
|
|
@@ -538,6 +585,7 @@ var BillingClient = class {
|
|
|
538
585
|
this.http = new HttpClient(options);
|
|
539
586
|
this.charges = new ChargesResource(this.http);
|
|
540
587
|
this.checkout = new CheckoutResource(this.http);
|
|
588
|
+
this.coupons = new CouponsResource(this.http);
|
|
541
589
|
this.customers = new CustomersResource(this.http);
|
|
542
590
|
this.items = new ItemsResource(this.http);
|
|
543
591
|
this.orders = new OrdersResource(this.http);
|
|
@@ -640,11 +688,23 @@ var plugin_default = (0, import_fastify_plugin.default)(billingPlugin, {
|
|
|
640
688
|
fastify: ">=4.0.0",
|
|
641
689
|
name: "@geekapps/billing-fastify"
|
|
642
690
|
});
|
|
691
|
+
|
|
692
|
+
// src/expiration.ts
|
|
693
|
+
var MULTIPLIERS = {
|
|
694
|
+
seconds: 1,
|
|
695
|
+
minutes: 60,
|
|
696
|
+
hours: 3600,
|
|
697
|
+
days: 86400
|
|
698
|
+
};
|
|
699
|
+
function expiresIn(value, unit) {
|
|
700
|
+
return value * MULTIPLIERS[unit];
|
|
701
|
+
}
|
|
643
702
|
export {
|
|
644
703
|
BillingApiError,
|
|
645
704
|
BillingClient,
|
|
646
705
|
ChargesResource,
|
|
647
706
|
CheckoutResource,
|
|
707
|
+
CouponsResource,
|
|
648
708
|
CustomersResource,
|
|
649
709
|
HttpClient,
|
|
650
710
|
ItemsResource,
|
|
@@ -654,6 +714,7 @@ export {
|
|
|
654
714
|
SubscriptionsResource,
|
|
655
715
|
WebhooksResource,
|
|
656
716
|
plugin_default as billingPlugin,
|
|
657
|
-
createServiceAccountToken
|
|
717
|
+
createServiceAccountToken,
|
|
718
|
+
expiresIn
|
|
658
719
|
};
|
|
659
720
|
//# sourceMappingURL=index.js.map
|
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"],"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\";\nimport type {\n BillingPlanSummary,\n CheckoutForCustomerInput,\n CheckoutForCustomerResult,\n CreateBillingPlanInput,\n GetPublicPlanPageResult,\n ListPublicPlansResult,\n PlanCheckoutInput,\n PlanCheckoutResult,\n PlanSubscriptionStatusResult,\n} from \"../types.js\";\n\nexport class PlansResource {\n constructor(private readonly http: HttpClient) {}\n\n list(): Promise<BillingPlanSummary[]> {\n return this.http.get<BillingPlanSummary[]>(\"/billing-plans\");\n }\n\n get(id: string): Promise<BillingPlanSummary> {\n return this.http.get<BillingPlanSummary>(`/billing-plans/${id}`);\n }\n\n create(input: CreateBillingPlanInput): Promise<BillingPlanSummary> {\n return this.http.post<BillingPlanSummary>(\"/billing-plans\", input);\n }\n\n update(id: string, input: Partial<CreateBillingPlanInput> & { active?: boolean }): Promise<BillingPlanSummary> {\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${id}`, input);\n }\n\n /** Não há hard-delete de planos (assinaturas existentes ainda referenciam) — para\n * remover um plano do catálogo público, arquive-o. */\n archive(id: string): Promise<BillingPlanSummary> {\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${id}`, { active: false });\n }\n\n /** Vincula um plano avulso a uma página de planos existente (mesma org). */\n attachToPage(planId: string, pageId: string): Promise<BillingPlanSummary> {\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${planId}`, { plan_page_id: pageId });\n }\n\n /** Desvincula um plano da sua página, tornando-o avulso (sem página pública). */\n detachFromPage(planId: string): Promise<BillingPlanSummary> {\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${planId}`, { plan_page_id: null });\n }\n\n /**\n * Fluxo simplificado de assinatura para um `Customer` já cadastrado na sua org\n * (autenticado, sem formulário de nome/e-mail): cria a assinatura + cobrança inicial e\n * retorna a URL de checkout hospedada.\n *\n * ```ts\n * const { checkout_url } = await client.plans.checkoutPlan(planId, customerId, {\n * return_url: \"https://meuapp.com/conta?upgraded=1\",\n * });\n * // redirecione o cliente para checkout_url; ele paga e volta para sua URL de retorno\n *\n * // depois que o cliente volta:\n * const { active, item } = await client.plans.confirmPlanSubscription(planId, customerId);\n * if (active) {\n * // ativa o plano real no seu sistema\n * }\n * ```\n */\n checkoutPlan(planId: string, customerId: string, input?: CheckoutForCustomerInput): Promise<CheckoutForCustomerResult> {\n return this.http.post<CheckoutForCustomerResult>(`/billing-plans/${planId}/checkout-for-customer`, {\n customer_id: customerId,\n ...(input?.return_url ? { return_url: input.return_url } : {}),\n });\n }\n\n /** Verifica se um `Customer` tem uma assinatura ativa deste plano (a mais recente),\n * contraparte de `checkoutPlan` no fluxo simplificado autenticado. */\n confirmPlanSubscription(planId: string, customerId: string): Promise<PlanSubscriptionStatusResult> {\n return this.http.get<PlanSubscriptionStatusResult>(`/billing-plans/${planId}/subscription-status?customer_id=${encodeURIComponent(customerId)}`);\n }\n\n // ─── Rotas públicas (sem auth — usadas para montar sua própria página de preços) ──\n\n /** Lista os planos ativos de uma org pelo slug público — página fixa legada, sem\n * suporte a múltiplas páginas. Prefira `getPublicPage` para orgs com várias páginas. */\n listPublic(orgSlug: string): Promise<ListPublicPlansResult> {\n return this.http.get<ListPublicPlansResult>(`/public/orgs/${orgSlug}/billing-plans`);\n }\n\n /** Busca uma página de planos pública específica pelo slug da org + slug da página. */\n getPublicPage(orgSlug: string, pageSlug: string): Promise<GetPublicPlanPageResult> {\n return this.http.get<GetPublicPlanPageResult>(`/public/orgs/${orgSlug}/plan-pages/${pageSlug}`);\n }\n\n /**\n * Inicia a assinatura de um plano para um cliente final: cria (ou reaproveita) o\n * `Customer` pelo e-mail, cria a `Subscription` e retorna uma URL de checkout hospedada\n * pela Geekapps para o cliente confirmar o pagamento.\n *\n * Fluxo típico:\n * ```ts\n * const { checkout_url, checkout_token } = await client.plans.checkout(planId, {\n * customer: { name, email },\n * });\n * // redirecione o cliente (ou abra checkout_url em uma WebView/nova aba)\n * window.location.href = checkout_url;\n *\n * // depois do retorno, confirme se realmente foi pago:\n * const { status } = await client.checkout.waitUntilPaid(checkout_token);\n * if (status === \"PAID\") { /* liberar acesso *\\/ }\n * ```\n *\n * Não requer autenticação — pode ser chamado a partir do backend do dev sem token de\n * service account, ou do próprio SDK server-side usando qualquer token válido.\n */\n checkout(planId: string, input: PlanCheckoutInput): Promise<PlanCheckoutResult> {\n return this.http.post<PlanCheckoutResult>(`/public/billing-plans/${planId}/checkout`, input);\n }\n}\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 * Troca o plano/item de uma assinatura já existente (upgrade/downgrade de tier),\r\n * aplicando a política de proration configurada — requer autenticação (service account).\r\n *\r\n * ```ts\r\n * const { charge_due, checkout_url } = await client.subscriptions.swapPlan(subId, newPlanId);\r\n * if (checkout_url) {\r\n * // proration IMMEDIATE gerou uma cobrança adicional (PIX/boleto) — envie o cliente para pagar\r\n * }\r\n * ```\r\n */\r\n swapPlan(id: string, newPlanId: string): Promise<{ charge_due: boolean; checkout_url: string | null }> {\r\n return this.http.patch(`/billing-subscriptions/${id}/swap`, { new_plan_id: newPlanId });\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 | \"SUBSCRIPTION_PAST_DUE\"\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 update(id: string, input: Partial<WebhookEndpointInput> & { active?: boolean }): Promise<WebhookEndpointSummary> {\r\n return this.http.patch<WebhookEndpointSummary>(`/webhook-endpoints/${id}`, {\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"],"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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekapps/billing-fastify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Geekapps Billing SDK for Fastify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -32,4 +32,4 @@
|
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"fastify": ">=4.0.0"
|
|
34
34
|
}
|
|
35
|
-
}
|
|
35
|
+
}
|