@garuhq/node 0.10.0 → 0.11.1
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 +49 -0
- package/dist/index.cjs +95 -4
- package/dist/index.d.cts +115 -1
- package/dist/index.d.ts +115 -1
- package/dist/index.js +95 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,55 @@
|
|
|
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.1] — 2026-05-19
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- Empty-body mutations (`webhookEvents.retry`, `scheduledCharges.resume`,
|
|
11
|
+
`customers.delete`, `products.portalConfig.clear`,
|
|
12
|
+
`scheduledCharges.clearPaymentMethod`) now send an explicit `{}` body.
|
|
13
|
+
`openapi-fetch` sets `Content-Type: application/json` as a default
|
|
14
|
+
header on every request, and the backend body-parser rejects
|
|
15
|
+
`Content-Type: json` + empty body with
|
|
16
|
+
`Body cannot be empty when content-type is set to 'application/json'`.
|
|
17
|
+
Previously these calls failed against production; the SDK's mock-fetch
|
|
18
|
+
tests didn't surface the regression because the mock never hits the
|
|
19
|
+
body-parser middleware.
|
|
20
|
+
|
|
21
|
+
## [0.11.0] — 2026-05-19
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- `webhookEvents` resource on the `Garu` client — the seller-facing
|
|
26
|
+
delivery log for outbound webhooks. Use it to audit deliveries from
|
|
27
|
+
the seller's API key, the canonical "did my customer's endpoint
|
|
28
|
+
actually receive event X?" workflow.
|
|
29
|
+
- `webhookEvents.list({ status?, eventType?, endpointId?, page?, limit? })`
|
|
30
|
+
— `GET /api/webhook-events`. Filter by delivery state
|
|
31
|
+
(`pending` / `success` / `failed`), Garu event type, or destination
|
|
32
|
+
endpoint id. Newest first.
|
|
33
|
+
- `webhookEvents.get(id)` — `GET /api/webhook-events/{id}`. Returns
|
|
34
|
+
the full payload, the embedded endpoint snapshot, and the most
|
|
35
|
+
recent response status/body.
|
|
36
|
+
- `webhookEvents.retry(id)` — `POST /api/webhook-events/{id}/retry`.
|
|
37
|
+
Resets the event to `pending`, clears the retry schedule, and
|
|
38
|
+
triggers an immediate delivery attempt. Works on any status
|
|
39
|
+
(`success` / `failed` / `pending`) — use this when a customer
|
|
40
|
+
reports a missed or unprocessed event.
|
|
41
|
+
- Types exported from the package root: `WebhookEvent`,
|
|
42
|
+
`WebhookEventEndpoint`, `WebhookEventList`, `WebhookEventStatus`,
|
|
43
|
+
`ListWebhookEventsParams`.
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- `webhookEvents.list` now normalizes the legacy backend response
|
|
48
|
+
(`{ events, total, page, limit, pages }`) into the standard
|
|
49
|
+
`{ data, meta: { page, limit, total, totalPages } }` paginated shape
|
|
50
|
+
used by every other SDK resource. Previously the cast-only
|
|
51
|
+
implementation returned `result.data === undefined` against the real
|
|
52
|
+
backend; tests had been mocking the post-normalization shape and
|
|
53
|
+
hid the bug.
|
|
54
|
+
|
|
6
55
|
## [0.5.0] — 2026-05-01
|
|
7
56
|
|
|
8
57
|
### Added
|
package/dist/index.cjs
CHANGED
|
@@ -435,9 +435,10 @@ var Customers = class {
|
|
|
435
435
|
*/
|
|
436
436
|
async delete(id) {
|
|
437
437
|
await this.http.call(
|
|
438
|
-
(signal) => this.http.client.DELETE(`/api/customers/${id}`, {
|
|
439
|
-
|
|
440
|
-
|
|
438
|
+
(signal) => this.http.client.DELETE(`/api/customers/${id}`, {
|
|
439
|
+
body: {},
|
|
440
|
+
signal
|
|
441
|
+
}).then((r) => r)
|
|
441
442
|
);
|
|
442
443
|
}
|
|
443
444
|
};
|
|
@@ -525,6 +526,7 @@ var ProductPortalConfigResource = class {
|
|
|
525
526
|
async clear(productId) {
|
|
526
527
|
return this.http.call(
|
|
527
528
|
(signal) => this.http.client.DELETE(`/api/products/${encodeURIComponent(String(productId))}/portal-config`, {
|
|
529
|
+
body: {},
|
|
528
530
|
signal
|
|
529
531
|
}).then((r) => r)
|
|
530
532
|
);
|
|
@@ -700,6 +702,7 @@ var ScheduledCharges = class {
|
|
|
700
702
|
async resume(id) {
|
|
701
703
|
return this.http.call(
|
|
702
704
|
(signal) => this.http.client.POST(`/api/scheduled-charges/${id}/resume`, {
|
|
705
|
+
body: {},
|
|
703
706
|
signal
|
|
704
707
|
}).then((r) => r)
|
|
705
708
|
);
|
|
@@ -798,6 +801,7 @@ var ScheduledCharges = class {
|
|
|
798
801
|
async clearPaymentMethod(id) {
|
|
799
802
|
return this.http.call(
|
|
800
803
|
(signal) => this.http.client.DELETE(`/api/scheduled-charges/${id}/payment-method`, {
|
|
804
|
+
body: {},
|
|
801
805
|
signal
|
|
802
806
|
}).then((r) => r)
|
|
803
807
|
);
|
|
@@ -829,6 +833,91 @@ var ScheduledCharges = class {
|
|
|
829
833
|
);
|
|
830
834
|
}
|
|
831
835
|
};
|
|
836
|
+
|
|
837
|
+
// src/resources/webhook-events.ts
|
|
838
|
+
var WebhookEvents = class {
|
|
839
|
+
constructor(http) {
|
|
840
|
+
this.http = http;
|
|
841
|
+
}
|
|
842
|
+
http;
|
|
843
|
+
/**
|
|
844
|
+
* List webhook events for the authenticated seller, newest first.
|
|
845
|
+
* Filter by delivery `status`, by Garu `eventType`, and/or by the
|
|
846
|
+
* destination `endpointId`.
|
|
847
|
+
*
|
|
848
|
+
* @example
|
|
849
|
+
* // Surface anything that didn't make it through
|
|
850
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 50 });
|
|
851
|
+
*
|
|
852
|
+
* @example
|
|
853
|
+
* // Inspect every paid-charge delivery for a specific endpoint
|
|
854
|
+
* const paidDeliveries = await garu.webhookEvents.list({
|
|
855
|
+
* endpointId: 17,
|
|
856
|
+
* eventType: 'transaction.payment.paid'
|
|
857
|
+
* });
|
|
858
|
+
*/
|
|
859
|
+
async list(params = {}) {
|
|
860
|
+
const qs = new URLSearchParams();
|
|
861
|
+
if (params.page !== void 0) qs.set("page", String(params.page));
|
|
862
|
+
if (params.limit !== void 0) qs.set("limit", String(params.limit));
|
|
863
|
+
if (params.status) qs.set("status", params.status);
|
|
864
|
+
if (params.eventType) qs.set("event_type", params.eventType);
|
|
865
|
+
if (params.endpointId !== void 0) qs.set("endpoint_id", String(params.endpointId));
|
|
866
|
+
const query = qs.toString();
|
|
867
|
+
const url = `/api/webhook-events${query ? `?${query}` : ""}`;
|
|
868
|
+
const raw = await this.http.call(
|
|
869
|
+
(signal) => this.http.client.GET(url, { signal }).then(
|
|
870
|
+
(r) => r
|
|
871
|
+
)
|
|
872
|
+
);
|
|
873
|
+
return {
|
|
874
|
+
data: raw.events,
|
|
875
|
+
meta: {
|
|
876
|
+
page: raw.page,
|
|
877
|
+
limit: raw.limit,
|
|
878
|
+
total: raw.total,
|
|
879
|
+
totalPages: raw.pages
|
|
880
|
+
}
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Fetch one webhook event by numeric ID — includes the full payload, the
|
|
885
|
+
* embedded endpoint snapshot, and the most recent response status/body.
|
|
886
|
+
*
|
|
887
|
+
* @example
|
|
888
|
+
* const event = await garu.webhookEvents.get(42);
|
|
889
|
+
* if (event.status === 'failed') {
|
|
890
|
+
* console.log(event.responseStatus, event.responseBody);
|
|
891
|
+
* }
|
|
892
|
+
*/
|
|
893
|
+
async get(id) {
|
|
894
|
+
return this.http.call(
|
|
895
|
+
(signal) => this.http.client.GET(`/api/webhook-events/${id}`, { signal }).then(
|
|
896
|
+
(r) => r
|
|
897
|
+
)
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Re-deliver a webhook event by ID. Resets it to `pending`, clears the
|
|
902
|
+
* retry schedule, and triggers an immediate delivery attempt. Works on
|
|
903
|
+
* any status (`success`, `failed`, `pending`) — use this when a
|
|
904
|
+
* customer reports a missed or unprocessed event.
|
|
905
|
+
*
|
|
906
|
+
* @example
|
|
907
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
|
|
908
|
+
* for (const event of failed.data) {
|
|
909
|
+
* await garu.webhookEvents.retry(event.id);
|
|
910
|
+
* }
|
|
911
|
+
*/
|
|
912
|
+
async retry(id) {
|
|
913
|
+
return this.http.call(
|
|
914
|
+
(signal) => this.http.client.POST(`/api/webhook-events/${id}/retry`, {
|
|
915
|
+
body: {},
|
|
916
|
+
signal
|
|
917
|
+
}).then((r) => r)
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
};
|
|
832
921
|
var webhooks = {
|
|
833
922
|
verify(params) {
|
|
834
923
|
const { signature, secret, payload } = params;
|
|
@@ -888,13 +977,14 @@ function parseSignatureHeader(header) {
|
|
|
888
977
|
var DEFAULT_BASE_URL = "https://garu.com.br";
|
|
889
978
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
890
979
|
var DEFAULT_MAX_RETRIES = 2;
|
|
891
|
-
var SDK_VERSION = "0.
|
|
980
|
+
var SDK_VERSION = "0.11.1";
|
|
892
981
|
var Garu = class {
|
|
893
982
|
charges;
|
|
894
983
|
customers;
|
|
895
984
|
meta;
|
|
896
985
|
products;
|
|
897
986
|
scheduledCharges;
|
|
987
|
+
webhookEvents;
|
|
898
988
|
/**
|
|
899
989
|
* Webhook helpers. Available both as an instance member and as a static —
|
|
900
990
|
* `Garu.webhooks.verify(...)` works without constructing a client.
|
|
@@ -915,6 +1005,7 @@ var Garu = class {
|
|
|
915
1005
|
this.meta = new Meta(http);
|
|
916
1006
|
this.products = new Products(http);
|
|
917
1007
|
this.scheduledCharges = new ScheduledCharges(http);
|
|
1008
|
+
this.webhookEvents = new WebhookEvents(http);
|
|
918
1009
|
}
|
|
919
1010
|
};
|
|
920
1011
|
|
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
|
|
@@ -1018,6 +1073,64 @@ declare class ScheduledCharges {
|
|
|
1018
1073
|
listAttempts(id: string, params?: ListScheduledChargeAttemptsParams): Promise<ScheduledChargeAttemptList>;
|
|
1019
1074
|
}
|
|
1020
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
|
+
|
|
1021
1134
|
interface GaruOptions {
|
|
1022
1135
|
/**
|
|
1023
1136
|
* Your Garu API key. `sk_live_…` for production, `sk_test_…` for test mode.
|
|
@@ -1058,6 +1171,7 @@ declare class Garu {
|
|
|
1058
1171
|
readonly meta: Meta;
|
|
1059
1172
|
readonly products: Products;
|
|
1060
1173
|
readonly scheduledCharges: ScheduledCharges;
|
|
1174
|
+
readonly webhookEvents: WebhookEvents;
|
|
1061
1175
|
/**
|
|
1062
1176
|
* Webhook helpers. Available both as an instance member and as a static —
|
|
1063
1177
|
* `Garu.webhooks.verify(...)` works without constructing a client.
|
|
@@ -1116,4 +1230,4 @@ declare class GaruServerError extends GaruAPIError {
|
|
|
1116
1230
|
constructor(message: string, status: number, requestId: string | null, body: unknown);
|
|
1117
1231
|
}
|
|
1118
1232
|
|
|
1119
|
-
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
|
|
@@ -1018,6 +1073,64 @@ declare class ScheduledCharges {
|
|
|
1018
1073
|
listAttempts(id: string, params?: ListScheduledChargeAttemptsParams): Promise<ScheduledChargeAttemptList>;
|
|
1019
1074
|
}
|
|
1020
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
|
+
|
|
1021
1134
|
interface GaruOptions {
|
|
1022
1135
|
/**
|
|
1023
1136
|
* Your Garu API key. `sk_live_…` for production, `sk_test_…` for test mode.
|
|
@@ -1058,6 +1171,7 @@ declare class Garu {
|
|
|
1058
1171
|
readonly meta: Meta;
|
|
1059
1172
|
readonly products: Products;
|
|
1060
1173
|
readonly scheduledCharges: ScheduledCharges;
|
|
1174
|
+
readonly webhookEvents: WebhookEvents;
|
|
1061
1175
|
/**
|
|
1062
1176
|
* Webhook helpers. Available both as an instance member and as a static —
|
|
1063
1177
|
* `Garu.webhooks.verify(...)` works without constructing a client.
|
|
@@ -1116,4 +1230,4 @@ declare class GaruServerError extends GaruAPIError {
|
|
|
1116
1230
|
constructor(message: string, status: number, requestId: string | null, body: unknown);
|
|
1117
1231
|
}
|
|
1118
1232
|
|
|
1119
|
-
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
|
@@ -429,9 +429,10 @@ var Customers = class {
|
|
|
429
429
|
*/
|
|
430
430
|
async delete(id) {
|
|
431
431
|
await this.http.call(
|
|
432
|
-
(signal) => this.http.client.DELETE(`/api/customers/${id}`, {
|
|
433
|
-
|
|
434
|
-
|
|
432
|
+
(signal) => this.http.client.DELETE(`/api/customers/${id}`, {
|
|
433
|
+
body: {},
|
|
434
|
+
signal
|
|
435
|
+
}).then((r) => r)
|
|
435
436
|
);
|
|
436
437
|
}
|
|
437
438
|
};
|
|
@@ -519,6 +520,7 @@ var ProductPortalConfigResource = class {
|
|
|
519
520
|
async clear(productId) {
|
|
520
521
|
return this.http.call(
|
|
521
522
|
(signal) => this.http.client.DELETE(`/api/products/${encodeURIComponent(String(productId))}/portal-config`, {
|
|
523
|
+
body: {},
|
|
522
524
|
signal
|
|
523
525
|
}).then((r) => r)
|
|
524
526
|
);
|
|
@@ -694,6 +696,7 @@ var ScheduledCharges = class {
|
|
|
694
696
|
async resume(id) {
|
|
695
697
|
return this.http.call(
|
|
696
698
|
(signal) => this.http.client.POST(`/api/scheduled-charges/${id}/resume`, {
|
|
699
|
+
body: {},
|
|
697
700
|
signal
|
|
698
701
|
}).then((r) => r)
|
|
699
702
|
);
|
|
@@ -792,6 +795,7 @@ var ScheduledCharges = class {
|
|
|
792
795
|
async clearPaymentMethod(id) {
|
|
793
796
|
return this.http.call(
|
|
794
797
|
(signal) => this.http.client.DELETE(`/api/scheduled-charges/${id}/payment-method`, {
|
|
798
|
+
body: {},
|
|
795
799
|
signal
|
|
796
800
|
}).then((r) => r)
|
|
797
801
|
);
|
|
@@ -823,6 +827,91 @@ var ScheduledCharges = class {
|
|
|
823
827
|
);
|
|
824
828
|
}
|
|
825
829
|
};
|
|
830
|
+
|
|
831
|
+
// src/resources/webhook-events.ts
|
|
832
|
+
var WebhookEvents = class {
|
|
833
|
+
constructor(http) {
|
|
834
|
+
this.http = http;
|
|
835
|
+
}
|
|
836
|
+
http;
|
|
837
|
+
/**
|
|
838
|
+
* List webhook events for the authenticated seller, newest first.
|
|
839
|
+
* Filter by delivery `status`, by Garu `eventType`, and/or by the
|
|
840
|
+
* destination `endpointId`.
|
|
841
|
+
*
|
|
842
|
+
* @example
|
|
843
|
+
* // Surface anything that didn't make it through
|
|
844
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 50 });
|
|
845
|
+
*
|
|
846
|
+
* @example
|
|
847
|
+
* // Inspect every paid-charge delivery for a specific endpoint
|
|
848
|
+
* const paidDeliveries = await garu.webhookEvents.list({
|
|
849
|
+
* endpointId: 17,
|
|
850
|
+
* eventType: 'transaction.payment.paid'
|
|
851
|
+
* });
|
|
852
|
+
*/
|
|
853
|
+
async list(params = {}) {
|
|
854
|
+
const qs = new URLSearchParams();
|
|
855
|
+
if (params.page !== void 0) qs.set("page", String(params.page));
|
|
856
|
+
if (params.limit !== void 0) qs.set("limit", String(params.limit));
|
|
857
|
+
if (params.status) qs.set("status", params.status);
|
|
858
|
+
if (params.eventType) qs.set("event_type", params.eventType);
|
|
859
|
+
if (params.endpointId !== void 0) qs.set("endpoint_id", String(params.endpointId));
|
|
860
|
+
const query = qs.toString();
|
|
861
|
+
const url = `/api/webhook-events${query ? `?${query}` : ""}`;
|
|
862
|
+
const raw = await this.http.call(
|
|
863
|
+
(signal) => this.http.client.GET(url, { signal }).then(
|
|
864
|
+
(r) => r
|
|
865
|
+
)
|
|
866
|
+
);
|
|
867
|
+
return {
|
|
868
|
+
data: raw.events,
|
|
869
|
+
meta: {
|
|
870
|
+
page: raw.page,
|
|
871
|
+
limit: raw.limit,
|
|
872
|
+
total: raw.total,
|
|
873
|
+
totalPages: raw.pages
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* Fetch one webhook event by numeric ID — includes the full payload, the
|
|
879
|
+
* embedded endpoint snapshot, and the most recent response status/body.
|
|
880
|
+
*
|
|
881
|
+
* @example
|
|
882
|
+
* const event = await garu.webhookEvents.get(42);
|
|
883
|
+
* if (event.status === 'failed') {
|
|
884
|
+
* console.log(event.responseStatus, event.responseBody);
|
|
885
|
+
* }
|
|
886
|
+
*/
|
|
887
|
+
async get(id) {
|
|
888
|
+
return this.http.call(
|
|
889
|
+
(signal) => this.http.client.GET(`/api/webhook-events/${id}`, { signal }).then(
|
|
890
|
+
(r) => r
|
|
891
|
+
)
|
|
892
|
+
);
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Re-deliver a webhook event by ID. Resets it to `pending`, clears the
|
|
896
|
+
* retry schedule, and triggers an immediate delivery attempt. Works on
|
|
897
|
+
* any status (`success`, `failed`, `pending`) — use this when a
|
|
898
|
+
* customer reports a missed or unprocessed event.
|
|
899
|
+
*
|
|
900
|
+
* @example
|
|
901
|
+
* const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
|
|
902
|
+
* for (const event of failed.data) {
|
|
903
|
+
* await garu.webhookEvents.retry(event.id);
|
|
904
|
+
* }
|
|
905
|
+
*/
|
|
906
|
+
async retry(id) {
|
|
907
|
+
return this.http.call(
|
|
908
|
+
(signal) => this.http.client.POST(`/api/webhook-events/${id}/retry`, {
|
|
909
|
+
body: {},
|
|
910
|
+
signal
|
|
911
|
+
}).then((r) => r)
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
};
|
|
826
915
|
var webhooks = {
|
|
827
916
|
verify(params) {
|
|
828
917
|
const { signature, secret, payload } = params;
|
|
@@ -882,13 +971,14 @@ function parseSignatureHeader(header) {
|
|
|
882
971
|
var DEFAULT_BASE_URL = "https://garu.com.br";
|
|
883
972
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
884
973
|
var DEFAULT_MAX_RETRIES = 2;
|
|
885
|
-
var SDK_VERSION = "0.
|
|
974
|
+
var SDK_VERSION = "0.11.1";
|
|
886
975
|
var Garu = class {
|
|
887
976
|
charges;
|
|
888
977
|
customers;
|
|
889
978
|
meta;
|
|
890
979
|
products;
|
|
891
980
|
scheduledCharges;
|
|
981
|
+
webhookEvents;
|
|
892
982
|
/**
|
|
893
983
|
* Webhook helpers. Available both as an instance member and as a static —
|
|
894
984
|
* `Garu.webhooks.verify(...)` works without constructing a client.
|
|
@@ -909,6 +999,7 @@ var Garu = class {
|
|
|
909
999
|
this.meta = new Meta(http);
|
|
910
1000
|
this.products = new Products(http);
|
|
911
1001
|
this.scheduledCharges = new ScheduledCharges(http);
|
|
1002
|
+
this.webhookEvents = new WebhookEvents(http);
|
|
912
1003
|
}
|
|
913
1004
|
};
|
|
914
1005
|
|