@garuhq/node 0.8.0 → 0.11.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 +34 -0
- package/README.md +7 -3
- package/dist/index.cjs +94 -8
- package/dist/index.d.cts +129 -11
- package/dist/index.d.ts +129 -11
- package/dist/index.js +94 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,40 @@
|
|
|
3
3
|
All notable changes to `@garuhq/node` are documented in this file. Format:
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning: [SemVer](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [0.11.0] — 2026-05-19
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- `webhookEvents` resource on the `Garu` client — the seller-facing
|
|
11
|
+
delivery log for outbound webhooks. Use it to audit deliveries from
|
|
12
|
+
the seller's API key, the canonical "did my customer's endpoint
|
|
13
|
+
actually receive event X?" workflow.
|
|
14
|
+
- `webhookEvents.list({ status?, eventType?, endpointId?, page?, limit? })`
|
|
15
|
+
— `GET /api/webhook-events`. Filter by delivery state
|
|
16
|
+
(`pending` / `success` / `failed`), Garu event type, or destination
|
|
17
|
+
endpoint id. Newest first.
|
|
18
|
+
- `webhookEvents.get(id)` — `GET /api/webhook-events/{id}`. Returns
|
|
19
|
+
the full payload, the embedded endpoint snapshot, and the most
|
|
20
|
+
recent response status/body.
|
|
21
|
+
- `webhookEvents.retry(id)` — `POST /api/webhook-events/{id}/retry`.
|
|
22
|
+
Resets the event to `pending`, clears the retry schedule, and
|
|
23
|
+
triggers an immediate delivery attempt. Works on any status
|
|
24
|
+
(`success` / `failed` / `pending`) — use this when a customer
|
|
25
|
+
reports a missed or unprocessed event.
|
|
26
|
+
- Types exported from the package root: `WebhookEvent`,
|
|
27
|
+
`WebhookEventEndpoint`, `WebhookEventList`, `WebhookEventStatus`,
|
|
28
|
+
`ListWebhookEventsParams`.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- `webhookEvents.list` now normalizes the legacy backend response
|
|
33
|
+
(`{ events, total, page, limit, pages }`) into the standard
|
|
34
|
+
`{ data, meta: { page, limit, total, totalPages } }` paginated shape
|
|
35
|
+
used by every other SDK resource. Previously the cast-only
|
|
36
|
+
implementation returned `result.data === undefined` against the real
|
|
37
|
+
backend; tests had been mocking the post-normalization shape and
|
|
38
|
+
hid the bug.
|
|
39
|
+
|
|
6
40
|
## [0.5.0] — 2026-05-01
|
|
7
41
|
|
|
8
42
|
### Added
|
package/README.md
CHANGED
|
@@ -167,7 +167,9 @@ const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 })
|
|
|
167
167
|
|
|
168
168
|
## Products
|
|
169
169
|
|
|
170
|
-
Discover products and customize the per-product portal experience (B2B2C
|
|
170
|
+
Discover products and customize the per-product portal experience (B2B2C).
|
|
171
|
+
|
|
172
|
+
`portalConfig.*` methods accept `productId` as either the product UUID (preferred — same identifier returned by `list()` and webhook payloads) or the legacy numeric id (Garu v0.10.0+).
|
|
171
173
|
|
|
172
174
|
| Method | Description |
|
|
173
175
|
| ----------------------------------- | ----------------------------------------------------------------- |
|
|
@@ -180,14 +182,16 @@ Discover products and customize the per-product portal experience (B2B2C, v0.8.0
|
|
|
180
182
|
|
|
181
183
|
```ts
|
|
182
184
|
// SaaS de coaching: per-coach branding under one Seller account
|
|
183
|
-
await garu.products.portalConfig.set(
|
|
185
|
+
await garu.products.portalConfig.set('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
184
186
|
businessName: 'Coach Maria — Corrida & Trilha',
|
|
185
187
|
primaryColor: '#257264',
|
|
186
188
|
logoUrl: 'https://cdn.exemplo.com/coaches/maria.png',
|
|
187
189
|
});
|
|
188
190
|
|
|
189
191
|
// Pass `null` on a field to inherit from the seller-level config
|
|
190
|
-
await garu.products.portalConfig.patch(
|
|
192
|
+
await garu.products.portalConfig.patch('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
193
|
+
primaryColor: null,
|
|
194
|
+
});
|
|
191
195
|
```
|
|
192
196
|
|
|
193
197
|
## Scheduled charges
|
package/dist/index.cjs
CHANGED
|
@@ -475,11 +475,11 @@ var ProductPortalConfigResource = class {
|
|
|
475
475
|
* portal config).
|
|
476
476
|
*
|
|
477
477
|
* @example
|
|
478
|
-
* const cfg = await garu.products.portalConfig.get(
|
|
478
|
+
* const cfg = await garu.products.portalConfig.get('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
479
479
|
*/
|
|
480
480
|
async get(productId) {
|
|
481
481
|
return this.http.call(
|
|
482
|
-
(signal) => this.http.client.GET(`/api/products/${productId}/portal-config`, {
|
|
482
|
+
(signal) => this.http.client.GET(`/api/products/${encodeURIComponent(String(productId))}/portal-config`, {
|
|
483
483
|
signal
|
|
484
484
|
}).then((r) => r)
|
|
485
485
|
);
|
|
@@ -491,7 +491,7 @@ var ProductPortalConfigResource = class {
|
|
|
491
491
|
* value. Use `clear` to reset everything.
|
|
492
492
|
*
|
|
493
493
|
* @example
|
|
494
|
-
* await garu.products.portalConfig.set(
|
|
494
|
+
* await garu.products.portalConfig.set('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
495
495
|
* businessName: 'Coach Maria — Corrida & Trilha',
|
|
496
496
|
* primaryColor: '#257264',
|
|
497
497
|
* logoUrl: 'https://cdn.atletia.com.br/coaches/maria.png'
|
|
@@ -499,7 +499,7 @@ var ProductPortalConfigResource = class {
|
|
|
499
499
|
*/
|
|
500
500
|
async set(productId, params) {
|
|
501
501
|
return this.http.call(
|
|
502
|
-
(signal) => this.http.client.POST(`/api/products/${productId}/portal-config`, {
|
|
502
|
+
(signal) => this.http.client.POST(`/api/products/${encodeURIComponent(String(productId))}/portal-config`, {
|
|
503
503
|
body: params,
|
|
504
504
|
signal
|
|
505
505
|
}).then((r) => r)
|
|
@@ -508,7 +508,7 @@ var ProductPortalConfigResource = class {
|
|
|
508
508
|
/** Same merge semantics as `set` — alias for HTTP-PATCH-prefering callers. */
|
|
509
509
|
async patch(productId, params) {
|
|
510
510
|
return this.http.call(
|
|
511
|
-
(signal) => this.http.client.PATCH(`/api/products/${productId}/portal-config`, {
|
|
511
|
+
(signal) => this.http.client.PATCH(`/api/products/${encodeURIComponent(String(productId))}/portal-config`, {
|
|
512
512
|
body: params,
|
|
513
513
|
signal
|
|
514
514
|
}).then((r) => r)
|
|
@@ -520,11 +520,11 @@ var ProductPortalConfigResource = class {
|
|
|
520
520
|
* deleted, `{ removed: false }` when there was nothing to remove.
|
|
521
521
|
*
|
|
522
522
|
* @example
|
|
523
|
-
* await garu.products.portalConfig.clear(
|
|
523
|
+
* await garu.products.portalConfig.clear('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
524
524
|
*/
|
|
525
525
|
async clear(productId) {
|
|
526
526
|
return this.http.call(
|
|
527
|
-
(signal) => this.http.client.DELETE(`/api/products/${productId}/portal-config`, {
|
|
527
|
+
(signal) => this.http.client.DELETE(`/api/products/${encodeURIComponent(String(productId))}/portal-config`, {
|
|
528
528
|
signal
|
|
529
529
|
}).then((r) => r)
|
|
530
530
|
);
|
|
@@ -829,6 +829,90 @@ var ScheduledCharges = class {
|
|
|
829
829
|
);
|
|
830
830
|
}
|
|
831
831
|
};
|
|
832
|
+
|
|
833
|
+
// src/resources/webhook-events.ts
|
|
834
|
+
var WebhookEvents = class {
|
|
835
|
+
constructor(http) {
|
|
836
|
+
this.http = http;
|
|
837
|
+
}
|
|
838
|
+
http;
|
|
839
|
+
/**
|
|
840
|
+
* List webhook events for the authenticated seller, newest first.
|
|
841
|
+
* Filter by delivery `status`, by Garu `eventType`, and/or by the
|
|
842
|
+
* destination `endpointId`.
|
|
843
|
+
*
|
|
844
|
+
* @example
|
|
845
|
+
* // Surface anything that didn't make it through
|
|
846
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 50 });
|
|
847
|
+
*
|
|
848
|
+
* @example
|
|
849
|
+
* // Inspect every paid-charge delivery for a specific endpoint
|
|
850
|
+
* const paidDeliveries = await garu.webhookEvents.list({
|
|
851
|
+
* endpointId: 17,
|
|
852
|
+
* eventType: 'transaction.payment.paid'
|
|
853
|
+
* });
|
|
854
|
+
*/
|
|
855
|
+
async list(params = {}) {
|
|
856
|
+
const qs = new URLSearchParams();
|
|
857
|
+
if (params.page !== void 0) qs.set("page", String(params.page));
|
|
858
|
+
if (params.limit !== void 0) qs.set("limit", String(params.limit));
|
|
859
|
+
if (params.status) qs.set("status", params.status);
|
|
860
|
+
if (params.eventType) qs.set("event_type", params.eventType);
|
|
861
|
+
if (params.endpointId !== void 0) qs.set("endpoint_id", String(params.endpointId));
|
|
862
|
+
const query = qs.toString();
|
|
863
|
+
const url = `/api/webhook-events${query ? `?${query}` : ""}`;
|
|
864
|
+
const raw = await this.http.call(
|
|
865
|
+
(signal) => this.http.client.GET(url, { signal }).then(
|
|
866
|
+
(r) => r
|
|
867
|
+
)
|
|
868
|
+
);
|
|
869
|
+
return {
|
|
870
|
+
data: raw.events,
|
|
871
|
+
meta: {
|
|
872
|
+
page: raw.page,
|
|
873
|
+
limit: raw.limit,
|
|
874
|
+
total: raw.total,
|
|
875
|
+
totalPages: raw.pages
|
|
876
|
+
}
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Fetch one webhook event by numeric ID — includes the full payload, the
|
|
881
|
+
* embedded endpoint snapshot, and the most recent response status/body.
|
|
882
|
+
*
|
|
883
|
+
* @example
|
|
884
|
+
* const event = await garu.webhookEvents.get(42);
|
|
885
|
+
* if (event.status === 'failed') {
|
|
886
|
+
* console.log(event.responseStatus, event.responseBody);
|
|
887
|
+
* }
|
|
888
|
+
*/
|
|
889
|
+
async get(id) {
|
|
890
|
+
return this.http.call(
|
|
891
|
+
(signal) => this.http.client.GET(`/api/webhook-events/${id}`, { signal }).then(
|
|
892
|
+
(r) => r
|
|
893
|
+
)
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* Re-deliver a webhook event by ID. Resets it to `pending`, clears the
|
|
898
|
+
* retry schedule, and triggers an immediate delivery attempt. Works on
|
|
899
|
+
* any status (`success`, `failed`, `pending`) — use this when a
|
|
900
|
+
* customer reports a missed or unprocessed event.
|
|
901
|
+
*
|
|
902
|
+
* @example
|
|
903
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
|
|
904
|
+
* for (const event of failed.data) {
|
|
905
|
+
* await garu.webhookEvents.retry(event.id);
|
|
906
|
+
* }
|
|
907
|
+
*/
|
|
908
|
+
async retry(id) {
|
|
909
|
+
return this.http.call(
|
|
910
|
+
(signal) => this.http.client.POST(`/api/webhook-events/${id}/retry`, { signal }).then(
|
|
911
|
+
(r) => r
|
|
912
|
+
)
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
};
|
|
832
916
|
var webhooks = {
|
|
833
917
|
verify(params) {
|
|
834
918
|
const { signature, secret, payload } = params;
|
|
@@ -888,13 +972,14 @@ function parseSignatureHeader(header) {
|
|
|
888
972
|
var DEFAULT_BASE_URL = "https://garu.com.br";
|
|
889
973
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
890
974
|
var DEFAULT_MAX_RETRIES = 2;
|
|
891
|
-
var SDK_VERSION = "0.
|
|
975
|
+
var SDK_VERSION = "0.11.0";
|
|
892
976
|
var Garu = class {
|
|
893
977
|
charges;
|
|
894
978
|
customers;
|
|
895
979
|
meta;
|
|
896
980
|
products;
|
|
897
981
|
scheduledCharges;
|
|
982
|
+
webhookEvents;
|
|
898
983
|
/**
|
|
899
984
|
* Webhook helpers. Available both as an instance member and as a static —
|
|
900
985
|
* `Garu.webhooks.verify(...)` works without constructing a client.
|
|
@@ -915,6 +1000,7 @@ var Garu = class {
|
|
|
915
1000
|
this.meta = new Meta(http);
|
|
916
1001
|
this.products = new Products(http);
|
|
917
1002
|
this.scheduledCharges = new ScheduledCharges(http);
|
|
1003
|
+
this.webhookEvents = new WebhookEvents(http);
|
|
918
1004
|
}
|
|
919
1005
|
};
|
|
920
1006
|
|
package/dist/index.d.cts
CHANGED
|
@@ -555,6 +555,61 @@ interface PaymentMethodExpiredPayload {
|
|
|
555
555
|
cardBrand: string;
|
|
556
556
|
expiresAt: string;
|
|
557
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* Delivery state of an outbound webhook event.
|
|
560
|
+
*
|
|
561
|
+
* - `pending` — queued or scheduled for a future retry (e.g. exponential backoff).
|
|
562
|
+
* - `success` — endpoint returned 2xx.
|
|
563
|
+
* - `failed` — endpoint exhausted retries or returned a non-2xx the gateway
|
|
564
|
+
* refuses to retry. Trigger a manual retry with `webhookEvents.retry(id)`.
|
|
565
|
+
*/
|
|
566
|
+
type WebhookEventStatus = 'pending' | 'success' | 'failed';
|
|
567
|
+
/**
|
|
568
|
+
* Minimal endpoint info embedded on every event row, so dashboards can
|
|
569
|
+
* render destination URL + description without a second lookup.
|
|
570
|
+
*/
|
|
571
|
+
interface WebhookEventEndpoint {
|
|
572
|
+
id: number;
|
|
573
|
+
url: string;
|
|
574
|
+
description: string | null;
|
|
575
|
+
enabled: boolean;
|
|
576
|
+
events: string[];
|
|
577
|
+
[key: string]: unknown;
|
|
578
|
+
}
|
|
579
|
+
interface WebhookEvent {
|
|
580
|
+
id: number;
|
|
581
|
+
endpointId: number;
|
|
582
|
+
/** Eager-loaded endpoint snapshot. */
|
|
583
|
+
webhookEndpoint: WebhookEventEndpoint;
|
|
584
|
+
/** Garu event type, e.g. `transaction.payment.paid`. */
|
|
585
|
+
eventType: string;
|
|
586
|
+
/** Full JSON payload the gateway POSTed (or will POST) to `webhookEndpoint.url`. */
|
|
587
|
+
payload: Record<string, unknown>;
|
|
588
|
+
status: WebhookEventStatus;
|
|
589
|
+
/** Number of delivery attempts so far. */
|
|
590
|
+
attempts: number;
|
|
591
|
+
/** ISO-8601. Null if no attempt has fired yet. */
|
|
592
|
+
lastAttemptAt: string | null;
|
|
593
|
+
/** ISO-8601. Null when terminal (`success`/`failed`) or not scheduled yet. */
|
|
594
|
+
nextRetryAt: string | null;
|
|
595
|
+
/** HTTP status returned by the endpoint on the most recent attempt. */
|
|
596
|
+
responseStatus: number | null;
|
|
597
|
+
/** Response body from the most recent attempt, truncated by the gateway. */
|
|
598
|
+
responseBody: string | null;
|
|
599
|
+
createdAt: string;
|
|
600
|
+
[key: string]: unknown;
|
|
601
|
+
}
|
|
602
|
+
type WebhookEventList = PaginatedList<WebhookEvent>;
|
|
603
|
+
interface ListWebhookEventsParams {
|
|
604
|
+
page?: number;
|
|
605
|
+
limit?: number;
|
|
606
|
+
/** Filter by delivery state. */
|
|
607
|
+
status?: WebhookEventStatus;
|
|
608
|
+
/** Filter by Garu event type, e.g. `transaction.payment.paid`. */
|
|
609
|
+
eventType?: string;
|
|
610
|
+
/** Filter by the destination endpoint that should receive (or received) the event. */
|
|
611
|
+
endpointId?: number;
|
|
612
|
+
}
|
|
558
613
|
/**
|
|
559
614
|
* Per-product portal customization (Atletia coach-as-product modeling and
|
|
560
615
|
* any other B2B2C platform). `null` fields inherit from the seller-level
|
|
@@ -776,9 +831,13 @@ declare class Meta {
|
|
|
776
831
|
}
|
|
777
832
|
|
|
778
833
|
/**
|
|
779
|
-
* Per-product portal customization
|
|
780
|
-
*
|
|
781
|
-
*
|
|
834
|
+
* Per-product portal customization. Used by B2B2C platforms that model
|
|
835
|
+
* their professionals/coaches as Products under a single seller and want
|
|
836
|
+
* per-product branding on the customer payment + portal pages.
|
|
837
|
+
*
|
|
838
|
+
* `productId` accepts either the product UUID (preferred — same identifier
|
|
839
|
+
* returned by `garu.products.list()` and webhook payloads) or the legacy
|
|
840
|
+
* numeric id. UUID support added in Garu v0.10.0.
|
|
782
841
|
*/
|
|
783
842
|
declare class ProductPortalConfigResource {
|
|
784
843
|
private readonly http;
|
|
@@ -789,9 +848,9 @@ declare class ProductPortalConfigResource {
|
|
|
789
848
|
* portal config).
|
|
790
849
|
*
|
|
791
850
|
* @example
|
|
792
|
-
* const cfg = await garu.products.portalConfig.get(
|
|
851
|
+
* const cfg = await garu.products.portalConfig.get('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
793
852
|
*/
|
|
794
|
-
get(productId: number): Promise<ProductPortalConfig | null>;
|
|
853
|
+
get(productId: string | number): Promise<ProductPortalConfig | null>;
|
|
795
854
|
/**
|
|
796
855
|
* Create or merge the portal customization (idempotent upsert). Both
|
|
797
856
|
* `set` and `patch` have the same merge semantics — only fields present
|
|
@@ -799,24 +858,24 @@ declare class ProductPortalConfigResource {
|
|
|
799
858
|
* value. Use `clear` to reset everything.
|
|
800
859
|
*
|
|
801
860
|
* @example
|
|
802
|
-
* await garu.products.portalConfig.set(
|
|
861
|
+
* await garu.products.portalConfig.set('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
803
862
|
* businessName: 'Coach Maria — Corrida & Trilha',
|
|
804
863
|
* primaryColor: '#257264',
|
|
805
864
|
* logoUrl: 'https://cdn.atletia.com.br/coaches/maria.png'
|
|
806
865
|
* });
|
|
807
866
|
*/
|
|
808
|
-
set(productId: number, params: SetProductPortalConfigParams): Promise<ProductPortalConfig>;
|
|
867
|
+
set(productId: string | number, params: SetProductPortalConfigParams): Promise<ProductPortalConfig>;
|
|
809
868
|
/** Same merge semantics as `set` — alias for HTTP-PATCH-prefering callers. */
|
|
810
|
-
patch(productId: number, params: SetProductPortalConfigParams): Promise<ProductPortalConfig>;
|
|
869
|
+
patch(productId: string | number, params: SetProductPortalConfigParams): Promise<ProductPortalConfig>;
|
|
811
870
|
/**
|
|
812
871
|
* Remove the per-product config. The product falls back to the
|
|
813
872
|
* seller-level portal config. Returns `{ removed: true }` when a row was
|
|
814
873
|
* deleted, `{ removed: false }` when there was nothing to remove.
|
|
815
874
|
*
|
|
816
875
|
* @example
|
|
817
|
-
* await garu.products.portalConfig.clear(
|
|
876
|
+
* await garu.products.portalConfig.clear('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
818
877
|
*/
|
|
819
|
-
clear(productId: number): Promise<{
|
|
878
|
+
clear(productId: string | number): Promise<{
|
|
820
879
|
removed: boolean;
|
|
821
880
|
}>;
|
|
822
881
|
}
|
|
@@ -1014,6 +1073,64 @@ declare class ScheduledCharges {
|
|
|
1014
1073
|
listAttempts(id: string, params?: ListScheduledChargeAttemptsParams): Promise<ScheduledChargeAttemptList>;
|
|
1015
1074
|
}
|
|
1016
1075
|
|
|
1076
|
+
/**
|
|
1077
|
+
* Webhook events — the seller-facing delivery log for outbound webhooks.
|
|
1078
|
+
*
|
|
1079
|
+
* Every time the gateway fires a webhook (e.g. `transaction.payment.paid`,
|
|
1080
|
+
* `scheduled_charge.cycle_failed`), it persists one row per destination
|
|
1081
|
+
* endpoint with the full payload, the HTTP outcome, and the retry schedule.
|
|
1082
|
+
* Use this resource to audit deliveries from the seller's API key — the
|
|
1083
|
+
* canonical "did my customer's endpoint actually receive event X?" workflow.
|
|
1084
|
+
*
|
|
1085
|
+
* Webhook endpoint *configuration* (URL, subscribed events, secret) is still
|
|
1086
|
+
* dashboard-only — this resource only covers the event log + manual retries.
|
|
1087
|
+
*/
|
|
1088
|
+
declare class WebhookEvents {
|
|
1089
|
+
private readonly http;
|
|
1090
|
+
constructor(http: HttpClient);
|
|
1091
|
+
/**
|
|
1092
|
+
* List webhook events for the authenticated seller, newest first.
|
|
1093
|
+
* Filter by delivery `status`, by Garu `eventType`, and/or by the
|
|
1094
|
+
* destination `endpointId`.
|
|
1095
|
+
*
|
|
1096
|
+
* @example
|
|
1097
|
+
* // Surface anything that didn't make it through
|
|
1098
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 50 });
|
|
1099
|
+
*
|
|
1100
|
+
* @example
|
|
1101
|
+
* // Inspect every paid-charge delivery for a specific endpoint
|
|
1102
|
+
* const paidDeliveries = await garu.webhookEvents.list({
|
|
1103
|
+
* endpointId: 17,
|
|
1104
|
+
* eventType: 'transaction.payment.paid'
|
|
1105
|
+
* });
|
|
1106
|
+
*/
|
|
1107
|
+
list(params?: ListWebhookEventsParams): Promise<WebhookEventList>;
|
|
1108
|
+
/**
|
|
1109
|
+
* Fetch one webhook event by numeric ID — includes the full payload, the
|
|
1110
|
+
* embedded endpoint snapshot, and the most recent response status/body.
|
|
1111
|
+
*
|
|
1112
|
+
* @example
|
|
1113
|
+
* const event = await garu.webhookEvents.get(42);
|
|
1114
|
+
* if (event.status === 'failed') {
|
|
1115
|
+
* console.log(event.responseStatus, event.responseBody);
|
|
1116
|
+
* }
|
|
1117
|
+
*/
|
|
1118
|
+
get(id: number): Promise<WebhookEvent>;
|
|
1119
|
+
/**
|
|
1120
|
+
* Re-deliver a webhook event by ID. Resets it to `pending`, clears the
|
|
1121
|
+
* retry schedule, and triggers an immediate delivery attempt. Works on
|
|
1122
|
+
* any status (`success`, `failed`, `pending`) — use this when a
|
|
1123
|
+
* customer reports a missed or unprocessed event.
|
|
1124
|
+
*
|
|
1125
|
+
* @example
|
|
1126
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
|
|
1127
|
+
* for (const event of failed.data) {
|
|
1128
|
+
* await garu.webhookEvents.retry(event.id);
|
|
1129
|
+
* }
|
|
1130
|
+
*/
|
|
1131
|
+
retry(id: number): Promise<WebhookEvent>;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1017
1134
|
interface GaruOptions {
|
|
1018
1135
|
/**
|
|
1019
1136
|
* Your Garu API key. `sk_live_…` for production, `sk_test_…` for test mode.
|
|
@@ -1054,6 +1171,7 @@ declare class Garu {
|
|
|
1054
1171
|
readonly meta: Meta;
|
|
1055
1172
|
readonly products: Products;
|
|
1056
1173
|
readonly scheduledCharges: ScheduledCharges;
|
|
1174
|
+
readonly webhookEvents: WebhookEvents;
|
|
1057
1175
|
/**
|
|
1058
1176
|
* Webhook helpers. Available both as an instance member and as a static —
|
|
1059
1177
|
* `Garu.webhooks.verify(...)` works without constructing a client.
|
|
@@ -1112,4 +1230,4 @@ declare class GaruServerError extends GaruAPIError {
|
|
|
1112
1230
|
constructor(message: string, status: number, requestId: string | null, body: unknown);
|
|
1113
1231
|
}
|
|
1114
1232
|
|
|
1115
|
-
export { type CancelAtPeriodEndScheduledChargeParams, type CancelRecurrenceScheduledChargeParams, type CardInfo, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type ListChargesParams, type ListCustomersParams, type ListProductsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethod, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetProductPortalConfigParams, type UpdateCustomerParams, type VerifiedWebhook, type VerifyWebhookParams, type WirePaymentMethodId, webhooks };
|
|
1233
|
+
export { type CancelAtPeriodEndScheduledChargeParams, type CancelRecurrenceScheduledChargeParams, type CardInfo, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type ListChargesParams, type ListCustomersParams, type ListProductsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type ListWebhookEventsParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethod, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetProductPortalConfigParams, type UpdateCustomerParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, type WirePaymentMethodId, webhooks };
|
package/dist/index.d.ts
CHANGED
|
@@ -555,6 +555,61 @@ interface PaymentMethodExpiredPayload {
|
|
|
555
555
|
cardBrand: string;
|
|
556
556
|
expiresAt: string;
|
|
557
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* Delivery state of an outbound webhook event.
|
|
560
|
+
*
|
|
561
|
+
* - `pending` — queued or scheduled for a future retry (e.g. exponential backoff).
|
|
562
|
+
* - `success` — endpoint returned 2xx.
|
|
563
|
+
* - `failed` — endpoint exhausted retries or returned a non-2xx the gateway
|
|
564
|
+
* refuses to retry. Trigger a manual retry with `webhookEvents.retry(id)`.
|
|
565
|
+
*/
|
|
566
|
+
type WebhookEventStatus = 'pending' | 'success' | 'failed';
|
|
567
|
+
/**
|
|
568
|
+
* Minimal endpoint info embedded on every event row, so dashboards can
|
|
569
|
+
* render destination URL + description without a second lookup.
|
|
570
|
+
*/
|
|
571
|
+
interface WebhookEventEndpoint {
|
|
572
|
+
id: number;
|
|
573
|
+
url: string;
|
|
574
|
+
description: string | null;
|
|
575
|
+
enabled: boolean;
|
|
576
|
+
events: string[];
|
|
577
|
+
[key: string]: unknown;
|
|
578
|
+
}
|
|
579
|
+
interface WebhookEvent {
|
|
580
|
+
id: number;
|
|
581
|
+
endpointId: number;
|
|
582
|
+
/** Eager-loaded endpoint snapshot. */
|
|
583
|
+
webhookEndpoint: WebhookEventEndpoint;
|
|
584
|
+
/** Garu event type, e.g. `transaction.payment.paid`. */
|
|
585
|
+
eventType: string;
|
|
586
|
+
/** Full JSON payload the gateway POSTed (or will POST) to `webhookEndpoint.url`. */
|
|
587
|
+
payload: Record<string, unknown>;
|
|
588
|
+
status: WebhookEventStatus;
|
|
589
|
+
/** Number of delivery attempts so far. */
|
|
590
|
+
attempts: number;
|
|
591
|
+
/** ISO-8601. Null if no attempt has fired yet. */
|
|
592
|
+
lastAttemptAt: string | null;
|
|
593
|
+
/** ISO-8601. Null when terminal (`success`/`failed`) or not scheduled yet. */
|
|
594
|
+
nextRetryAt: string | null;
|
|
595
|
+
/** HTTP status returned by the endpoint on the most recent attempt. */
|
|
596
|
+
responseStatus: number | null;
|
|
597
|
+
/** Response body from the most recent attempt, truncated by the gateway. */
|
|
598
|
+
responseBody: string | null;
|
|
599
|
+
createdAt: string;
|
|
600
|
+
[key: string]: unknown;
|
|
601
|
+
}
|
|
602
|
+
type WebhookEventList = PaginatedList<WebhookEvent>;
|
|
603
|
+
interface ListWebhookEventsParams {
|
|
604
|
+
page?: number;
|
|
605
|
+
limit?: number;
|
|
606
|
+
/** Filter by delivery state. */
|
|
607
|
+
status?: WebhookEventStatus;
|
|
608
|
+
/** Filter by Garu event type, e.g. `transaction.payment.paid`. */
|
|
609
|
+
eventType?: string;
|
|
610
|
+
/** Filter by the destination endpoint that should receive (or received) the event. */
|
|
611
|
+
endpointId?: number;
|
|
612
|
+
}
|
|
558
613
|
/**
|
|
559
614
|
* Per-product portal customization (Atletia coach-as-product modeling and
|
|
560
615
|
* any other B2B2C platform). `null` fields inherit from the seller-level
|
|
@@ -776,9 +831,13 @@ declare class Meta {
|
|
|
776
831
|
}
|
|
777
832
|
|
|
778
833
|
/**
|
|
779
|
-
* Per-product portal customization
|
|
780
|
-
*
|
|
781
|
-
*
|
|
834
|
+
* Per-product portal customization. Used by B2B2C platforms that model
|
|
835
|
+
* their professionals/coaches as Products under a single seller and want
|
|
836
|
+
* per-product branding on the customer payment + portal pages.
|
|
837
|
+
*
|
|
838
|
+
* `productId` accepts either the product UUID (preferred — same identifier
|
|
839
|
+
* returned by `garu.products.list()` and webhook payloads) or the legacy
|
|
840
|
+
* numeric id. UUID support added in Garu v0.10.0.
|
|
782
841
|
*/
|
|
783
842
|
declare class ProductPortalConfigResource {
|
|
784
843
|
private readonly http;
|
|
@@ -789,9 +848,9 @@ declare class ProductPortalConfigResource {
|
|
|
789
848
|
* portal config).
|
|
790
849
|
*
|
|
791
850
|
* @example
|
|
792
|
-
* const cfg = await garu.products.portalConfig.get(
|
|
851
|
+
* const cfg = await garu.products.portalConfig.get('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
793
852
|
*/
|
|
794
|
-
get(productId: number): Promise<ProductPortalConfig | null>;
|
|
853
|
+
get(productId: string | number): Promise<ProductPortalConfig | null>;
|
|
795
854
|
/**
|
|
796
855
|
* Create or merge the portal customization (idempotent upsert). Both
|
|
797
856
|
* `set` and `patch` have the same merge semantics — only fields present
|
|
@@ -799,24 +858,24 @@ declare class ProductPortalConfigResource {
|
|
|
799
858
|
* value. Use `clear` to reset everything.
|
|
800
859
|
*
|
|
801
860
|
* @example
|
|
802
|
-
* await garu.products.portalConfig.set(
|
|
861
|
+
* await garu.products.portalConfig.set('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
803
862
|
* businessName: 'Coach Maria — Corrida & Trilha',
|
|
804
863
|
* primaryColor: '#257264',
|
|
805
864
|
* logoUrl: 'https://cdn.atletia.com.br/coaches/maria.png'
|
|
806
865
|
* });
|
|
807
866
|
*/
|
|
808
|
-
set(productId: number, params: SetProductPortalConfigParams): Promise<ProductPortalConfig>;
|
|
867
|
+
set(productId: string | number, params: SetProductPortalConfigParams): Promise<ProductPortalConfig>;
|
|
809
868
|
/** Same merge semantics as `set` — alias for HTTP-PATCH-prefering callers. */
|
|
810
|
-
patch(productId: number, params: SetProductPortalConfigParams): Promise<ProductPortalConfig>;
|
|
869
|
+
patch(productId: string | number, params: SetProductPortalConfigParams): Promise<ProductPortalConfig>;
|
|
811
870
|
/**
|
|
812
871
|
* Remove the per-product config. The product falls back to the
|
|
813
872
|
* seller-level portal config. Returns `{ removed: true }` when a row was
|
|
814
873
|
* deleted, `{ removed: false }` when there was nothing to remove.
|
|
815
874
|
*
|
|
816
875
|
* @example
|
|
817
|
-
* await garu.products.portalConfig.clear(
|
|
876
|
+
* await garu.products.portalConfig.clear('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
818
877
|
*/
|
|
819
|
-
clear(productId: number): Promise<{
|
|
878
|
+
clear(productId: string | number): Promise<{
|
|
820
879
|
removed: boolean;
|
|
821
880
|
}>;
|
|
822
881
|
}
|
|
@@ -1014,6 +1073,64 @@ declare class ScheduledCharges {
|
|
|
1014
1073
|
listAttempts(id: string, params?: ListScheduledChargeAttemptsParams): Promise<ScheduledChargeAttemptList>;
|
|
1015
1074
|
}
|
|
1016
1075
|
|
|
1076
|
+
/**
|
|
1077
|
+
* Webhook events — the seller-facing delivery log for outbound webhooks.
|
|
1078
|
+
*
|
|
1079
|
+
* Every time the gateway fires a webhook (e.g. `transaction.payment.paid`,
|
|
1080
|
+
* `scheduled_charge.cycle_failed`), it persists one row per destination
|
|
1081
|
+
* endpoint with the full payload, the HTTP outcome, and the retry schedule.
|
|
1082
|
+
* Use this resource to audit deliveries from the seller's API key — the
|
|
1083
|
+
* canonical "did my customer's endpoint actually receive event X?" workflow.
|
|
1084
|
+
*
|
|
1085
|
+
* Webhook endpoint *configuration* (URL, subscribed events, secret) is still
|
|
1086
|
+
* dashboard-only — this resource only covers the event log + manual retries.
|
|
1087
|
+
*/
|
|
1088
|
+
declare class WebhookEvents {
|
|
1089
|
+
private readonly http;
|
|
1090
|
+
constructor(http: HttpClient);
|
|
1091
|
+
/**
|
|
1092
|
+
* List webhook events for the authenticated seller, newest first.
|
|
1093
|
+
* Filter by delivery `status`, by Garu `eventType`, and/or by the
|
|
1094
|
+
* destination `endpointId`.
|
|
1095
|
+
*
|
|
1096
|
+
* @example
|
|
1097
|
+
* // Surface anything that didn't make it through
|
|
1098
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 50 });
|
|
1099
|
+
*
|
|
1100
|
+
* @example
|
|
1101
|
+
* // Inspect every paid-charge delivery for a specific endpoint
|
|
1102
|
+
* const paidDeliveries = await garu.webhookEvents.list({
|
|
1103
|
+
* endpointId: 17,
|
|
1104
|
+
* eventType: 'transaction.payment.paid'
|
|
1105
|
+
* });
|
|
1106
|
+
*/
|
|
1107
|
+
list(params?: ListWebhookEventsParams): Promise<WebhookEventList>;
|
|
1108
|
+
/**
|
|
1109
|
+
* Fetch one webhook event by numeric ID — includes the full payload, the
|
|
1110
|
+
* embedded endpoint snapshot, and the most recent response status/body.
|
|
1111
|
+
*
|
|
1112
|
+
* @example
|
|
1113
|
+
* const event = await garu.webhookEvents.get(42);
|
|
1114
|
+
* if (event.status === 'failed') {
|
|
1115
|
+
* console.log(event.responseStatus, event.responseBody);
|
|
1116
|
+
* }
|
|
1117
|
+
*/
|
|
1118
|
+
get(id: number): Promise<WebhookEvent>;
|
|
1119
|
+
/**
|
|
1120
|
+
* Re-deliver a webhook event by ID. Resets it to `pending`, clears the
|
|
1121
|
+
* retry schedule, and triggers an immediate delivery attempt. Works on
|
|
1122
|
+
* any status (`success`, `failed`, `pending`) — use this when a
|
|
1123
|
+
* customer reports a missed or unprocessed event.
|
|
1124
|
+
*
|
|
1125
|
+
* @example
|
|
1126
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
|
|
1127
|
+
* for (const event of failed.data) {
|
|
1128
|
+
* await garu.webhookEvents.retry(event.id);
|
|
1129
|
+
* }
|
|
1130
|
+
*/
|
|
1131
|
+
retry(id: number): Promise<WebhookEvent>;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1017
1134
|
interface GaruOptions {
|
|
1018
1135
|
/**
|
|
1019
1136
|
* Your Garu API key. `sk_live_…` for production, `sk_test_…` for test mode.
|
|
@@ -1054,6 +1171,7 @@ declare class Garu {
|
|
|
1054
1171
|
readonly meta: Meta;
|
|
1055
1172
|
readonly products: Products;
|
|
1056
1173
|
readonly scheduledCharges: ScheduledCharges;
|
|
1174
|
+
readonly webhookEvents: WebhookEvents;
|
|
1057
1175
|
/**
|
|
1058
1176
|
* Webhook helpers. Available both as an instance member and as a static —
|
|
1059
1177
|
* `Garu.webhooks.verify(...)` works without constructing a client.
|
|
@@ -1112,4 +1230,4 @@ declare class GaruServerError extends GaruAPIError {
|
|
|
1112
1230
|
constructor(message: string, status: number, requestId: string | null, body: unknown);
|
|
1113
1231
|
}
|
|
1114
1232
|
|
|
1115
|
-
export { type CancelAtPeriodEndScheduledChargeParams, type CancelRecurrenceScheduledChargeParams, type CardInfo, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type ListChargesParams, type ListCustomersParams, type ListProductsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethod, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetProductPortalConfigParams, type UpdateCustomerParams, type VerifiedWebhook, type VerifyWebhookParams, type WirePaymentMethodId, webhooks };
|
|
1233
|
+
export { type CancelAtPeriodEndScheduledChargeParams, type CancelRecurrenceScheduledChargeParams, type CardInfo, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type ListChargesParams, type ListCustomersParams, type ListProductsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type ListWebhookEventsParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethod, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetProductPortalConfigParams, type UpdateCustomerParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, type WirePaymentMethodId, webhooks };
|
package/dist/index.js
CHANGED
|
@@ -469,11 +469,11 @@ var ProductPortalConfigResource = class {
|
|
|
469
469
|
* portal config).
|
|
470
470
|
*
|
|
471
471
|
* @example
|
|
472
|
-
* const cfg = await garu.products.portalConfig.get(
|
|
472
|
+
* const cfg = await garu.products.portalConfig.get('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
473
473
|
*/
|
|
474
474
|
async get(productId) {
|
|
475
475
|
return this.http.call(
|
|
476
|
-
(signal) => this.http.client.GET(`/api/products/${productId}/portal-config`, {
|
|
476
|
+
(signal) => this.http.client.GET(`/api/products/${encodeURIComponent(String(productId))}/portal-config`, {
|
|
477
477
|
signal
|
|
478
478
|
}).then((r) => r)
|
|
479
479
|
);
|
|
@@ -485,7 +485,7 @@ var ProductPortalConfigResource = class {
|
|
|
485
485
|
* value. Use `clear` to reset everything.
|
|
486
486
|
*
|
|
487
487
|
* @example
|
|
488
|
-
* await garu.products.portalConfig.set(
|
|
488
|
+
* await garu.products.portalConfig.set('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f', {
|
|
489
489
|
* businessName: 'Coach Maria — Corrida & Trilha',
|
|
490
490
|
* primaryColor: '#257264',
|
|
491
491
|
* logoUrl: 'https://cdn.atletia.com.br/coaches/maria.png'
|
|
@@ -493,7 +493,7 @@ var ProductPortalConfigResource = class {
|
|
|
493
493
|
*/
|
|
494
494
|
async set(productId, params) {
|
|
495
495
|
return this.http.call(
|
|
496
|
-
(signal) => this.http.client.POST(`/api/products/${productId}/portal-config`, {
|
|
496
|
+
(signal) => this.http.client.POST(`/api/products/${encodeURIComponent(String(productId))}/portal-config`, {
|
|
497
497
|
body: params,
|
|
498
498
|
signal
|
|
499
499
|
}).then((r) => r)
|
|
@@ -502,7 +502,7 @@ var ProductPortalConfigResource = class {
|
|
|
502
502
|
/** Same merge semantics as `set` — alias for HTTP-PATCH-prefering callers. */
|
|
503
503
|
async patch(productId, params) {
|
|
504
504
|
return this.http.call(
|
|
505
|
-
(signal) => this.http.client.PATCH(`/api/products/${productId}/portal-config`, {
|
|
505
|
+
(signal) => this.http.client.PATCH(`/api/products/${encodeURIComponent(String(productId))}/portal-config`, {
|
|
506
506
|
body: params,
|
|
507
507
|
signal
|
|
508
508
|
}).then((r) => r)
|
|
@@ -514,11 +514,11 @@ var ProductPortalConfigResource = class {
|
|
|
514
514
|
* deleted, `{ removed: false }` when there was nothing to remove.
|
|
515
515
|
*
|
|
516
516
|
* @example
|
|
517
|
-
* await garu.products.portalConfig.clear(
|
|
517
|
+
* await garu.products.portalConfig.clear('b3f2c1e8-6e4a-4b9f-9d1c-2a1f6c3d4e5f');
|
|
518
518
|
*/
|
|
519
519
|
async clear(productId) {
|
|
520
520
|
return this.http.call(
|
|
521
|
-
(signal) => this.http.client.DELETE(`/api/products/${productId}/portal-config`, {
|
|
521
|
+
(signal) => this.http.client.DELETE(`/api/products/${encodeURIComponent(String(productId))}/portal-config`, {
|
|
522
522
|
signal
|
|
523
523
|
}).then((r) => r)
|
|
524
524
|
);
|
|
@@ -823,6 +823,90 @@ var ScheduledCharges = class {
|
|
|
823
823
|
);
|
|
824
824
|
}
|
|
825
825
|
};
|
|
826
|
+
|
|
827
|
+
// src/resources/webhook-events.ts
|
|
828
|
+
var WebhookEvents = class {
|
|
829
|
+
constructor(http) {
|
|
830
|
+
this.http = http;
|
|
831
|
+
}
|
|
832
|
+
http;
|
|
833
|
+
/**
|
|
834
|
+
* List webhook events for the authenticated seller, newest first.
|
|
835
|
+
* Filter by delivery `status`, by Garu `eventType`, and/or by the
|
|
836
|
+
* destination `endpointId`.
|
|
837
|
+
*
|
|
838
|
+
* @example
|
|
839
|
+
* // Surface anything that didn't make it through
|
|
840
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 50 });
|
|
841
|
+
*
|
|
842
|
+
* @example
|
|
843
|
+
* // Inspect every paid-charge delivery for a specific endpoint
|
|
844
|
+
* const paidDeliveries = await garu.webhookEvents.list({
|
|
845
|
+
* endpointId: 17,
|
|
846
|
+
* eventType: 'transaction.payment.paid'
|
|
847
|
+
* });
|
|
848
|
+
*/
|
|
849
|
+
async list(params = {}) {
|
|
850
|
+
const qs = new URLSearchParams();
|
|
851
|
+
if (params.page !== void 0) qs.set("page", String(params.page));
|
|
852
|
+
if (params.limit !== void 0) qs.set("limit", String(params.limit));
|
|
853
|
+
if (params.status) qs.set("status", params.status);
|
|
854
|
+
if (params.eventType) qs.set("event_type", params.eventType);
|
|
855
|
+
if (params.endpointId !== void 0) qs.set("endpoint_id", String(params.endpointId));
|
|
856
|
+
const query = qs.toString();
|
|
857
|
+
const url = `/api/webhook-events${query ? `?${query}` : ""}`;
|
|
858
|
+
const raw = await this.http.call(
|
|
859
|
+
(signal) => this.http.client.GET(url, { signal }).then(
|
|
860
|
+
(r) => r
|
|
861
|
+
)
|
|
862
|
+
);
|
|
863
|
+
return {
|
|
864
|
+
data: raw.events,
|
|
865
|
+
meta: {
|
|
866
|
+
page: raw.page,
|
|
867
|
+
limit: raw.limit,
|
|
868
|
+
total: raw.total,
|
|
869
|
+
totalPages: raw.pages
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Fetch one webhook event by numeric ID — includes the full payload, the
|
|
875
|
+
* embedded endpoint snapshot, and the most recent response status/body.
|
|
876
|
+
*
|
|
877
|
+
* @example
|
|
878
|
+
* const event = await garu.webhookEvents.get(42);
|
|
879
|
+
* if (event.status === 'failed') {
|
|
880
|
+
* console.log(event.responseStatus, event.responseBody);
|
|
881
|
+
* }
|
|
882
|
+
*/
|
|
883
|
+
async get(id) {
|
|
884
|
+
return this.http.call(
|
|
885
|
+
(signal) => this.http.client.GET(`/api/webhook-events/${id}`, { signal }).then(
|
|
886
|
+
(r) => r
|
|
887
|
+
)
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Re-deliver a webhook event by ID. Resets it to `pending`, clears the
|
|
892
|
+
* retry schedule, and triggers an immediate delivery attempt. Works on
|
|
893
|
+
* any status (`success`, `failed`, `pending`) — use this when a
|
|
894
|
+
* customer reports a missed or unprocessed event.
|
|
895
|
+
*
|
|
896
|
+
* @example
|
|
897
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
|
|
898
|
+
* for (const event of failed.data) {
|
|
899
|
+
* await garu.webhookEvents.retry(event.id);
|
|
900
|
+
* }
|
|
901
|
+
*/
|
|
902
|
+
async retry(id) {
|
|
903
|
+
return this.http.call(
|
|
904
|
+
(signal) => this.http.client.POST(`/api/webhook-events/${id}/retry`, { signal }).then(
|
|
905
|
+
(r) => r
|
|
906
|
+
)
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
};
|
|
826
910
|
var webhooks = {
|
|
827
911
|
verify(params) {
|
|
828
912
|
const { signature, secret, payload } = params;
|
|
@@ -882,13 +966,14 @@ function parseSignatureHeader(header) {
|
|
|
882
966
|
var DEFAULT_BASE_URL = "https://garu.com.br";
|
|
883
967
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
884
968
|
var DEFAULT_MAX_RETRIES = 2;
|
|
885
|
-
var SDK_VERSION = "0.
|
|
969
|
+
var SDK_VERSION = "0.11.0";
|
|
886
970
|
var Garu = class {
|
|
887
971
|
charges;
|
|
888
972
|
customers;
|
|
889
973
|
meta;
|
|
890
974
|
products;
|
|
891
975
|
scheduledCharges;
|
|
976
|
+
webhookEvents;
|
|
892
977
|
/**
|
|
893
978
|
* Webhook helpers. Available both as an instance member and as a static —
|
|
894
979
|
* `Garu.webhooks.verify(...)` works without constructing a client.
|
|
@@ -909,6 +994,7 @@ var Garu = class {
|
|
|
909
994
|
this.meta = new Meta(http);
|
|
910
995
|
this.products = new Products(http);
|
|
911
996
|
this.scheduledCharges = new ScheduledCharges(http);
|
|
997
|
+
this.webhookEvents = new WebhookEvents(http);
|
|
912
998
|
}
|
|
913
999
|
};
|
|
914
1000
|
|