wyzecash 0.2.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Mudanças
2
2
 
3
+ ## 0.3.0 (15/11/2026)
4
+
5
+ **Atualize antes de 01/12/2026:** a 0.2.0 só lê o cabeçalho `X-Bukio-Signature`, que deixa de vir nos webhooks em 01/12/2026. A partir desse dia, o plugin `wyzecash/fastify` da 0.2.0 recusa todos os avisos.
6
+
7
+ **Mudanças que pedem ajuste no seu código:**
8
+
9
+ - Os webhooks passam a vir com os cabeçalhos `X-WyzeCash-Signature`, `X-WyzeCash-Event` e `X-WyzeCash-Delivery`. Até 30/11/2026 (23h59 de Brasília) os antigos `X-Bukio-*` vêm junto, com o mesmo valor; a partir de 01/12/2026, só os novos. A assinatura continua no mesmo formato.
10
+ - `SIGNATURE_HEADER` passa a ser `x-wyzecash-signature`; o antigo fica em `LEGACY_SIGNATURE_HEADER` (`x-bukio-signature`). O plugin `wyzecash/fastify` lê o cabeçalho novo primeiro e, sem ele, o antigo (com o plugin, nada muda no seu código). Se você lê o cabeçalho na mão, passe o `x-wyzecash-signature` para o `verifyWebhook`.
11
+ - A chave de API passa a começar com `wyze_` no lugar de `bk_live_` (a mesma chave, só o começo muda: `bk_live_ABC123_XYZ` vira `wyze_ABC123_XYZ`). A `bk_live_` vale até 30/11/2026; a partir de 01/12/2026, a API recusa com `401 OLD_KEY_PREFIX`. Troque o começo da chave na variável `WYZECASH_API_KEY`.
12
+ - As mensagens do `WyzeCashWebhookError` citam o `X-WyzeCash-Signature` (os códigos, como `MISSING_SIGNATURE`, não mudam).
13
+
14
+ **Novidades:**
15
+
16
+ - `subaccounts.updateSettings` aceita `medFeeToSubaccount`: repassar a taxa de MED à subconta (a Taxa de MED recebido de um MED numa venda da subconta sai dela).
17
+
3
18
  ## 0.2.0
4
19
 
5
20
  **Mudanças que pedem ajuste no seu código:**
package/README.md CHANGED
@@ -21,7 +21,7 @@ const cobranca = await wyzecash.payments.create({
21
21
  console.log(cobranca.copyPaste); // Pix Copia e Cola
22
22
  ```
23
23
 
24
- A chave de API (`bk_live_…`) é criada no painel, em Integrações e API, com uma permissão por rota. Sem passar a chave, o SDK lê a variável `WYZECASH_API_KEY`.
24
+ A chave de API (`wyze_…`) é criada no painel, em Integrações e API, com uma permissão por rota. Sem passar a chave, o SDK lê a variável `WYZECASH_API_KEY`.
25
25
 
26
26
  Não existe ambiente de testes: todo pedido é de verdade. Para testar, faça uma cobrança pequena.
27
27
 
@@ -102,18 +102,18 @@ Chamar a consulta da cobrança em sequência para ver se ela foi paga gasta o li
102
102
 
103
103
  ## Webhooks
104
104
 
105
- Cada aviso chega com o cabeçalho `X-Bukio-Signature`. Confira sempre com o corpo cru, como chegou:
105
+ Cada aviso chega com o cabeçalho `X-WyzeCash-Signature` (junto vêm o `X-WyzeCash-Event`, com o tipo do evento, e o `X-WyzeCash-Delivery`, com o código da entrega). Até 30/11/2026 os antigos `X-Bukio-*` vêm junto, com o mesmo valor; a partir de 01/12/2026, só os novos. Confira sempre com o corpo cru, como chegou:
106
106
 
107
107
  ```ts
108
108
  import { verifyWebhook } from "wyzecash";
109
109
 
110
- const evento = await verifyWebhook(corpoCru, request.headers["x-bukio-signature"], process.env.WYZECASH_WEBHOOK_SECRET);
110
+ const evento = await verifyWebhook(corpoCru, request.headers["x-wyzecash-signature"], process.env.WYZECASH_WEBHOOK_SECRET);
111
111
  if (evento.type === "payment.paid") {
112
112
  // marque o pedido como pago (use evento.id para não processar duas vezes)
113
113
  }
114
114
  ```
115
115
 
116
- Aviso com assinatura errada, sem assinatura ou assinado há mais de 5 minutos lança `WyzeCashWebhookError`.
116
+ Aviso com assinatura errada, sem assinatura ou assinado há mais de 5 minutos lança `WyzeCashWebhookError`. Os nomes dos cabeçalhos ficam em `SIGNATURE_HEADER` (`x-wyzecash-signature`) e `LEGACY_SIGNATURE_HEADER` (o antigo, `x-bukio-signature`).
117
117
 
118
118
  ### Fastify
119
119
 
@@ -136,7 +136,7 @@ await app.register(wyzecashWebhooks, {
136
136
  await app.listen({ port: 3000 });
137
137
  ```
138
138
 
139
- O plugin lê o corpo cru só na rota dele (o resto da aplicação continua lendo JSON como sempre) e responde `200` quando deu certo, `400` quando o aviso não é da WyzeCash e `500` quando o `onEvent` falha (a WyzeCash manda de novo mais tarde).
139
+ O plugin lê o corpo cru só na rota dele (o resto da aplicação continua lendo JSON como sempre), confere o `X-WyzeCash-Signature` (sem ele, o antigo `X-Bukio-Signature`) e responde `200` quando deu certo, `400` quando o aviso não é da WyzeCash e `500` quando o `onEvent` falha (a WyzeCash manda de novo mais tarde).
140
140
 
141
141
  ## Tempo real (WebSocket)
142
142
 
@@ -157,6 +157,34 @@ ws.on("error", (erro) => console.error(erro.code, erro.message));
157
157
  - Chave apagada ou inválida fecha a conexão (código 1008) e não reconecta. `ws.close()` fecha de vez.
158
158
  - No Node 20, que não tem WebSocket, passe o do pacote `ws`: `wyzecash.realtime({ WebSocket })` com `import WebSocket from "ws"`.
159
159
 
160
+ ## Atualizar da 0.2.0
161
+
162
+ ```bash
163
+ npm install wyzecash@0.3.0
164
+ ```
165
+
166
+ > **Atualize antes de 01/12/2026.** A 0.2.0 só lê o cabeçalho `X-Bukio-Signature`, que deixa de vir nos webhooks em 01/12/2026: a partir desse dia, o plugin `wyzecash/fastify` da 0.2.0 recusa todos os avisos.
167
+
168
+ | Na 0.2.0 | Na 0.3.0 |
169
+ | --- | --- |
170
+ | Cabeçalho `X-Bukio-Signature` | `X-WyzeCash-Signature`. Até 30/11/2026 o antigo vem junto, com o mesmo valor |
171
+ | `SIGNATURE_HEADER` é `x-bukio-signature` | `SIGNATURE_HEADER` é `x-wyzecash-signature`, e o antigo fica em `LEGACY_SIGNATURE_HEADER` |
172
+ | Chave de API `bk_live_…` | `wyze_…` (a mesma chave, só o começo muda) |
173
+
174
+ **Webhooks:** com o plugin `wyzecash/fastify`, nada muda no seu código: ele lê o cabeçalho novo e, sem ele, o antigo. Se você lê o cabeçalho na mão, passe o novo para o `verifyWebhook` (a assinatura continua no mesmo formato):
175
+
176
+ ```ts
177
+ // Antes (0.2.0)
178
+ const evento = await verifyWebhook(corpoCru, request.headers["x-bukio-signature"], process.env.WYZECASH_WEBHOOK_SECRET);
179
+
180
+ // Agora (0.3.0)
181
+ const evento = await verifyWebhook(corpoCru, request.headers["x-wyzecash-signature"], process.env.WYZECASH_WEBHOOK_SECRET);
182
+ ```
183
+
184
+ **Chave de API:** troque o começo da chave onde ela fica guardada (a variável `WYZECASH_API_KEY`): `bk_live_ABC123_XYZ` vira `wyze_ABC123_XYZ`. A `bk_live_` vale até 30/11/2026; a partir de 01/12/2026, a API recusa com `401 OLD_KEY_PREFIX`. O resto do código não muda.
185
+
186
+ **O que mais mudou:** `subaccounts.updateSettings` aceita `medFeeToSubaccount`, para repassar a taxa de MED à subconta.
187
+
160
188
  ## Documentação
161
189
 
162
190
  Referência completa da API: https://docs.wyzecash.com.br
package/dist/client.d.ts CHANGED
@@ -5,7 +5,7 @@ import { RealtimeConnection, type RealtimeOptions } from "./realtime.js";
5
5
  import { Webhooks } from "./webhooks.js";
6
6
  export declare const DEFAULT_BASE_URL = "https://api.wyzecash.com.br";
7
7
  export interface ClientOptions {
8
- /** A chave de API (`bk_live_…`). Sem ela, vale a variável de ambiente `WYZECASH_API_KEY`. */
8
+ /** A chave de API (`wyze_…`). Sem ela, vale a variável de ambiente `WYZECASH_API_KEY`. */
9
9
  apiKey?: string;
10
10
  /** Endereço da API (padrão: o de produção). */
11
11
  baseUrl?: string;
package/dist/fastify.js CHANGED
@@ -7,13 +7,21 @@
7
7
  // async onEvent(evento) { if (evento.type === "payment.paid") ... },
8
8
  // });
9
9
  //
10
- // A rota lê o corpo cru (a assinatura é conferida nos bytes como chegaram). O plugin não é
11
- // "fastify-plugin" de propósito: a troca do leitor de JSON fica só dentro dele e o resto da sua
12
- // aplicação continua lendo JSON como sempre. Responde 200 quando deu certo, 400 quando o aviso não
13
- // é da WyzeCash e 500 quando o seu onEvent falha (aí a WyzeCash manda de novo mais tarde).
10
+ // A rota lê o corpo cru (a assinatura é conferida nos bytes como chegaram) e a assinatura do
11
+ // cabeçalho X-WyzeCash-Signature; sem ele, a do antigo X-Bukio-Signature, que vem junto até
12
+ // 30/11/2026. O plugin não é "fastify-plugin" de propósito: a troca do leitor de JSON fica só
13
+ // dentro dele e o resto da sua aplicação continua lendo JSON como sempre. Responde 200 quando deu
14
+ // certo, 400 quando o aviso não é da WyzeCash e 500 quando o seu onEvent falha (aí a WyzeCash
15
+ // manda de novo mais tarde).
14
16
  import { WyzeCashWebhookError } from "./errors.js";
15
- import { SIGNATURE_HEADER, verifyWebhook } from "./webhooks.js";
17
+ import { LEGACY_SIGNATURE_HEADER, SIGNATURE_HEADER, verifyWebhook } from "./webhooks.js";
16
18
  const env = (name) => globalThis.process?.env?.[name];
19
+ /** O valor de um cabeçalho (o primeiro, se vier repetido), ou nada quando falta ou vem vazio. */
20
+ function header(request, name) {
21
+ const value = request.headers[name];
22
+ const text = Array.isArray(value) ? value[0] : value;
23
+ return text || undefined;
24
+ }
17
25
  export async function wyzecashWebhooks(fastify, options) {
18
26
  const secret = options.secret ?? env("WYZECASH_WEBHOOK_SECRET");
19
27
  if (!secret)
@@ -28,7 +36,7 @@ export async function wyzecashWebhooks(fastify, options) {
28
36
  return reply.code(400).send({ error: "Corpo do aviso vazio ou fora do JSON." });
29
37
  let event;
30
38
  try {
31
- event = await verifyWebhook(raw, request.headers[SIGNATURE_HEADER], secret, { tolerance: options.tolerance });
39
+ event = await verifyWebhook(raw, header(request, SIGNATURE_HEADER) ?? header(request, LEGACY_SIGNATURE_HEADER), secret, { tolerance: options.tolerance });
32
40
  }
33
41
  catch (error) {
34
42
  if (error instanceof WyzeCashWebhookError) {
@@ -2315,6 +2315,8 @@ export type SubaccountsUpdateSettingsParams = {
2315
2315
  };
2316
2316
  /** Bloqueio automático por MED: subconta sem saldo livre para o MED fica sem sacar até pagar. */
2317
2317
  medAutoLock?: boolean;
2318
+ /** Repassar a taxa de MED à subconta: a Taxa de MED recebido de um MED numa venda da subconta sai dela (na venda dividida, cada uma paga a parte dela); sem saldo livre, fica pendente e sai das próximas entradas dela. */
2319
+ medFeeToSubaccount?: boolean;
2318
2320
  /** Saque para o titular: `off`, `notify` (avisa quando é outra pessoa) ou `cpf_only` (só a chave CPF/CNPJ do titular). */
2319
2321
  holderWithdrawal?: "off" | "notify" | "cpf_only";
2320
2322
  };
@@ -3483,7 +3485,7 @@ export declare class SubaccountsResource {
3483
3485
  *
3484
3486
  * - Sem taxa no pedido, a subconta segue a taxa global da Configuração das subcontas (`feeMode: "global"`); com comissão por venda (`saleFeeBps`, `saleFeeFixed`) ou taxa por saque (`withdrawFeeBps`, `withdrawFeeFixed`), fica com a própria (`feeMode: "custom"`). `pixKey` é a chave Pix do cliente para o saque dele.
3485
3487
  * - Os `limits` que não vierem no pedido usam os limites padrão da Configuração das subcontas.
3486
- * - O `name` tem de 2 a 80 caracteres. Use só o nome do cliente: o CPF/CNPJ vai em `document` e o id do seu sistema em `externalId`.
3488
+ * - O `name` é o nome do cliente (com CPF, nome e sobrenome; com CNPJ, a razão social; até 100 caracteres), sem CPF/CNPJ, id ou colchetes: o CPF/CNPJ vai em `document` e o id do seu sistema em `externalId`. Até 30/11/2026 o nome fora da regra ainda passa, com o cabeçalho `Warning`; a partir de 01/12/2026, `422 INVALID_NAME`.
3487
3489
  * - Opcionais: `document` (CPF ou CNPJ do titular, guardado criptografado; volta inteiro ao abrir a subconta e mascarado na lista), `lockMode` (`none`, `receive`, `withdraw` ou `full`) e `limits` (`perWithdrawal`, `daily`, `monthly` em centavos para o saque da subconta; `null` sem limite).
3488
3490
  *
3489
3491
  * `POST /v1/subaccounts`
@@ -3532,7 +3534,7 @@ export declare class SubaccountsResource {
3532
3534
  /**
3533
3535
  * Configuração das subcontas
3534
3536
  *
3535
- * A taxa global (`saleFee`, `withdrawFee`: o que você ganha em cada venda e saque das subcontas com `feeMode` global), os limites padrão das subcontas novas (`limits`), o bloqueio automático por MED (`medAutoLock`), o saque para o titular (`holderWithdrawal`: `off`, `notify` ou `cpf_only`), quantas seguem a global (`subaccounts`) e as tarifas da WyzeCash na conta (`platform`). Centavos e pontos-base.
3537
+ * A taxa global (`saleFee`, `withdrawFee`: o que você ganha em cada venda e saque das subcontas com `feeMode` global), os limites padrão das subcontas novas (`limits`), o bloqueio automático por MED (`medAutoLock`), o repasse da taxa de MED à subconta (`medFeeToSubaccount`), o saque para o titular (`holderWithdrawal`: `off`, `notify` ou `cpf_only`), quantas seguem a global (`subaccounts`) e as tarifas da WyzeCash na conta (`platform`, com a Taxa de MED recebido em `med`). Centavos e pontos-base.
3536
3538
  *
3537
3539
  * **Permissão da chave:** `subaccounts:get`.
3538
3540
  *
@@ -3542,7 +3544,7 @@ export declare class SubaccountsResource {
3542
3544
  /**
3543
3545
  * Mudar a Configuração das subcontas
3544
3546
  *
3545
- * Muda a taxa global (`saleFeeBps`, `saleFeeFixed`, `withdrawFeeBps`, `withdrawFeeFixed`), os limites padrão (`limits`, que não passam dos da conta), o bloqueio automático por MED (`medAutoLock`) e o saque para o titular (`holderWithdrawal`). O que não vier fica como está. Só o dono da conta.
3547
+ * Muda a taxa global (`saleFeeBps`, `saleFeeFixed`, `withdrawFeeBps`, `withdrawFeeFixed`), os limites padrão (`limits`, que não passam dos da conta), o bloqueio automático por MED (`medAutoLock`), o repasse da taxa de MED à subconta (`medFeeToSubaccount`: a Taxa de MED recebido de um MED numa venda da subconta sai dela; sem saldo livre, fica pendente nela) e o saque para o titular (`holderWithdrawal`). O que não vier fica como está. Só o dono da conta.
3546
3548
  *
3547
3549
  * **Permissão da chave:** `subaccounts:update`.
3548
3550
  *
@@ -3565,7 +3567,7 @@ export declare class SubaccountsResource {
3565
3567
  /**
3566
3568
  * Movimentos da subconta
3567
3569
  *
3568
- * Os movimentos SUB- da subconta; filtros `from`/`to` e `kind` (`sale`, `fund`, `transfer`, `withdraw`, `return`, `refund`, `med`).
3570
+ * Os movimentos SUB- da subconta; filtros `from`/`to` e `kind` (`sale`, `fund`, `transfer`, `withdraw`, `return`, `refund`, `med`, `med_fee`, a taxa de MED repassada).
3569
3571
  *
3570
3572
  * **Permissão da chave:** `subaccounts:entries`.
3571
3573
  *
package/dist/generated.js CHANGED
@@ -558,7 +558,7 @@ export class SubaccountsResource {
558
558
  *
559
559
  * - Sem taxa no pedido, a subconta segue a taxa global da Configuração das subcontas (`feeMode: "global"`); com comissão por venda (`saleFeeBps`, `saleFeeFixed`) ou taxa por saque (`withdrawFeeBps`, `withdrawFeeFixed`), fica com a própria (`feeMode: "custom"`). `pixKey` é a chave Pix do cliente para o saque dele.
560
560
  * - Os `limits` que não vierem no pedido usam os limites padrão da Configuração das subcontas.
561
- * - O `name` tem de 2 a 80 caracteres. Use só o nome do cliente: o CPF/CNPJ vai em `document` e o id do seu sistema em `externalId`.
561
+ * - O `name` é o nome do cliente (com CPF, nome e sobrenome; com CNPJ, a razão social; até 100 caracteres), sem CPF/CNPJ, id ou colchetes: o CPF/CNPJ vai em `document` e o id do seu sistema em `externalId`. Até 30/11/2026 o nome fora da regra ainda passa, com o cabeçalho `Warning`; a partir de 01/12/2026, `422 INVALID_NAME`.
562
562
  * - Opcionais: `document` (CPF ou CNPJ do titular, guardado criptografado; volta inteiro ao abrir a subconta e mascarado na lista), `lockMode` (`none`, `receive`, `withdraw` ou `full`) e `limits` (`perWithdrawal`, `daily`, `monthly` em centavos para o saque da subconta; `null` sem limite).
563
563
  *
564
564
  * `POST /v1/subaccounts`
@@ -617,7 +617,7 @@ export class SubaccountsResource {
617
617
  /**
618
618
  * Configuração das subcontas
619
619
  *
620
- * A taxa global (`saleFee`, `withdrawFee`: o que você ganha em cada venda e saque das subcontas com `feeMode` global), os limites padrão das subcontas novas (`limits`), o bloqueio automático por MED (`medAutoLock`), o saque para o titular (`holderWithdrawal`: `off`, `notify` ou `cpf_only`), quantas seguem a global (`subaccounts`) e as tarifas da WyzeCash na conta (`platform`). Centavos e pontos-base.
620
+ * A taxa global (`saleFee`, `withdrawFee`: o que você ganha em cada venda e saque das subcontas com `feeMode` global), os limites padrão das subcontas novas (`limits`), o bloqueio automático por MED (`medAutoLock`), o repasse da taxa de MED à subconta (`medFeeToSubaccount`), o saque para o titular (`holderWithdrawal`: `off`, `notify` ou `cpf_only`), quantas seguem a global (`subaccounts`) e as tarifas da WyzeCash na conta (`platform`, com a Taxa de MED recebido em `med`). Centavos e pontos-base.
621
621
  *
622
622
  * **Permissão da chave:** `subaccounts:get`.
623
623
  *
@@ -629,7 +629,7 @@ export class SubaccountsResource {
629
629
  /**
630
630
  * Mudar a Configuração das subcontas
631
631
  *
632
- * Muda a taxa global (`saleFeeBps`, `saleFeeFixed`, `withdrawFeeBps`, `withdrawFeeFixed`), os limites padrão (`limits`, que não passam dos da conta), o bloqueio automático por MED (`medAutoLock`) e o saque para o titular (`holderWithdrawal`). O que não vier fica como está. Só o dono da conta.
632
+ * Muda a taxa global (`saleFeeBps`, `saleFeeFixed`, `withdrawFeeBps`, `withdrawFeeFixed`), os limites padrão (`limits`, que não passam dos da conta), o bloqueio automático por MED (`medAutoLock`), o repasse da taxa de MED à subconta (`medFeeToSubaccount`: a Taxa de MED recebido de um MED numa venda da subconta sai dela; sem saldo livre, fica pendente nela) e o saque para o titular (`holderWithdrawal`). O que não vier fica como está. Só o dono da conta.
633
633
  *
634
634
  * **Permissão da chave:** `subaccounts:update`.
635
635
  *
@@ -656,7 +656,7 @@ export class SubaccountsResource {
656
656
  /**
657
657
  * Movimentos da subconta
658
658
  *
659
- * Os movimentos SUB- da subconta; filtros `from`/`to` e `kind` (`sale`, `fund`, `transfer`, `withdraw`, `return`, `refund`, `med`).
659
+ * Os movimentos SUB- da subconta; filtros `from`/`to` e `kind` (`sale`, `fund`, `transfer`, `withdraw`, `return`, `refund`, `med`, `med_fee`, a taxa de MED repassada).
660
660
  *
661
661
  * **Permissão da chave:** `subaccounts:entries`.
662
662
  *
package/dist/index.d.ts CHANGED
@@ -5,4 +5,4 @@ export * from "./generated.js";
5
5
  export { ListPromise } from "./pagination.js";
6
6
  export { RealtimeConnection, matchesEvent, type RealtimeEvent, type RealtimeOptions, type WebSocketConstructor, type WebSocketLike } from "./realtime.js";
7
7
  export { VERSION } from "./version.js";
8
- export { SIGNATURE_HEADER, WEBHOOK_EVENT_TYPES, signWebhook, verifyWebhook, type VerifyOptions, type WebhookEvent, type WebhookEventType } from "./webhooks.js";
8
+ export { LEGACY_SIGNATURE_HEADER, SIGNATURE_HEADER, WEBHOOK_EVENT_TYPES, signWebhook, verifyWebhook, type VerifyOptions, type WebhookEvent, type WebhookEventType } from "./webhooks.js";
package/dist/index.js CHANGED
@@ -4,4 +4,4 @@ export * from "./generated.js";
4
4
  export { ListPromise } from "./pagination.js";
5
5
  export { RealtimeConnection, matchesEvent } from "./realtime.js";
6
6
  export { VERSION } from "./version.js";
7
- export { SIGNATURE_HEADER, WEBHOOK_EVENT_TYPES, signWebhook, verifyWebhook } from "./webhooks.js";
7
+ export { LEGACY_SIGNATURE_HEADER, SIGNATURE_HEADER, WEBHOOK_EVENT_TYPES, signWebhook, verifyWebhook } from "./webhooks.js";
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "0.2.0";
1
+ export declare const VERSION = "0.3.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.2.0";
1
+ export const VERSION = "0.3.0";
@@ -13,7 +13,10 @@ export interface VerifyOptions {
13
13
  /** Agora, em segundos (para testes). */
14
14
  now?: number;
15
15
  }
16
- export declare const SIGNATURE_HEADER = "x-bukio-signature";
16
+ /** O cabeçalho da assinatura (em minúsculas, como o Node entrega). */
17
+ export declare const SIGNATURE_HEADER = "x-wyzecash-signature";
18
+ /** O cabeçalho antigo: vem junto, com o mesmo valor, até 30/11/2026; a partir de 01/12/2026, não vem mais. */
19
+ export declare const LEGACY_SIGNATURE_HEADER = "x-bukio-signature";
17
20
  /**
18
21
  * Confere a assinatura e devolve o evento. Lança `WyzeCashWebhookError` quando o aviso não é da
19
22
  * WyzeCash (assinatura errada, sem assinatura ou fora do prazo).
package/dist/webhooks.js CHANGED
@@ -1,7 +1,8 @@
1
1
  // Conferir a assinatura dos webhooks da WyzeCash. Cada aviso chega com o cabeçalho
2
- // X-Bukio-Signature: t=<unix>,v1=<HMAC-SHA256 em hex de "<t>.<corpo>">
3
- // feito com o segredo do webhook (painel › Integrações e API › Webhooks). Confira sempre com o
4
- // corpo cru, como chegou: o JSON lido e escrito de novo muda os bytes e a assinatura não bate.
2
+ // X-WyzeCash-Signature: t=<unix>,v1=<HMAC-SHA256 em hex de "<t>.<corpo>">
3
+ // feito com o segredo do webhook (painel › Integrações e API › Webhooks). Até 30/11/2026 o antigo
4
+ // X-Bukio-Signature vem junto, com o mesmo valor; a partir de 01/12/2026, só o novo. Confira sempre
5
+ // com o corpo cru, como chegou: o JSON lido e escrito de novo muda os bytes e a assinatura não bate.
5
6
  // Usa o Web Crypto, então funciona no Node 20+, Bun, Deno e servidores na borda.
6
7
  import { WyzeCashWebhookError } from "./errors.js";
7
8
  export const WEBHOOK_EVENT_TYPES = [
@@ -20,7 +21,10 @@ export const WEBHOOK_EVENT_TYPES = [
20
21
  "subaccount.debited",
21
22
  "webhook.test",
22
23
  ];
23
- export const SIGNATURE_HEADER = "x-bukio-signature";
24
+ /** O cabeçalho da assinatura (em minúsculas, como o Node entrega). */
25
+ export const SIGNATURE_HEADER = "x-wyzecash-signature";
26
+ /** O cabeçalho antigo: vem junto, com o mesmo valor, até 30/11/2026; a partir de 01/12/2026, não vem mais. */
27
+ export const LEGACY_SIGNATURE_HEADER = "x-bukio-signature";
24
28
  const encoder = new TextEncoder();
25
29
  function toBytes(body) {
26
30
  if (typeof body === "string")
@@ -49,12 +53,12 @@ export async function verifyWebhook(body, signatureHeader, secret, options = {})
49
53
  if (!secret)
50
54
  throw new Error("Passe o segredo do webhook (painel › Integrações e API › Webhooks).");
51
55
  if (!signatureHeader)
52
- throw new WyzeCashWebhookError("Aviso sem o cabeçalho X-Bukio-Signature.", "MISSING_SIGNATURE");
56
+ throw new WyzeCashWebhookError("Aviso sem o cabeçalho X-WyzeCash-Signature.", "MISSING_SIGNATURE");
53
57
  const parts = signatureHeader.split(",").map((part) => part.trim().split("="));
54
58
  const timestamp = Number(parts.find(([k]) => k === "t")?.[1]);
55
59
  const signatures = parts.filter(([k]) => k === "v1").map(([, v]) => v ?? "");
56
60
  if (!Number.isInteger(timestamp) || !signatures.length)
57
- throw new WyzeCashWebhookError("Cabeçalho X-Bukio-Signature em formato errado.", "INVALID_SIGNATURE");
61
+ throw new WyzeCashWebhookError("Cabeçalho X-WyzeCash-Signature em formato errado.", "INVALID_SIGNATURE");
58
62
  const tolerance = options.tolerance ?? 300;
59
63
  const now = options.now ?? Math.floor(Date.now() / 1000);
60
64
  if (Math.abs(now - timestamp) > tolerance)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wyzecash",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "SDK oficial da WyzeCash para Node.js, Bun e Deno: cobranças por Pix, cartão e cripto, saques, subcontas e webhooks (com plugin para o Fastify).",
5
5
  "license": "MIT",
6
6
  "type": "module",