@felipepasc/core-sdk 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -2
- package/dist/index.d.ts +684 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +373 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -4
package/README.md
CHANGED
|
@@ -1,3 +1,39 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @felipepasc/core-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Cliente, sem dependências, da API de integração do Core: métricas do dia, assinantes, lançamentos, orçamentos, cobranças, pagamentos, notas e avisos (webhooks) com `verifyWebhook`. Usa o `fetch` e o `crypto` do Node 20+.
|
|
4
|
+
|
|
5
|
+
## Instalação
|
|
6
|
+
|
|
7
|
+
O pacote é público no npm. Não precisa de token nem de configuração:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @felipepasc/core-sdk
|
|
11
|
+
# ou: pnpm add @felipepasc/core-sdk / yarn add @felipepasc/core-sdk
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Uso
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { createClient, CoreApiError } from "@felipepasc/core-sdk";
|
|
18
|
+
|
|
19
|
+
const core = createClient({ baseUrl: process.env.CORE_API_URL ?? "", apiKey: process.env.CORE_API_KEY ?? "" });
|
|
20
|
+
|
|
21
|
+
await core.metrics.report(new Date(), { subscribers_active: 120, mrr_cents: 5964000 });
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
await core.charges.markPaid("cob_981", { method: "pix" });
|
|
25
|
+
} catch (err) {
|
|
26
|
+
if (err instanceof CoreApiError) console.error(err.status, err.code, err.fields);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
A chave (`fk_...`) identifica o serviço; ele nunca vai no corpo. A referência completa das rotas está em `docs/api-integracao.md`, na raiz do repositório. O guia completo de integração (módulos, receitas, checklists) está em `docs/sdk.md`.
|
|
31
|
+
|
|
32
|
+
## Lançar uma versão nova
|
|
33
|
+
|
|
34
|
+
1. Suba o `version` em `sdk/package.json`.
|
|
35
|
+
2. Mande para a `main`.
|
|
36
|
+
|
|
37
|
+
O workflow `publish-sdk` compila, publica no npm se essa versão ainda não existir no registro e cria a tag `sdk-v<versão>`. Se a versão já existe, ele termina sem publicar.
|
|
38
|
+
|
|
39
|
+
Requisito: o segredo `NPM_TOKEN` (token do npm com permissão de publicar em `@felipepasc`) no repositório. O pacote é público: nada sensível pode entrar nele.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,684 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK do sistema financeiro: o que cada serviço usa pra reportar os próprios
|
|
3
|
+
* dados e gerar orçamentos e cobranças. Sem dependências: só `fetch` e `crypto` (Node 20+).
|
|
4
|
+
*
|
|
5
|
+
* const core = createClient({ baseUrl: process.env.CORE_API_URL, apiKey: process.env.CORE_API_KEY });
|
|
6
|
+
* await core.metrics.report("2026-10-12", { subscribers_active: 120 });
|
|
7
|
+
* const charge = await core.charges.upsert("inv_981", { customer, items, dueDate: "2026-10-20" });
|
|
8
|
+
* charge.pdfUrl; // link do PDF pra mandar ao cliente
|
|
9
|
+
* const pix = await core.charges.createPayment("inv_981", { method: "pix" });
|
|
10
|
+
* pix.pixCopyPaste; // o provedor é o que estiver configurado no CNPJ
|
|
11
|
+
*
|
|
12
|
+
* Dinheiro é sempre em centavos, inteiro. Tudo é idempotente pelo id que o
|
|
13
|
+
* serviço manda: repetir a chamada troca o que estava, não duplica.
|
|
14
|
+
*/
|
|
15
|
+
export type SubscriberStatus = "trial" | "active" | "past_due" | "paused" | "canceled";
|
|
16
|
+
export type TransactionType = "payment" | "refund" | "fee" | "cost";
|
|
17
|
+
export type QuoteStatus = "open" | "accepted" | "rejected" | "canceled";
|
|
18
|
+
export type ChargeStatus = "open" | "paid" | "canceled";
|
|
19
|
+
/** Data com hora: `Date` ou texto ISO 8601 com fuso. */
|
|
20
|
+
export type DateInput = Date | string;
|
|
21
|
+
export interface Subscriber {
|
|
22
|
+
name: string;
|
|
23
|
+
status: SubscriberStatus;
|
|
24
|
+
email?: string | null;
|
|
25
|
+
document?: string | null;
|
|
26
|
+
plan?: string | null;
|
|
27
|
+
/** Quanto paga por mês, em centavos. Plano anual entra dividido por 12. */
|
|
28
|
+
mrrCents?: number;
|
|
29
|
+
startedAt?: DateInput | null;
|
|
30
|
+
canceledAt?: DateInput | null;
|
|
31
|
+
metadata?: Record<string, string | number | boolean | null>;
|
|
32
|
+
}
|
|
33
|
+
export interface Transaction {
|
|
34
|
+
type: TransactionType;
|
|
35
|
+
/** Sempre positivo: o tipo dá o sinal. */
|
|
36
|
+
amountCents: number;
|
|
37
|
+
occurredAt: DateInput;
|
|
38
|
+
description?: string | null;
|
|
39
|
+
subscriberExternalId?: string | null;
|
|
40
|
+
method?: string | null;
|
|
41
|
+
/** Do que é o custo (ia, sms, armazenamento…): abre o custo por tipo no relatório. */
|
|
42
|
+
category?: string | null;
|
|
43
|
+
}
|
|
44
|
+
/** O custo de um assinante num mês, de um tipo. */
|
|
45
|
+
export interface SubscriberCost {
|
|
46
|
+
/** Id do assinante no seu sistema (o mesmo de `subscribers.upsert`). */
|
|
47
|
+
subscriberExternalId: string;
|
|
48
|
+
/** Do que é o custo: "ia", "sms", "armazenamento"… */
|
|
49
|
+
category: string;
|
|
50
|
+
amountCents: number;
|
|
51
|
+
}
|
|
52
|
+
export interface BillingCustomer {
|
|
53
|
+
name: string;
|
|
54
|
+
document?: string | null;
|
|
55
|
+
email?: string | null;
|
|
56
|
+
phone?: string | null;
|
|
57
|
+
address?: string | null;
|
|
58
|
+
/** Endereço em campos, que a nota fiscal pede. Sem ele a nota sai sem endereço do cliente. */
|
|
59
|
+
fiscalAddress?: {
|
|
60
|
+
/** Só números (8). */
|
|
61
|
+
postalCode: string;
|
|
62
|
+
/** Código IBGE do município (7 números). */
|
|
63
|
+
cityCode: string;
|
|
64
|
+
street: string;
|
|
65
|
+
number: string;
|
|
66
|
+
complement?: string | null;
|
|
67
|
+
district: string;
|
|
68
|
+
} | null;
|
|
69
|
+
}
|
|
70
|
+
export interface BillingItem {
|
|
71
|
+
description: string;
|
|
72
|
+
/** Padrão 1. Aceita fração (horas, mês proporcional). */
|
|
73
|
+
quantity?: number;
|
|
74
|
+
unitPriceCents: number;
|
|
75
|
+
}
|
|
76
|
+
export interface QuoteInput {
|
|
77
|
+
customer: BillingCustomer;
|
|
78
|
+
items: BillingItem[];
|
|
79
|
+
discountCents?: number;
|
|
80
|
+
/** Texto do rodapé do PDF: condições, observações. */
|
|
81
|
+
notes?: string | null;
|
|
82
|
+
/** Até quando vale, `AAAA-MM-DD`. */
|
|
83
|
+
validUntil?: string | null;
|
|
84
|
+
}
|
|
85
|
+
export interface ChargeInput {
|
|
86
|
+
customer: BillingCustomer;
|
|
87
|
+
items: BillingItem[];
|
|
88
|
+
discountCents?: number;
|
|
89
|
+
notes?: string | null;
|
|
90
|
+
/** Vencimento, `AAAA-MM-DD`. */
|
|
91
|
+
dueDate: string;
|
|
92
|
+
/** Onde o cliente paga (boleto, Pix, checkout). Vai no PDF. */
|
|
93
|
+
paymentUrl?: string | null;
|
|
94
|
+
/** Id do orçamento que virou esta cobrança. */
|
|
95
|
+
quoteExternalId?: string | null;
|
|
96
|
+
/** Id do assinante (o mesmo de `subscribers.upsert`). Paga, a receita entra na linha dele no relatório. */
|
|
97
|
+
subscriberExternalId?: string | null;
|
|
98
|
+
}
|
|
99
|
+
export interface Invoice {
|
|
100
|
+
number: string;
|
|
101
|
+
url: string | null;
|
|
102
|
+
issuedAt: string | null;
|
|
103
|
+
}
|
|
104
|
+
/** O documento como o sistema guardou: com número, totais calculados e o link do PDF. */
|
|
105
|
+
export interface BillingDocument<TStatus extends string> {
|
|
106
|
+
id: number;
|
|
107
|
+
kind: "quote" | "charge";
|
|
108
|
+
externalId: string;
|
|
109
|
+
number: number;
|
|
110
|
+
status: TStatus;
|
|
111
|
+
/** Em aberto e com a data vencida. */
|
|
112
|
+
overdue: boolean;
|
|
113
|
+
customer: BillingCustomer;
|
|
114
|
+
items: Required<BillingItem>[];
|
|
115
|
+
subtotalCents: number;
|
|
116
|
+
discountCents: number;
|
|
117
|
+
totalCents: number;
|
|
118
|
+
notes: string | null;
|
|
119
|
+
validUntil: string | null;
|
|
120
|
+
dueDate: string | null;
|
|
121
|
+
paymentUrl: string | null;
|
|
122
|
+
paymentMethod: string | null;
|
|
123
|
+
paidAt: string | null;
|
|
124
|
+
invoice: Invoice | null;
|
|
125
|
+
/** Link público do PDF, com a logo do serviço. */
|
|
126
|
+
pdfUrl: string;
|
|
127
|
+
createdAt: string;
|
|
128
|
+
updatedAt: string;
|
|
129
|
+
}
|
|
130
|
+
export type PaymentProvider = "asaas" | "inter" | "stripe" | "mercadopago" | "woovi" | "abacatepay";
|
|
131
|
+
export type PaymentMethod = "pix" | "boleto" | "card" | "checkout";
|
|
132
|
+
export type PaymentStatus = "pending" | "paid" | "expired" | "canceled" | "refunded" | "failed";
|
|
133
|
+
/** O pagamento de uma cobrança num provedor: o que mandar pro cliente pagar. */
|
|
134
|
+
export interface Payment {
|
|
135
|
+
id: number;
|
|
136
|
+
provider: PaymentProvider;
|
|
137
|
+
method: PaymentMethod;
|
|
138
|
+
status: PaymentStatus;
|
|
139
|
+
amountCents: number;
|
|
140
|
+
/** Página do provedor onde o cliente paga (fatura, checkout). */
|
|
141
|
+
paymentUrl: string | null;
|
|
142
|
+
/** Pix copia e cola. */
|
|
143
|
+
pixCopyPaste: string | null;
|
|
144
|
+
/** QR code do Pix: `data:image/png;base64,…` ou endereço https da imagem. */
|
|
145
|
+
pixQrCodeImage: string | null;
|
|
146
|
+
boletoUrl: string | null;
|
|
147
|
+
/** Linha digitável do boleto. */
|
|
148
|
+
boletoLine: string | null;
|
|
149
|
+
expiresAt: string | null;
|
|
150
|
+
paidAt: string | null;
|
|
151
|
+
createdAt: string;
|
|
152
|
+
}
|
|
153
|
+
/** `pix` é o Pix Automático (Woovi); `card` é cartão recorrente (Asaas ou Stripe). */
|
|
154
|
+
export type SubscriptionMethod = "pix" | "card";
|
|
155
|
+
export type SubscriptionInterval = "weekly" | "monthly" | "quarterly" | "semiannual" | "yearly";
|
|
156
|
+
/**
|
|
157
|
+
* `pending_authorization`: o cliente ainda não autorizou no banco dele.
|
|
158
|
+
* `active`: autorizada, os débitos acontecem sozinhos.
|
|
159
|
+
*/
|
|
160
|
+
export type SubscriptionStatus = "pending_authorization" | "active" | "rejected" | "canceled" | "expired";
|
|
161
|
+
export interface SubscriptionAddress {
|
|
162
|
+
/** CEP, 8 números. */
|
|
163
|
+
zipCode: string;
|
|
164
|
+
street: string;
|
|
165
|
+
number: string;
|
|
166
|
+
complement?: string | null;
|
|
167
|
+
neighborhood: string;
|
|
168
|
+
city: string;
|
|
169
|
+
/** UF, 2 letras. */
|
|
170
|
+
state: string;
|
|
171
|
+
}
|
|
172
|
+
export interface SubscriptionCustomer {
|
|
173
|
+
name: string;
|
|
174
|
+
/** CPF ou CNPJ: a recorrência é autorizada na conta desse documento. */
|
|
175
|
+
document: string;
|
|
176
|
+
email?: string | null;
|
|
177
|
+
phone?: string | null;
|
|
178
|
+
/** Obrigatório no Pix Automático (a Woovi exige). No cartão é opcional. */
|
|
179
|
+
address?: SubscriptionAddress | null;
|
|
180
|
+
}
|
|
181
|
+
export interface SubscriptionInput {
|
|
182
|
+
customer: SubscriptionCustomer;
|
|
183
|
+
/** O que o cliente vê no banco ao autorizar e em cada cobrança gerada. */
|
|
184
|
+
description: string;
|
|
185
|
+
amountCents: number;
|
|
186
|
+
/** Padrão: `pix`. */
|
|
187
|
+
method?: SubscriptionMethod;
|
|
188
|
+
/** Padrão: `monthly`. */
|
|
189
|
+
interval?: SubscriptionInterval;
|
|
190
|
+
/** Dia do primeiro débito, `AAAA-MM-DD`. */
|
|
191
|
+
startDate: string;
|
|
192
|
+
/** Id do assinante (o mesmo de `subscribers.upsert`). Cada débito pago entra na linha dele no relatório. */
|
|
193
|
+
subscriberExternalId?: string | null;
|
|
194
|
+
/** Qual provedor usar. Vazio: a conta padrão do CNPJ do serviço. */
|
|
195
|
+
provider?: PaymentProvider;
|
|
196
|
+
}
|
|
197
|
+
/** Pagamento recorrente: Pix Automático ou cartão. */
|
|
198
|
+
export interface Subscription {
|
|
199
|
+
id: number;
|
|
200
|
+
externalId: string;
|
|
201
|
+
provider: PaymentProvider;
|
|
202
|
+
status: SubscriptionStatus;
|
|
203
|
+
description: string;
|
|
204
|
+
amountCents: number;
|
|
205
|
+
method: SubscriptionMethod;
|
|
206
|
+
interval: SubscriptionInterval;
|
|
207
|
+
startDate: string;
|
|
208
|
+
customer: SubscriptionCustomer;
|
|
209
|
+
/** Página onde o cliente autoriza a recorrência (no cartão: onde ele cadastra o cartão). */
|
|
210
|
+
authorizationUrl: string | null;
|
|
211
|
+
/** Pix copia e cola da autorização. Só no Pix Automático. */
|
|
212
|
+
pixCopyPaste: string | null;
|
|
213
|
+
pixQrCodeImage: string | null;
|
|
214
|
+
/** Quantos débitos já foram pagos. */
|
|
215
|
+
paidCycles: number;
|
|
216
|
+
lastPaidAt: string | null;
|
|
217
|
+
canceledAt: string | null;
|
|
218
|
+
createdAt: string;
|
|
219
|
+
}
|
|
220
|
+
export type FiscalInvoiceStatus = "pending" | "issued" | "rejected" | "cancelled";
|
|
221
|
+
/** Recusa (ou aviso) do governo: o código dele e o texto. */
|
|
222
|
+
export interface FiscalInvoiceMessage {
|
|
223
|
+
code: string;
|
|
224
|
+
message: string;
|
|
225
|
+
detail: string | null;
|
|
226
|
+
}
|
|
227
|
+
/** A NFS-e de uma cobrança, emitida pelo Emissor Nacional. */
|
|
228
|
+
export interface FiscalInvoice {
|
|
229
|
+
id: number;
|
|
230
|
+
/** `pending`: o governo ainda não confirmou (consulte de novo); `rejected`: veja `messages`. */
|
|
231
|
+
status: FiscalInvoiceStatus;
|
|
232
|
+
environment: "restricted" | "production";
|
|
233
|
+
series: string;
|
|
234
|
+
dpsNumber: number;
|
|
235
|
+
dpsId: string;
|
|
236
|
+
accessKey: string | null;
|
|
237
|
+
nfseNumber: string | null;
|
|
238
|
+
amountCents: number;
|
|
239
|
+
description: string;
|
|
240
|
+
competenceDate: string;
|
|
241
|
+
issuedAt: string | null;
|
|
242
|
+
cancelledAt: string | null;
|
|
243
|
+
cancelReason: string | null;
|
|
244
|
+
messages: FiscalInvoiceMessage[];
|
|
245
|
+
/** Link público do PDF (DANFSe), só com a nota autorizada. */
|
|
246
|
+
pdfUrl: string | null;
|
|
247
|
+
createdAt: string;
|
|
248
|
+
updatedAt: string;
|
|
249
|
+
}
|
|
250
|
+
export interface IssueInvoiceOptions {
|
|
251
|
+
/** Descrição do serviço nesta nota; vazio, a padrão do serviço. */
|
|
252
|
+
description?: string | null;
|
|
253
|
+
/** Quando o serviço foi prestado, `AAAA-MM-DD`; vazio, hoje. */
|
|
254
|
+
competenceDate?: string | null;
|
|
255
|
+
}
|
|
256
|
+
export type InvestmentType = "fixed_income" | "treasury" | "fund" | "stock" | "reit" | "etf" | "crypto" | "pension" | "savings" | "other";
|
|
257
|
+
export type InvestmentLiquidity = "immediate" | "at_maturity" | "locked";
|
|
258
|
+
export type InvestmentStatus = "active" | "closed";
|
|
259
|
+
export type InvestmentMovementType = "contribution" | "redemption" | "income" | "fee";
|
|
260
|
+
/** Um investimento como o serviço o enxerga agora. */
|
|
261
|
+
export interface InvestmentPosition {
|
|
262
|
+
name: string;
|
|
263
|
+
type: InvestmentType;
|
|
264
|
+
/** Valor aplicado, em centavos. */
|
|
265
|
+
investedCents: number;
|
|
266
|
+
/** Valor de hoje, em centavos. */
|
|
267
|
+
currentCents: number;
|
|
268
|
+
/** CPF ou CNPJ (com ou sem pontuação) de quem é o investimento, já cadastrado no sistema. Sem ele, é da empresa dona do serviço. */
|
|
269
|
+
holderDocument?: string | null;
|
|
270
|
+
ticker?: string | null;
|
|
271
|
+
institution?: string | null;
|
|
272
|
+
/** Cotas, ações ou moedas: aceita decimal. */
|
|
273
|
+
quantity?: number | null;
|
|
274
|
+
/** Quando o valor foi medido (ISO 8601). Sem ele, vale o momento em que a api recebe. Serve pra mandar histórico. */
|
|
275
|
+
referenceAt?: DateInput;
|
|
276
|
+
/** Sem ele, na criação vale o padrão do tipo e na atualização fica o que estava. */
|
|
277
|
+
liquidity?: InvestmentLiquidity;
|
|
278
|
+
/** `AAAA-MM-DD`. */
|
|
279
|
+
maturityDate?: string | null;
|
|
280
|
+
/** Taxa ou indexador em texto livre: "110% do CDI". */
|
|
281
|
+
rate?: string | null;
|
|
282
|
+
/** Padrão `active`. `closed` encerra a posição (o histórico fica). */
|
|
283
|
+
status?: InvestmentStatus;
|
|
284
|
+
/** Só vale na criação: depois a observação é da pessoa, na tela. */
|
|
285
|
+
notes?: string | null;
|
|
286
|
+
}
|
|
287
|
+
export interface InvestmentHistoryPoint {
|
|
288
|
+
referenceAt: DateInput;
|
|
289
|
+
currentCents: number;
|
|
290
|
+
investedCents: number;
|
|
291
|
+
quantity?: number | null;
|
|
292
|
+
}
|
|
293
|
+
export interface InvestmentMovement {
|
|
294
|
+
/** Id da posição no seu sistema (o mesmo de `investments.positions.upsert`). */
|
|
295
|
+
positionExternalId: string;
|
|
296
|
+
type: InvestmentMovementType;
|
|
297
|
+
/** `AAAA-MM-DD`. */
|
|
298
|
+
date: string;
|
|
299
|
+
/** Sempre positivo: o tipo dá o sentido. */
|
|
300
|
+
amountCents: number;
|
|
301
|
+
quantity?: number | null;
|
|
302
|
+
description?: string | null;
|
|
303
|
+
}
|
|
304
|
+
export interface InvestmentPositionView {
|
|
305
|
+
id: number;
|
|
306
|
+
entityId: number;
|
|
307
|
+
entityName: string;
|
|
308
|
+
externalId: string | null;
|
|
309
|
+
name: string;
|
|
310
|
+
ticker: string | null;
|
|
311
|
+
type: InvestmentType;
|
|
312
|
+
institution: string | null;
|
|
313
|
+
quantity: number | null;
|
|
314
|
+
investedCents: number;
|
|
315
|
+
currentCents: number;
|
|
316
|
+
returnCents: number;
|
|
317
|
+
returnRatio: number | null;
|
|
318
|
+
valueAt: string;
|
|
319
|
+
liquidity: InvestmentLiquidity;
|
|
320
|
+
maturityDate: string | null;
|
|
321
|
+
rate: string | null;
|
|
322
|
+
status: InvestmentStatus;
|
|
323
|
+
closedAt: string | null;
|
|
324
|
+
}
|
|
325
|
+
export interface UpsertedInvestmentPosition {
|
|
326
|
+
id: number;
|
|
327
|
+
externalId: string;
|
|
328
|
+
created: boolean;
|
|
329
|
+
/** Se virou um ponto novo no histórico (idêntico a um que já existia, não vira). */
|
|
330
|
+
recorded: boolean;
|
|
331
|
+
}
|
|
332
|
+
export type Quote = BillingDocument<QuoteStatus>;
|
|
333
|
+
export type Charge = BillingDocument<ChargeStatus>;
|
|
334
|
+
/** Tipo de aviso: `<objeto>.<situação nova>`. */
|
|
335
|
+
export type WebhookEventType = `charge.${ChargeStatus}` | `quote.${QuoteStatus}` | `payment.${PaymentStatus}` | `subscription.${SubscriptionStatus}` | `invoice.${Exclude<FiscalInvoiceStatus, "pending">}` | "webhook.test";
|
|
336
|
+
/** O que um endereço quer receber: um tipo exato, `<objeto>.*` (ex.: `charge.*`) ou `*` (tudo). */
|
|
337
|
+
export type WebhookEventFilter = WebhookEventType | "charge.*" | "quote.*" | "payment.*" | "subscription.*" | "invoice.*" | "*";
|
|
338
|
+
interface WebhookEventBase<TType extends string, TData> {
|
|
339
|
+
/** Id do aviso: o mesmo em todas as tentativas. Use pra não processar duas vezes. */
|
|
340
|
+
id: string;
|
|
341
|
+
type: TType;
|
|
342
|
+
/** Quando aconteceu (ISO 8601). */
|
|
343
|
+
timestamp: string;
|
|
344
|
+
/** A situação antes desta mudança. */
|
|
345
|
+
previousStatus: string | null;
|
|
346
|
+
/** O objeto como está agora, no mesmo formato do GET dele. */
|
|
347
|
+
data: TData;
|
|
348
|
+
}
|
|
349
|
+
/** Todo aviso que o Core manda. Discrimine por `type`. */
|
|
350
|
+
export type CoreWebhookEvent = WebhookEventBase<`charge.${ChargeStatus}`, Charge> | WebhookEventBase<`quote.${QuoteStatus}`, Quote> | WebhookEventBase<`payment.${PaymentStatus}`, Payment & {
|
|
351
|
+
chargeExternalId: string;
|
|
352
|
+
}> | WebhookEventBase<`subscription.${SubscriptionStatus}`, Subscription> | WebhookEventBase<`invoice.${Exclude<FiscalInvoiceStatus, "pending">}`, FiscalInvoice & {
|
|
353
|
+
chargeExternalId: string | null;
|
|
354
|
+
}> | WebhookEventBase<"webhook.test", {
|
|
355
|
+
message: string;
|
|
356
|
+
endpointId: number;
|
|
357
|
+
}>;
|
|
358
|
+
export interface WebhookEndpointInput {
|
|
359
|
+
/** Endereço que recebe o POST. Em produção, https público. */
|
|
360
|
+
url: string;
|
|
361
|
+
/** Sem isto, recebe tudo. */
|
|
362
|
+
events?: WebhookEventFilter[];
|
|
363
|
+
description?: string | null;
|
|
364
|
+
}
|
|
365
|
+
export interface WebhookEndpoint {
|
|
366
|
+
id: number;
|
|
367
|
+
url: string;
|
|
368
|
+
events: WebhookEventFilter[];
|
|
369
|
+
description: string | null;
|
|
370
|
+
/** Desativado não recebe, mas guarda os avisos e manda tudo ao reativar. */
|
|
371
|
+
active: boolean;
|
|
372
|
+
/** Avisos esperando o endereço aceitar. */
|
|
373
|
+
pendingDeliveries: number;
|
|
374
|
+
oldestPendingAt: string | null;
|
|
375
|
+
lastDeliveredAt: string | null;
|
|
376
|
+
/** O último erro de um aviso ainda pendente (ex.: `HTTP 500: ...`). */
|
|
377
|
+
lastError: string | null;
|
|
378
|
+
createdAt: string;
|
|
379
|
+
updatedAt: string;
|
|
380
|
+
}
|
|
381
|
+
export interface WebhookDelivery {
|
|
382
|
+
id: number;
|
|
383
|
+
eventId: string;
|
|
384
|
+
eventType: WebhookEventType;
|
|
385
|
+
status: "pending" | "delivered";
|
|
386
|
+
attempts: number;
|
|
387
|
+
/** Quando sai a próxima tentativa (só pendente). */
|
|
388
|
+
nextAttemptAt: string | null;
|
|
389
|
+
lastAttemptAt: string | null;
|
|
390
|
+
lastStatusCode: number | null;
|
|
391
|
+
lastError: string | null;
|
|
392
|
+
deliveredAt: string | null;
|
|
393
|
+
createdAt: string;
|
|
394
|
+
}
|
|
395
|
+
export interface Page<T> {
|
|
396
|
+
items: T[];
|
|
397
|
+
total: number;
|
|
398
|
+
page: number;
|
|
399
|
+
limit: number;
|
|
400
|
+
nextPage: number | null;
|
|
401
|
+
}
|
|
402
|
+
export interface ClientOptions {
|
|
403
|
+
/** Endereço da api, sem o `/v1` (ex.: `https://felipepasc.com`). */
|
|
404
|
+
baseUrl: string;
|
|
405
|
+
/** A chave do serviço (`fk_…`), criada na aba Integração. */
|
|
406
|
+
apiKey: string;
|
|
407
|
+
/** Tempo máximo por chamada. Padrão: 15 s. */
|
|
408
|
+
timeoutMs?: number;
|
|
409
|
+
/** Quantas vezes repetir depois de falha de rede, 429 ou 5xx. Padrão: 2. */
|
|
410
|
+
retries?: number;
|
|
411
|
+
/** Pra testes: troca o `fetch` global. */
|
|
412
|
+
fetch?: typeof fetch;
|
|
413
|
+
}
|
|
414
|
+
/** Erro que a api devolveu (4xx/5xx) ou falha de rede (`status` 0). */
|
|
415
|
+
export declare class CoreApiError extends Error {
|
|
416
|
+
readonly status: number;
|
|
417
|
+
readonly code: string;
|
|
418
|
+
/** No 400 de validação: a mensagem de cada campo. */
|
|
419
|
+
readonly fields: Record<string, string>;
|
|
420
|
+
constructor(status: number, code: string, message: string, fields?: Record<string, string>);
|
|
421
|
+
}
|
|
422
|
+
export declare function createClient(options: ClientOptions): {
|
|
423
|
+
/** Confere a chave e diz qual serviço ela representa. */
|
|
424
|
+
ping: () => Promise<{
|
|
425
|
+
service: {
|
|
426
|
+
id: number;
|
|
427
|
+
name: string;
|
|
428
|
+
};
|
|
429
|
+
time: string;
|
|
430
|
+
}>;
|
|
431
|
+
metrics: {
|
|
432
|
+
/** Os números de um dia. Reenviar o dia troca os valores das métricas enviadas. */
|
|
433
|
+
report: (date: DateInput, metrics: Record<string, number>) => Promise<{
|
|
434
|
+
date: string;
|
|
435
|
+
saved: number;
|
|
436
|
+
}>;
|
|
437
|
+
};
|
|
438
|
+
subscribers: {
|
|
439
|
+
/** Um assinante como está agora. */
|
|
440
|
+
upsert: (externalId: string, subscriber: Subscriber) => Promise<{
|
|
441
|
+
externalId: string;
|
|
442
|
+
saved: number;
|
|
443
|
+
}>;
|
|
444
|
+
/** Qualquer quantidade: o SDK divide em lotes de 500. */
|
|
445
|
+
upsertMany: (subscribers: (Subscriber & {
|
|
446
|
+
externalId: string;
|
|
447
|
+
})[]) => Promise<{
|
|
448
|
+
saved: number;
|
|
449
|
+
}>;
|
|
450
|
+
};
|
|
451
|
+
transactions: {
|
|
452
|
+
/** Um lançamento de dinheiro: entrada, estorno, taxa ou custo. */
|
|
453
|
+
upsert: (externalId: string, transaction: Transaction) => Promise<{
|
|
454
|
+
externalId: string;
|
|
455
|
+
saved: number;
|
|
456
|
+
}>;
|
|
457
|
+
/** Qualquer quantidade: o SDK divide em lotes de 500. */
|
|
458
|
+
upsertMany: (transactions: (Transaction & {
|
|
459
|
+
externalId: string;
|
|
460
|
+
})[]) => Promise<{
|
|
461
|
+
saved: number;
|
|
462
|
+
}>;
|
|
463
|
+
};
|
|
464
|
+
costs: {
|
|
465
|
+
/**
|
|
466
|
+
* Quanto cada assinante custou no mês, por tipo de custo. É o que faz o
|
|
467
|
+
* relatório do serviço mostrar a margem de cada assinante e abater o
|
|
468
|
+
* custo do resultado. Reenviar o mês troca os valores (mande o
|
|
469
|
+
* acumulado do mês, não o do dia). Zero remove o custo daquele tipo.
|
|
470
|
+
*
|
|
471
|
+
* `month` é `AAAA-MM`. Não mande o mesmo custo de novo em
|
|
472
|
+
* `transactions` nem na métrica `usage_cost_cents`: contaria em dobro.
|
|
473
|
+
*/
|
|
474
|
+
reportMonth: (month: string, costs: SubscriberCost[]) => Promise<{
|
|
475
|
+
saved: number;
|
|
476
|
+
}>;
|
|
477
|
+
};
|
|
478
|
+
quotes: {
|
|
479
|
+
/** Cria ou troca o orçamento. Devolve o número, os totais e o `pdfUrl`. */
|
|
480
|
+
upsert: (externalId: string, quote: QuoteInput) => Promise<Quote>;
|
|
481
|
+
get: (externalId: string) => Promise<Quote>;
|
|
482
|
+
accept: (externalId: string) => Promise<Quote>;
|
|
483
|
+
reject: (externalId: string) => Promise<Quote>;
|
|
484
|
+
cancel: (externalId: string) => Promise<Quote>;
|
|
485
|
+
};
|
|
486
|
+
charges: {
|
|
487
|
+
/** Cria ou troca a cobrança. Devolve o número, os totais e o `pdfUrl`. */
|
|
488
|
+
upsert: (externalId: string, charge: ChargeInput) => Promise<Charge>;
|
|
489
|
+
get: (externalId: string) => Promise<Charge>;
|
|
490
|
+
/**
|
|
491
|
+
* Marca como paga. O valor entra sozinho como receita do serviço nos
|
|
492
|
+
* relatórios: não mande o mesmo pagamento de novo em `transactions`.
|
|
493
|
+
*/
|
|
494
|
+
markPaid: (externalId: string, payment?: {
|
|
495
|
+
paidAt?: DateInput;
|
|
496
|
+
method?: string;
|
|
497
|
+
}) => Promise<Charge>;
|
|
498
|
+
/** Volta pra em aberto (pagamento estornado ou marcado por engano). */
|
|
499
|
+
reopen: (externalId: string) => Promise<Charge>;
|
|
500
|
+
cancel: (externalId: string) => Promise<Charge>;
|
|
501
|
+
/**
|
|
502
|
+
* Gera o pagamento da cobrança no provedor configurado no CNPJ do serviço
|
|
503
|
+
* (o padrão, ou o `provider` pedido). Devolve o Pix, o boleto ou o link.
|
|
504
|
+
* Quando o cliente paga, o provedor avisa o sistema e a cobrança vira paga
|
|
505
|
+
* sozinha: não precisa chamar `markPaid`. Pedir de novo a mesma forma
|
|
506
|
+
* devolve o pagamento que já está aguardando.
|
|
507
|
+
*/
|
|
508
|
+
createPayment: (externalId: string, options?: {
|
|
509
|
+
method?: PaymentMethod;
|
|
510
|
+
provider?: PaymentProvider;
|
|
511
|
+
}) => Promise<Payment>;
|
|
512
|
+
/** Os pagamentos já gerados pra cobrança, do mais novo pro mais antigo. */
|
|
513
|
+
listPayments: (externalId: string) => Promise<Payment[]>;
|
|
514
|
+
/** Liga a nota fiscal emitida à cobrança: o número (e o link) passam a sair no PDF. */
|
|
515
|
+
attachInvoice: (externalId: string, invoice: {
|
|
516
|
+
number: string;
|
|
517
|
+
url?: string | null;
|
|
518
|
+
issuedAt?: DateInput | null;
|
|
519
|
+
}) => Promise<Charge>;
|
|
520
|
+
/**
|
|
521
|
+
* Emite a NFS-e da cobrança pelo Emissor Nacional, com o certificado da empresa. O valor é o
|
|
522
|
+
* total da cobrança e o tomador é o cliente dela. Repetir não gera outra nota: devolve a que
|
|
523
|
+
* existe. Fique de olho no `status`: `issued` (autorizada), `pending` (o governo não respondeu;
|
|
524
|
+
* chame `invoice` mais tarde) ou `rejected` (veja `messages`; corrija e chame de novo). Faltando
|
|
525
|
+
* configuração fiscal da empresa ou do serviço, vem 400 com `fields`.
|
|
526
|
+
*/
|
|
527
|
+
issueInvoice: (externalId: string, options?: IssueInvoiceOptions) => Promise<FiscalInvoice>;
|
|
528
|
+
/** A nota da cobrança. Pendente, consulta o governo antes de responder. */
|
|
529
|
+
invoice: (externalId: string) => Promise<FiscalInvoice>;
|
|
530
|
+
/** Cancela a nota autorizada. `reasonCode`: 1 erro na emissão, 2 serviço não prestado, 9 outros. `reason` tem de 15 a 255 letras. */
|
|
531
|
+
cancelInvoice: (externalId: string, cancellation: {
|
|
532
|
+
reasonCode: 1 | 2 | 9;
|
|
533
|
+
reason: string;
|
|
534
|
+
}) => Promise<FiscalInvoice>;
|
|
535
|
+
};
|
|
536
|
+
investments: {
|
|
537
|
+
positions: {
|
|
538
|
+
/**
|
|
539
|
+
* Uma posição como está agora. O investimento é de um titular (CPF ou CNPJ cadastrado), não do
|
|
540
|
+
* serviço: `holderDocument` diz de quem; sem ele, é da empresa dona do serviço. Documento que não
|
|
541
|
+
* existe no cadastro vira erro 400 com `fields` (o sistema não cria titular). Cada reporte vira um
|
|
542
|
+
* ponto do histórico; só o de referência mais recente é o valor atual.
|
|
543
|
+
*/
|
|
544
|
+
upsert: (externalId: string, position: InvestmentPosition) => Promise<UpsertedInvestmentPosition>;
|
|
545
|
+
/** Qualquer quantidade: o SDK divide em lotes de 200. Cada lote é tudo ou nada. */
|
|
546
|
+
upsertMany: (positions: (InvestmentPosition & {
|
|
547
|
+
externalId: string;
|
|
548
|
+
})[]) => Promise<{
|
|
549
|
+
saved: number;
|
|
550
|
+
positions: UpsertedInvestmentPosition[];
|
|
551
|
+
}>;
|
|
552
|
+
/** As posições que este serviço reportou (e só elas). */
|
|
553
|
+
list: (query?: {
|
|
554
|
+
status?: "active" | "closed" | "all";
|
|
555
|
+
page?: number;
|
|
556
|
+
limit?: number;
|
|
557
|
+
}) => Promise<{
|
|
558
|
+
items: InvestmentPositionView[];
|
|
559
|
+
total: number;
|
|
560
|
+
page: number;
|
|
561
|
+
limit: number;
|
|
562
|
+
}>;
|
|
563
|
+
/** Encerra a posição (o histórico fica). Reportar de novo como ativa reabre. */
|
|
564
|
+
close: (externalId: string) => Promise<InvestmentPositionView>;
|
|
565
|
+
/**
|
|
566
|
+
* Pontos de histórico de uma posição já reportada, em lote (até 500 por chamada), pra preencher o passado.
|
|
567
|
+
* Ponto antigo entra no histórico e não troca o valor atual; só o ponto de referência mais recente o troca.
|
|
568
|
+
* Repetir um ponto idêntico não duplica.
|
|
569
|
+
*/
|
|
570
|
+
reportHistory: (externalId: string, points: InvestmentHistoryPoint[]) => Promise<{
|
|
571
|
+
received: number;
|
|
572
|
+
recorded: number;
|
|
573
|
+
skipped: number;
|
|
574
|
+
currentUpdated: boolean;
|
|
575
|
+
}>;
|
|
576
|
+
};
|
|
577
|
+
movements: {
|
|
578
|
+
/** Aporte, resgate, rendimento ou taxa de uma posição que o serviço já reportou. */
|
|
579
|
+
upsert: (externalId: string, movement: InvestmentMovement) => Promise<{
|
|
580
|
+
saved: number;
|
|
581
|
+
}>;
|
|
582
|
+
/** Qualquer quantidade: o SDK divide em lotes de 500. */
|
|
583
|
+
upsertMany: (movements: (InvestmentMovement & {
|
|
584
|
+
externalId: string;
|
|
585
|
+
})[]) => Promise<{
|
|
586
|
+
saved: number;
|
|
587
|
+
}>;
|
|
588
|
+
};
|
|
589
|
+
};
|
|
590
|
+
subscriptions: {
|
|
591
|
+
/**
|
|
592
|
+
* Cria o pagamento recorrente no provedor do CNPJ: Pix Automático
|
|
593
|
+
* (`method: "pix"`, pela Woovi) ou cartão (`method: "card"`, pelo Asaas ou
|
|
594
|
+
* pela Stripe). O cliente autoriza uma vez (`pixCopyPaste` no banco dele, ou
|
|
595
|
+
* `authorizationUrl` pra cadastrar o cartão) e os débitos seguintes acontecem sozinhos: cada um
|
|
596
|
+
* pago vira uma cobrança paga do serviço, sem chamada nenhuma. Pedir de
|
|
597
|
+
* novo o mesmo id devolve a recorrência que já existe; pra mudar valor ou
|
|
598
|
+
* intervalo, cancele e crie outra.
|
|
599
|
+
*/
|
|
600
|
+
create: (externalId: string, subscription: SubscriptionInput) => Promise<Subscription>;
|
|
601
|
+
get: (externalId: string) => Promise<Subscription>;
|
|
602
|
+
/** Encerra a recorrência: não há mais débitos. */
|
|
603
|
+
cancel: (externalId: string) => Promise<Subscription>;
|
|
604
|
+
};
|
|
605
|
+
/**
|
|
606
|
+
* Avisos do Core pro seu serviço. Cadastre o endereço uma vez e guarde o `secret` (só aparece ao criar):
|
|
607
|
+
* cada mudança de situação (cobrança paga, nota emitida, recorrência ativada...) chega por POST, assinada.
|
|
608
|
+
* Responda 2xx pra confirmar. Qualquer outra resposta, erro ou demora (15 s) faz o Core tentar de novo,
|
|
609
|
+
* esperando 2 s, 4 s, 8 s, 16 s... até 1 hora entre tentativas, pra sempre, até você aceitar.
|
|
610
|
+
* Confira cada aviso com `verifyWebhook`.
|
|
611
|
+
*/
|
|
612
|
+
webhooks: {
|
|
613
|
+
list: () => Promise<WebhookEndpoint[]>;
|
|
614
|
+
get: (endpointId: number) => Promise<WebhookEndpoint>;
|
|
615
|
+
/** Devolve o endereço com o `secret`. Endereço repetido dá 409 `webhook_exists`. */
|
|
616
|
+
create: (endpoint: WebhookEndpointInput) => Promise<WebhookEndpoint & {
|
|
617
|
+
secret: string;
|
|
618
|
+
}>;
|
|
619
|
+
/** Trocar o endereço ou reativar manda na hora o que estava esperando. */
|
|
620
|
+
update: (endpointId: number, changes: Partial<WebhookEndpointInput> & {
|
|
621
|
+
active?: boolean;
|
|
622
|
+
}) => Promise<WebhookEndpoint>;
|
|
623
|
+
/** Apaga o endereço e descarta o que ainda não foi entregue nele. */
|
|
624
|
+
delete: (endpointId: number) => Promise<{
|
|
625
|
+
deleted: true;
|
|
626
|
+
}>;
|
|
627
|
+
/** Segredo novo, valendo na hora. */
|
|
628
|
+
rotateSecret: (endpointId: number) => Promise<{
|
|
629
|
+
secret: string;
|
|
630
|
+
}>;
|
|
631
|
+
/** Manda um `webhook.test` pra este endereço. */
|
|
632
|
+
test: (endpointId: number) => Promise<{
|
|
633
|
+
eventId: string;
|
|
634
|
+
}>;
|
|
635
|
+
deliveries: (endpointId: number, query?: {
|
|
636
|
+
status?: "pending" | "delivered";
|
|
637
|
+
page?: number;
|
|
638
|
+
limit?: number;
|
|
639
|
+
}) => Promise<Page<WebhookDelivery>>;
|
|
640
|
+
/** Manda de novo agora (também a já entregue). */
|
|
641
|
+
resend: (endpointId: number, deliveryId: number) => Promise<WebhookDelivery>;
|
|
642
|
+
};
|
|
643
|
+
/** Todos os avisos já gerados pro serviço, do mais novo ao mais antigo: pra conferir o que pode ter passado. */
|
|
644
|
+
events: {
|
|
645
|
+
list: (query?: {
|
|
646
|
+
type?: WebhookEventFilter;
|
|
647
|
+
since?: DateInput;
|
|
648
|
+
page?: number;
|
|
649
|
+
limit?: number;
|
|
650
|
+
}) => Promise<Page<CoreWebhookEvent>>;
|
|
651
|
+
get: (eventId: string) => Promise<CoreWebhookEvent>;
|
|
652
|
+
};
|
|
653
|
+
};
|
|
654
|
+
/** Aviso com assinatura que não confere, velho demais ou malformado: responda 400 e não processe. */
|
|
655
|
+
export declare class WebhookVerificationError extends Error {
|
|
656
|
+
constructor(message: string);
|
|
657
|
+
}
|
|
658
|
+
export type WebhookHeaders = Headers | Record<string, string | string[] | undefined>;
|
|
659
|
+
export interface VerifyWebhookOptions {
|
|
660
|
+
/** O corpo CRU, exatamente como chegou (texto ou bytes). JSON já interpretado e reescrito não confere. */
|
|
661
|
+
payload: string | Uint8Array;
|
|
662
|
+
headers: WebhookHeaders;
|
|
663
|
+
/** O `secret` do endereço (`whsec_...`). */
|
|
664
|
+
secret: string;
|
|
665
|
+
/** Diferença máxima entre o relógio do aviso e o seu, em segundos (padrão 300). */
|
|
666
|
+
toleranceSeconds?: number;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Confere a assinatura de um aviso do Core (padrão Standard Webhooks: cabeçalhos `webhook-id`,
|
|
670
|
+
* `webhook-timestamp` e `webhook-signature`) e devolve o aviso já interpretado. Falhou, lança
|
|
671
|
+
* `WebhookVerificationError`.
|
|
672
|
+
*
|
|
673
|
+
* app.post("/core/webhook", express.raw({ type: "application/json" }), async (req, res) => {
|
|
674
|
+
* const event = await verifyWebhook({ payload: req.body, headers: req.headers, secret: process.env.CORE_WEBHOOK_SECRET });
|
|
675
|
+
* if (event.type === "charge.paid") await releaseOrder(event.data.externalId);
|
|
676
|
+
* res.sendStatus(204);
|
|
677
|
+
* });
|
|
678
|
+
*
|
|
679
|
+
* O mesmo aviso pode chegar mais de uma vez (o Core repete até ter 2xx): use `event.id` pra não processar duas vezes.
|
|
680
|
+
*/
|
|
681
|
+
export declare function verifyWebhook(options: VerifyWebhookOptions): Promise<CoreWebhookEvent>;
|
|
682
|
+
export type CoreClient = ReturnType<typeof createClient>;
|
|
683
|
+
export {};
|
|
684
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK do sistema financeiro: o que cada serviço usa pra reportar os próprios
|
|
3
|
+
* dados e gerar orçamentos e cobranças. Sem dependências: só `fetch` e `crypto` (Node 20+).
|
|
4
|
+
*
|
|
5
|
+
* const core = createClient({ baseUrl: process.env.CORE_API_URL, apiKey: process.env.CORE_API_KEY });
|
|
6
|
+
* await core.metrics.report("2026-10-12", { subscribers_active: 120 });
|
|
7
|
+
* const charge = await core.charges.upsert("inv_981", { customer, items, dueDate: "2026-10-20" });
|
|
8
|
+
* charge.pdfUrl; // link do PDF pra mandar ao cliente
|
|
9
|
+
* const pix = await core.charges.createPayment("inv_981", { method: "pix" });
|
|
10
|
+
* pix.pixCopyPaste; // o provedor é o que estiver configurado no CNPJ
|
|
11
|
+
*
|
|
12
|
+
* Dinheiro é sempre em centavos, inteiro. Tudo é idempotente pelo id que o
|
|
13
|
+
* serviço manda: repetir a chamada troca o que estava, não duplica.
|
|
14
|
+
*/
|
|
15
|
+
/** Erro que a api devolveu (4xx/5xx) ou falha de rede (`status` 0). */
|
|
16
|
+
export class CoreApiError extends Error {
|
|
17
|
+
status;
|
|
18
|
+
code;
|
|
19
|
+
/** No 400 de validação: a mensagem de cada campo. */
|
|
20
|
+
fields;
|
|
21
|
+
constructor(status, code, message, fields = {}) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "CoreApiError";
|
|
24
|
+
this.status = status;
|
|
25
|
+
this.code = code;
|
|
26
|
+
this.fields = fields;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// ─── Cliente ────────────────────────────────────────────────────────
|
|
30
|
+
const BATCH_SIZE = 500;
|
|
31
|
+
function isoDay(date) {
|
|
32
|
+
return typeof date === "string" ? date.slice(0, 10) : date.toISOString().slice(0, 10);
|
|
33
|
+
}
|
|
34
|
+
function chunk(items, size) {
|
|
35
|
+
const parts = [];
|
|
36
|
+
for (let index = 0; index < items.length; index += size)
|
|
37
|
+
parts.push(items.slice(index, index + size));
|
|
38
|
+
return parts;
|
|
39
|
+
}
|
|
40
|
+
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
41
|
+
export function createClient(options) {
|
|
42
|
+
const baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
43
|
+
const timeoutMs = options.timeoutMs ?? 15_000;
|
|
44
|
+
const retries = options.retries ?? 2;
|
|
45
|
+
const doFetch = options.fetch ?? fetch;
|
|
46
|
+
if (!baseUrl)
|
|
47
|
+
throw new Error("createClient: informe o baseUrl da api");
|
|
48
|
+
if (!options.apiKey)
|
|
49
|
+
throw new Error("createClient: informe a apiKey do serviço");
|
|
50
|
+
async function request(method, path, body) {
|
|
51
|
+
let lastError = null;
|
|
52
|
+
for (let attempt = 0; attempt <= retries; attempt += 1) {
|
|
53
|
+
if (attempt > 0)
|
|
54
|
+
await wait(300 * 2 ** (attempt - 1));
|
|
55
|
+
let response;
|
|
56
|
+
try {
|
|
57
|
+
response = await doFetch(`${baseUrl}/v1${path}`, {
|
|
58
|
+
method,
|
|
59
|
+
headers: { Authorization: `Bearer ${options.apiKey}`, ...(body === undefined ? {} : { "Content-Type": "application/json" }) },
|
|
60
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
61
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
lastError = new CoreApiError(0, "network_error", err instanceof Error ? err.message : "falha de rede");
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (response.ok)
|
|
69
|
+
return (await response.json());
|
|
70
|
+
const payload = (await response.json().catch(() => null));
|
|
71
|
+
lastError = new CoreApiError(response.status, payload?.error?.code ?? "request_error", payload?.error?.message ?? `a api respondeu ${response.status}`, payload?.error?.fields);
|
|
72
|
+
// Erro de quem chamou (400, 401, 404, 409) não melhora repetindo.
|
|
73
|
+
const retryable = response.status === 429 || response.status >= 500;
|
|
74
|
+
if (!retryable)
|
|
75
|
+
throw lastError;
|
|
76
|
+
}
|
|
77
|
+
throw lastError ?? new CoreApiError(0, "network_error", "falha de rede");
|
|
78
|
+
}
|
|
79
|
+
const id = (externalId) => encodeURIComponent(externalId);
|
|
80
|
+
return {
|
|
81
|
+
/** Confere a chave e diz qual serviço ela representa. */
|
|
82
|
+
ping: () => request("GET", "/ping"),
|
|
83
|
+
metrics: {
|
|
84
|
+
/** Os números de um dia. Reenviar o dia troca os valores das métricas enviadas. */
|
|
85
|
+
report: (date, metrics) => request("PUT", `/metrics/${isoDay(date)}`, { metrics }),
|
|
86
|
+
},
|
|
87
|
+
subscribers: {
|
|
88
|
+
/** Um assinante como está agora. */
|
|
89
|
+
upsert: (externalId, subscriber) => request("PUT", `/subscribers/${id(externalId)}`, subscriber),
|
|
90
|
+
/** Qualquer quantidade: o SDK divide em lotes de 500. */
|
|
91
|
+
upsertMany: async (subscribers) => {
|
|
92
|
+
let saved = 0;
|
|
93
|
+
for (const part of chunk(subscribers, BATCH_SIZE)) {
|
|
94
|
+
const result = await request("POST", "/subscribers/batch", { subscribers: part });
|
|
95
|
+
saved += result.saved;
|
|
96
|
+
}
|
|
97
|
+
return { saved };
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
transactions: {
|
|
101
|
+
/** Um lançamento de dinheiro: entrada, estorno, taxa ou custo. */
|
|
102
|
+
upsert: (externalId, transaction) => request("PUT", `/transactions/${id(externalId)}`, transaction),
|
|
103
|
+
/** Qualquer quantidade: o SDK divide em lotes de 500. */
|
|
104
|
+
upsertMany: async (transactions) => {
|
|
105
|
+
let saved = 0;
|
|
106
|
+
for (const part of chunk(transactions, BATCH_SIZE)) {
|
|
107
|
+
const result = await request("POST", "/transactions/batch", { transactions: part });
|
|
108
|
+
saved += result.saved;
|
|
109
|
+
}
|
|
110
|
+
return { saved };
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
costs: {
|
|
114
|
+
/**
|
|
115
|
+
* Quanto cada assinante custou no mês, por tipo de custo. É o que faz o
|
|
116
|
+
* relatório do serviço mostrar a margem de cada assinante e abater o
|
|
117
|
+
* custo do resultado. Reenviar o mês troca os valores (mande o
|
|
118
|
+
* acumulado do mês, não o do dia). Zero remove o custo daquele tipo.
|
|
119
|
+
*
|
|
120
|
+
* `month` é `AAAA-MM`. Não mande o mesmo custo de novo em
|
|
121
|
+
* `transactions` nem na métrica `usage_cost_cents`: contaria em dobro.
|
|
122
|
+
*/
|
|
123
|
+
reportMonth: async (month, costs) => {
|
|
124
|
+
if (!/^\d{4}-(0[1-9]|1[0-2])$/.test(month))
|
|
125
|
+
throw new Error("costs.reportMonth: month no formato AAAA-MM");
|
|
126
|
+
// Meio-dia do dia 1 em Brasília: cai dentro do mês em qualquer fuso do servidor.
|
|
127
|
+
const occurredAt = `${month}-01T12:00:00-03:00`;
|
|
128
|
+
const slug = (text) => text.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 30);
|
|
129
|
+
const transactions = costs.map((cost) => ({ externalId: `cost:${month}:${cost.subscriberExternalId}:${slug(cost.category)}`.slice(0, 120), type: "cost", amountCents: cost.amountCents, occurredAt, subscriberExternalId: cost.subscriberExternalId, category: cost.category, description: `Custo de ${cost.category}` }));
|
|
130
|
+
let saved = 0;
|
|
131
|
+
for (const part of chunk(transactions, BATCH_SIZE)) {
|
|
132
|
+
const result = await request("POST", "/transactions/batch", { transactions: part });
|
|
133
|
+
saved += result.saved;
|
|
134
|
+
}
|
|
135
|
+
return { saved };
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
quotes: {
|
|
139
|
+
/** Cria ou troca o orçamento. Devolve o número, os totais e o `pdfUrl`. */
|
|
140
|
+
upsert: (externalId, quote) => request("PUT", `/quotes/${id(externalId)}`, quote),
|
|
141
|
+
get: (externalId) => request("GET", `/quotes/${id(externalId)}`),
|
|
142
|
+
accept: (externalId) => request("PUT", `/quotes/${id(externalId)}/status`, { status: "accepted" }),
|
|
143
|
+
reject: (externalId) => request("PUT", `/quotes/${id(externalId)}/status`, { status: "rejected" }),
|
|
144
|
+
cancel: (externalId) => request("PUT", `/quotes/${id(externalId)}/status`, { status: "canceled" }),
|
|
145
|
+
},
|
|
146
|
+
charges: {
|
|
147
|
+
/** Cria ou troca a cobrança. Devolve o número, os totais e o `pdfUrl`. */
|
|
148
|
+
upsert: (externalId, charge) => request("PUT", `/charges/${id(externalId)}`, charge),
|
|
149
|
+
get: (externalId) => request("GET", `/charges/${id(externalId)}`),
|
|
150
|
+
/**
|
|
151
|
+
* Marca como paga. O valor entra sozinho como receita do serviço nos
|
|
152
|
+
* relatórios: não mande o mesmo pagamento de novo em `transactions`.
|
|
153
|
+
*/
|
|
154
|
+
markPaid: (externalId, payment = {}) => request("PUT", `/charges/${id(externalId)}/status`, { status: "paid", ...payment }),
|
|
155
|
+
/** Volta pra em aberto (pagamento estornado ou marcado por engano). */
|
|
156
|
+
reopen: (externalId) => request("PUT", `/charges/${id(externalId)}/status`, { status: "open" }),
|
|
157
|
+
cancel: (externalId) => request("PUT", `/charges/${id(externalId)}/status`, { status: "canceled" }),
|
|
158
|
+
/**
|
|
159
|
+
* Gera o pagamento da cobrança no provedor configurado no CNPJ do serviço
|
|
160
|
+
* (o padrão, ou o `provider` pedido). Devolve o Pix, o boleto ou o link.
|
|
161
|
+
* Quando o cliente paga, o provedor avisa o sistema e a cobrança vira paga
|
|
162
|
+
* sozinha: não precisa chamar `markPaid`. Pedir de novo a mesma forma
|
|
163
|
+
* devolve o pagamento que já está aguardando.
|
|
164
|
+
*/
|
|
165
|
+
createPayment: (externalId, options = {}) => request("POST", `/charges/${id(externalId)}/payments`, options),
|
|
166
|
+
/** Os pagamentos já gerados pra cobrança, do mais novo pro mais antigo. */
|
|
167
|
+
listPayments: (externalId) => request("GET", `/charges/${id(externalId)}/payments`),
|
|
168
|
+
/** Liga a nota fiscal emitida à cobrança: o número (e o link) passam a sair no PDF. */
|
|
169
|
+
attachInvoice: (externalId, invoice) => request("PUT", `/charges/${id(externalId)}/invoice`, invoice),
|
|
170
|
+
/**
|
|
171
|
+
* Emite a NFS-e da cobrança pelo Emissor Nacional, com o certificado da empresa. O valor é o
|
|
172
|
+
* total da cobrança e o tomador é o cliente dela. Repetir não gera outra nota: devolve a que
|
|
173
|
+
* existe. Fique de olho no `status`: `issued` (autorizada), `pending` (o governo não respondeu;
|
|
174
|
+
* chame `invoice` mais tarde) ou `rejected` (veja `messages`; corrija e chame de novo). Faltando
|
|
175
|
+
* configuração fiscal da empresa ou do serviço, vem 400 com `fields`.
|
|
176
|
+
*/
|
|
177
|
+
issueInvoice: (externalId, options = {}) => request("POST", `/charges/${id(externalId)}/invoice`, options),
|
|
178
|
+
/** A nota da cobrança. Pendente, consulta o governo antes de responder. */
|
|
179
|
+
invoice: (externalId) => request("GET", `/charges/${id(externalId)}/invoice`),
|
|
180
|
+
/** Cancela a nota autorizada. `reasonCode`: 1 erro na emissão, 2 serviço não prestado, 9 outros. `reason` tem de 15 a 255 letras. */
|
|
181
|
+
cancelInvoice: (externalId, cancellation) => request("POST", `/charges/${id(externalId)}/invoice/cancel`, cancellation),
|
|
182
|
+
},
|
|
183
|
+
investments: {
|
|
184
|
+
positions: {
|
|
185
|
+
/**
|
|
186
|
+
* Uma posição como está agora. O investimento é de um titular (CPF ou CNPJ cadastrado), não do
|
|
187
|
+
* serviço: `holderDocument` diz de quem; sem ele, é da empresa dona do serviço. Documento que não
|
|
188
|
+
* existe no cadastro vira erro 400 com `fields` (o sistema não cria titular). Cada reporte vira um
|
|
189
|
+
* ponto do histórico; só o de referência mais recente é o valor atual.
|
|
190
|
+
*/
|
|
191
|
+
upsert: async (externalId, position) => {
|
|
192
|
+
const result = await request("PUT", "/investments/positions", { positions: [{ ...position, externalId }] });
|
|
193
|
+
return result.positions[0];
|
|
194
|
+
},
|
|
195
|
+
/** Qualquer quantidade: o SDK divide em lotes de 200. Cada lote é tudo ou nada. */
|
|
196
|
+
upsertMany: async (positions) => {
|
|
197
|
+
const saved = [];
|
|
198
|
+
for (const part of chunk(positions, 200)) {
|
|
199
|
+
const result = await request("PUT", "/investments/positions", { positions: part });
|
|
200
|
+
saved.push(...result.positions);
|
|
201
|
+
}
|
|
202
|
+
return { saved: saved.length, positions: saved };
|
|
203
|
+
},
|
|
204
|
+
/** As posições que este serviço reportou (e só elas). */
|
|
205
|
+
list: (query = {}) => {
|
|
206
|
+
const params = new URLSearchParams();
|
|
207
|
+
if (query.status)
|
|
208
|
+
params.set("status", query.status);
|
|
209
|
+
if (query.page)
|
|
210
|
+
params.set("page", String(query.page));
|
|
211
|
+
if (query.limit)
|
|
212
|
+
params.set("limit", String(query.limit));
|
|
213
|
+
const suffix = params.size > 0 ? `?${params}` : "";
|
|
214
|
+
return request("GET", `/investments/positions${suffix}`);
|
|
215
|
+
},
|
|
216
|
+
/** Encerra a posição (o histórico fica). Reportar de novo como ativa reabre. */
|
|
217
|
+
close: (externalId) => request("DELETE", `/investments/positions/${id(externalId)}`),
|
|
218
|
+
/**
|
|
219
|
+
* Pontos de histórico de uma posição já reportada, em lote (até 500 por chamada), pra preencher o passado.
|
|
220
|
+
* Ponto antigo entra no histórico e não troca o valor atual; só o ponto de referência mais recente o troca.
|
|
221
|
+
* Repetir um ponto idêntico não duplica.
|
|
222
|
+
*/
|
|
223
|
+
reportHistory: async (externalId, points) => {
|
|
224
|
+
const total = { received: 0, recorded: 0, skipped: 0, currentUpdated: false };
|
|
225
|
+
for (const part of chunk(points, BATCH_SIZE)) {
|
|
226
|
+
const result = await request("PUT", `/investments/positions/${id(externalId)}/history`, { points: part });
|
|
227
|
+
total.received += result.received;
|
|
228
|
+
total.recorded += result.recorded;
|
|
229
|
+
total.skipped += result.skipped;
|
|
230
|
+
total.currentUpdated = total.currentUpdated || result.currentUpdated;
|
|
231
|
+
}
|
|
232
|
+
return total;
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
movements: {
|
|
236
|
+
/** Aporte, resgate, rendimento ou taxa de uma posição que o serviço já reportou. */
|
|
237
|
+
upsert: (externalId, movement) => request("PUT", "/investments/movements", { movements: [{ ...movement, externalId }] }),
|
|
238
|
+
/** Qualquer quantidade: o SDK divide em lotes de 500. */
|
|
239
|
+
upsertMany: async (movements) => {
|
|
240
|
+
let saved = 0;
|
|
241
|
+
for (const part of chunk(movements, BATCH_SIZE)) {
|
|
242
|
+
const result = await request("PUT", "/investments/movements", { movements: part });
|
|
243
|
+
saved += result.saved;
|
|
244
|
+
}
|
|
245
|
+
return { saved };
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
subscriptions: {
|
|
250
|
+
/**
|
|
251
|
+
* Cria o pagamento recorrente no provedor do CNPJ: Pix Automático
|
|
252
|
+
* (`method: "pix"`, pela Woovi) ou cartão (`method: "card"`, pelo Asaas ou
|
|
253
|
+
* pela Stripe). O cliente autoriza uma vez (`pixCopyPaste` no banco dele, ou
|
|
254
|
+
* `authorizationUrl` pra cadastrar o cartão) e os débitos seguintes acontecem sozinhos: cada um
|
|
255
|
+
* pago vira uma cobrança paga do serviço, sem chamada nenhuma. Pedir de
|
|
256
|
+
* novo o mesmo id devolve a recorrência que já existe; pra mudar valor ou
|
|
257
|
+
* intervalo, cancele e crie outra.
|
|
258
|
+
*/
|
|
259
|
+
create: (externalId, subscription) => request("PUT", `/subscriptions/${id(externalId)}`, subscription),
|
|
260
|
+
get: (externalId) => request("GET", `/subscriptions/${id(externalId)}`),
|
|
261
|
+
/** Encerra a recorrência: não há mais débitos. */
|
|
262
|
+
cancel: (externalId) => request("POST", `/subscriptions/${id(externalId)}/cancel`, {}),
|
|
263
|
+
},
|
|
264
|
+
/**
|
|
265
|
+
* Avisos do Core pro seu serviço. Cadastre o endereço uma vez e guarde o `secret` (só aparece ao criar):
|
|
266
|
+
* cada mudança de situação (cobrança paga, nota emitida, recorrência ativada...) chega por POST, assinada.
|
|
267
|
+
* Responda 2xx pra confirmar. Qualquer outra resposta, erro ou demora (15 s) faz o Core tentar de novo,
|
|
268
|
+
* esperando 2 s, 4 s, 8 s, 16 s... até 1 hora entre tentativas, pra sempre, até você aceitar.
|
|
269
|
+
* Confira cada aviso com `verifyWebhook`.
|
|
270
|
+
*/
|
|
271
|
+
webhooks: {
|
|
272
|
+
list: () => request("GET", "/webhooks"),
|
|
273
|
+
get: (endpointId) => request("GET", `/webhooks/${endpointId}`),
|
|
274
|
+
/** Devolve o endereço com o `secret`. Endereço repetido dá 409 `webhook_exists`. */
|
|
275
|
+
create: (endpoint) => request("POST", "/webhooks", endpoint),
|
|
276
|
+
/** Trocar o endereço ou reativar manda na hora o que estava esperando. */
|
|
277
|
+
update: (endpointId, changes) => request("PATCH", `/webhooks/${endpointId}`, changes),
|
|
278
|
+
/** Apaga o endereço e descarta o que ainda não foi entregue nele. */
|
|
279
|
+
delete: (endpointId) => request("DELETE", `/webhooks/${endpointId}`),
|
|
280
|
+
/** Segredo novo, valendo na hora. */
|
|
281
|
+
rotateSecret: (endpointId) => request("POST", `/webhooks/${endpointId}/rotate-secret`, {}),
|
|
282
|
+
/** Manda um `webhook.test` pra este endereço. */
|
|
283
|
+
test: (endpointId) => request("POST", `/webhooks/${endpointId}/test`, {}),
|
|
284
|
+
deliveries: (endpointId, query = {}) => request("GET", `/webhooks/${endpointId}/deliveries${queryString(query)}`),
|
|
285
|
+
/** Manda de novo agora (também a já entregue). */
|
|
286
|
+
resend: (endpointId, deliveryId) => request("POST", `/webhooks/${endpointId}/deliveries/${deliveryId}/resend`, {}),
|
|
287
|
+
},
|
|
288
|
+
/** Todos os avisos já gerados pro serviço, do mais novo ao mais antigo: pra conferir o que pode ter passado. */
|
|
289
|
+
events: {
|
|
290
|
+
list: (query = {}) => {
|
|
291
|
+
const since = query.since === undefined ? undefined : typeof query.since === "string" ? query.since : query.since.toISOString();
|
|
292
|
+
return request("GET", `/events${queryString({ ...query, since })}`);
|
|
293
|
+
},
|
|
294
|
+
get: (eventId) => request("GET", `/events/${encodeURIComponent(eventId)}`),
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function queryString(query) {
|
|
299
|
+
const params = new URLSearchParams();
|
|
300
|
+
for (const [key, value] of Object.entries(query)) {
|
|
301
|
+
if (value !== undefined && value !== "")
|
|
302
|
+
params.set(key, String(value));
|
|
303
|
+
}
|
|
304
|
+
const text = params.toString();
|
|
305
|
+
return text ? `?${text}` : "";
|
|
306
|
+
}
|
|
307
|
+
// ─── Conferir um aviso ──────────────────────────────────────────────
|
|
308
|
+
/** Aviso com assinatura que não confere, velho demais ou malformado: responda 400 e não processe. */
|
|
309
|
+
export class WebhookVerificationError extends Error {
|
|
310
|
+
constructor(message) {
|
|
311
|
+
super(message);
|
|
312
|
+
this.name = "WebhookVerificationError";
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function headerOf(headers, name) {
|
|
316
|
+
if (typeof Headers !== "undefined" && headers instanceof Headers)
|
|
317
|
+
return headers.get(name);
|
|
318
|
+
const record = headers;
|
|
319
|
+
const key = Object.keys(record).find((candidate) => candidate.toLowerCase() === name);
|
|
320
|
+
const value = key === undefined ? undefined : record[key];
|
|
321
|
+
return Array.isArray(value) ? (value[0] ?? null) : (value ?? null);
|
|
322
|
+
}
|
|
323
|
+
function base64ToBytes(value) {
|
|
324
|
+
const binary = atob(value);
|
|
325
|
+
const bytes = new Uint8Array(binary.length);
|
|
326
|
+
for (let index = 0; index < binary.length; index += 1)
|
|
327
|
+
bytes[index] = binary.charCodeAt(index);
|
|
328
|
+
return bytes;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Confere a assinatura de um aviso do Core (padrão Standard Webhooks: cabeçalhos `webhook-id`,
|
|
332
|
+
* `webhook-timestamp` e `webhook-signature`) e devolve o aviso já interpretado. Falhou, lança
|
|
333
|
+
* `WebhookVerificationError`.
|
|
334
|
+
*
|
|
335
|
+
* app.post("/core/webhook", express.raw({ type: "application/json" }), async (req, res) => {
|
|
336
|
+
* const event = await verifyWebhook({ payload: req.body, headers: req.headers, secret: process.env.CORE_WEBHOOK_SECRET });
|
|
337
|
+
* if (event.type === "charge.paid") await releaseOrder(event.data.externalId);
|
|
338
|
+
* res.sendStatus(204);
|
|
339
|
+
* });
|
|
340
|
+
*
|
|
341
|
+
* O mesmo aviso pode chegar mais de uma vez (o Core repete até ter 2xx): use `event.id` pra não processar duas vezes.
|
|
342
|
+
*/
|
|
343
|
+
export async function verifyWebhook(options) {
|
|
344
|
+
const eventId = headerOf(options.headers, "webhook-id");
|
|
345
|
+
const timestamp = headerOf(options.headers, "webhook-timestamp");
|
|
346
|
+
const signatures = headerOf(options.headers, "webhook-signature");
|
|
347
|
+
if (!eventId || !timestamp || !signatures)
|
|
348
|
+
throw new WebhookVerificationError("faltam os cabeçalhos webhook-id, webhook-timestamp ou webhook-signature");
|
|
349
|
+
const seconds = Number(timestamp);
|
|
350
|
+
const tolerance = options.toleranceSeconds ?? 300;
|
|
351
|
+
if (!Number.isInteger(seconds) || Math.abs(Date.now() / 1000 - seconds) > tolerance)
|
|
352
|
+
throw new WebhookVerificationError("aviso fora da janela de tempo (relógio errado ou reenvio antigo)");
|
|
353
|
+
const body = typeof options.payload === "string" ? options.payload : new TextDecoder().decode(options.payload);
|
|
354
|
+
const subtle = globalThis.crypto.subtle;
|
|
355
|
+
const key = await subtle.importKey("raw", base64ToBytes(options.secret.replace(/^whsec_/, "")), { name: "HMAC", hash: "SHA-256" }, false, ["verify"]);
|
|
356
|
+
const signed = new TextEncoder().encode(`${eventId}.${timestamp}.${body}`);
|
|
357
|
+
for (const entry of signatures.split(" ")) {
|
|
358
|
+
const [version, signature] = entry.split(",");
|
|
359
|
+
if (version !== "v1" || !signature)
|
|
360
|
+
continue;
|
|
361
|
+
let bytes;
|
|
362
|
+
try {
|
|
363
|
+
bytes = base64ToBytes(signature);
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (await subtle.verify("HMAC", key, bytes, signed))
|
|
369
|
+
return JSON.parse(body);
|
|
370
|
+
}
|
|
371
|
+
throw new WebhookVerificationError("assinatura não confere");
|
|
372
|
+
}
|
|
373
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@felipepasc/core-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Cliente da API de integração do Core: métricas, assinantes, lançamentos, orçamentos, cobranças e avisos (webhooks).",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/felipepasc/core.git",
|
|
10
|
+
"directory": "sdk"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"registry": "https://registry.npmjs.org",
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"main": "dist/index.js",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"import": "./dist/index.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=20"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"clean": "rimraf dist tsconfig.tsbuildinfo",
|
|
33
|
+
"build": "npm run clean && tsc -b",
|
|
34
|
+
"dev": "tsc -b --watch --preserveWatchOutput",
|
|
35
|
+
"prepublishOnly": "npm run build"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^25.0.3",
|
|
39
|
+
"rimraf": "^6.1.3",
|
|
40
|
+
"typescript": "^6.0.3"
|
|
41
|
+
}
|
|
42
|
+
}
|