@tsed/stripe 8.11.0 → 8.11.2-rc.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/lib/esm/constants/constants.js +0 -1
- package/lib/esm/decorators/webhookEvent.js +0 -1
- package/lib/esm/domain/StripeSettings.js +0 -1
- package/lib/esm/index.js +0 -1
- package/lib/esm/middlewares/WebhookEventMiddleware.js +0 -1
- package/lib/esm/services/StripeFactory.js +0 -1
- package/package.json +14 -11
- package/lib/esm/constants/constants.js.map +0 -1
- package/lib/esm/decorators/webhookEvent.js.map +0 -1
- package/lib/esm/domain/StripeSettings.js.map +0 -1
- package/lib/esm/index.js.map +0 -1
- package/lib/esm/middlewares/WebhookEventMiddleware.js.map +0 -1
- package/lib/esm/services/StripeFactory.js.map +0 -1
- package/src/constants/constants.ts +0 -2
- package/src/decorators/webhookEvent.ts +0 -26
- package/src/domain/StripeSettings.ts +0 -30
- package/src/index.ts +0 -8
- package/src/middlewares/WebhookEventMiddleware.spec.ts +0 -137
- package/src/middlewares/WebhookEventMiddleware.ts +0 -43
- package/src/services/StripeFactory.spec.ts +0 -34
- package/src/services/StripeFactory.ts +0 -25
- package/vitest.config.mts +0 -21
|
@@ -14,4 +14,3 @@ import { WebhookEventMiddleware } from "../middlewares/WebhookEventMiddleware.js
|
|
|
14
14
|
export function WebhookEvent(options) {
|
|
15
15
|
return useDecorators(useMethodDecorators(In("body").Type(Object).Required().Description("The raw webhook payload"), In("header").Name("stripe-signature").Type(String).Required().Description("The stripe webhook signature"), StoreSet(WebhookEventMiddleware, options), UseBefore(WebhookEventMiddleware)), Context(STRIPE_WEBHOOK_EVENT));
|
|
16
16
|
}
|
|
17
|
-
//# sourceMappingURL=webhookEvent.js.map
|
package/lib/esm/index.js
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@tsed/stripe",
|
|
3
3
|
"description": "Stripe package for Ts.ED framework",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "8.11.
|
|
5
|
+
"version": "8.11.2-rc.1",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"Stripe",
|
|
8
8
|
"Ts.ED",
|
|
@@ -35,15 +35,15 @@
|
|
|
35
35
|
"tslib": "2.7.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@tsed/adapters": "8.11.
|
|
39
|
-
"@tsed/barrels": "8.11.
|
|
40
|
-
"@tsed/core": "8.11.
|
|
41
|
-
"@tsed/di": "8.11.
|
|
42
|
-
"@tsed/exceptions": "8.11.
|
|
43
|
-
"@tsed/platform-middlewares": "8.11.
|
|
44
|
-
"@tsed/platform-params": "8.11.
|
|
45
|
-
"@tsed/schema": "8.11.
|
|
46
|
-
"@tsed/typescript": "8.11.
|
|
38
|
+
"@tsed/adapters": "8.11.2-rc.1",
|
|
39
|
+
"@tsed/barrels": "8.11.2-rc.1",
|
|
40
|
+
"@tsed/core": "8.11.2-rc.1",
|
|
41
|
+
"@tsed/di": "8.11.2-rc.1",
|
|
42
|
+
"@tsed/exceptions": "8.11.2-rc.1",
|
|
43
|
+
"@tsed/platform-middlewares": "8.11.2-rc.1",
|
|
44
|
+
"@tsed/platform-params": "8.11.2-rc.1",
|
|
45
|
+
"@tsed/schema": "8.11.2-rc.1",
|
|
46
|
+
"@tsed/typescript": "8.11.2-rc.1",
|
|
47
47
|
"eslint": "9.12.0",
|
|
48
48
|
"stripe": "^17.7.0",
|
|
49
49
|
"typescript": "5.4.5",
|
|
@@ -81,5 +81,8 @@
|
|
|
81
81
|
},
|
|
82
82
|
"homepage": "https://github.com/tsedio/tsed/tree/production/packages/third-parties/stripe",
|
|
83
83
|
"author": "Romain Lenzotti",
|
|
84
|
-
"license": "MIT"
|
|
84
|
+
"license": "MIT",
|
|
85
|
+
"publishConfig": {
|
|
86
|
+
"tag": "rc"
|
|
87
|
+
}
|
|
85
88
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/constants/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,qBAAqB,CAAC;AAC1D,MAAM,CAAC,MAAM,wBAAwB,GAAG,yBAAyB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webhookEvent.js","sourceRoot":"","sources":["../../../src/decorators/webhookEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,aAAa,EAAE,mBAAmB,EAAC,MAAM,YAAY,CAAC;AACxE,OAAO,EAAC,SAAS,EAAC,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAC,EAAE,EAAC,MAAM,cAAc,CAAC;AAEhC,OAAO,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAC,sBAAsB,EAAsB,MAAM,0CAA0C,CAAC;AAErG;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAAsC;IACjE,OAAO,aAAa,CAClB,mBAAmB,CACjB,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,yBAAyB,CAAC,EACzE,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,8BAA8B,CAAC,EACzG,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC,EACzC,SAAS,CAAC,sBAAsB,CAAC,CAClC,EACD,OAAO,CAAC,oBAAoB,CAAC,CAC9B,CAAC;AACJ,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StripeSettings.js","sourceRoot":"","sources":["../../../src/domain/StripeSettings.ts"],"names":[],"mappings":""}
|
package/lib/esm/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;AACxD,cAAc,6BAA6B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WebhookEventMiddleware.js","sourceRoot":"","sources":["../../../src/middlewares/WebhookEventMiddleware.ts"],"names":[],"mappings":";;AAAA,OAAO,8BAA8B,CAAC;AAEtC,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAC,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAC,UAAU,EAAE,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAC,UAAU,EAAoB,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAE9B,OAAO,EAAC,oBAAoB,EAAE,wBAAwB,EAAC,MAAM,2BAA2B,CAAC;AAQlF,IAAM,sBAAsB,8BAA5B,MAAM,sBAAsB;IAOjC,GAAG,CAAmC,SAAiB,EAAmB,IAAY,EAAa,GAAY;QAC7G,MAAM,EAAC,MAAM,EAAE,SAAS,EAAC,GAAwB;YAC/C,GAAG,IAAI,CAAC,QAAQ;YAChB,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAsB,CAAC;SAClD,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,mBAAmB,CAC3B,qHAAqH,CACtH,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,GAAG,CAAC,GAAG,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;YAC7C,GAAG,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QACzG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,UAAU,CAAC,yBAAyB,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;CACF,CAAA;AAxBW;IADT,MAAM,EAAE;8BACS,MAAM;sDAAC;AAGf;IADT,QAAQ,CAAC,iBAAiB,CAAC;;wDACY;AAExC;IAAK,WAAA,YAAY,CAAC,kBAAkB,CAAC,CAAA;IAAqB,WAAA,aAAa,EAAE,CAAA;IAAgB,WAAA,OAAO,EAAE,CAAA;;6CAAlB,MAAM;;iDAkBrF;AAzBU,sBAAsB;IADlC,UAAU,EAAE;GACA,sBAAsB,CA0BlC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StripeFactory.js","sourceRoot":"","sources":["../../../src/services/StripeFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,gBAAgB,EAAC,MAAM,UAAU,CAAC;AACzD,OAAO,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAI9B,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AAEpC,gBAAgB,CAAC;IACf,KAAK,EAAE,MAAM;IACb,IAAI,EAAE,CAAC,aAAa,CAAC;IACrB,UAAU,CAAC,QAAuB;QAChC,MAAM,EAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAC,GAAG,QAAQ,CAAC,GAAG,CAAiB,QAAQ,EAAE,EAAS,CAAC,CAAC;QAEzF,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAE9B,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE;gBACxB,GAAG,OAAO;gBACV,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import {StoreSet, useDecorators, useMethodDecorators} from "@tsed/core";
|
|
2
|
-
import {UseBefore} from "@tsed/platform-middlewares";
|
|
3
|
-
import {Context} from "@tsed/platform-params";
|
|
4
|
-
import {In} from "@tsed/schema";
|
|
5
|
-
|
|
6
|
-
import {STRIPE_WEBHOOK_EVENT} from "../constants/constants.js";
|
|
7
|
-
import {WebhookEventMiddleware, WebhookEventOptions} from "../middlewares/WebhookEventMiddleware.js";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Get the stripe webhook event.
|
|
11
|
-
*
|
|
12
|
-
* @decorator
|
|
13
|
-
* @operation
|
|
14
|
-
* @input
|
|
15
|
-
*/
|
|
16
|
-
export function WebhookEvent(options?: Partial<WebhookEventOptions>) {
|
|
17
|
-
return useDecorators(
|
|
18
|
-
useMethodDecorators(
|
|
19
|
-
In("body").Type(Object).Required().Description("The raw webhook payload"),
|
|
20
|
-
In("header").Name("stripe-signature").Type(String).Required().Description("The stripe webhook signature"),
|
|
21
|
-
StoreSet(WebhookEventMiddleware, options),
|
|
22
|
-
UseBefore(WebhookEventMiddleware)
|
|
23
|
-
),
|
|
24
|
-
Context(STRIPE_WEBHOOK_EVENT)
|
|
25
|
-
);
|
|
26
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import {Stripe} from "stripe";
|
|
2
|
-
|
|
3
|
-
export interface StripeSettings extends Stripe.StripeConfig {
|
|
4
|
-
/**
|
|
5
|
-
* Stripe ApiKey
|
|
6
|
-
*/
|
|
7
|
-
apiKey: string;
|
|
8
|
-
/**
|
|
9
|
-
* Webhooks settings
|
|
10
|
-
*/
|
|
11
|
-
webhooks?: {
|
|
12
|
-
/**
|
|
13
|
-
* Your Webhook Signing Secret for this endpoint (e.g., 'whsec_...').
|
|
14
|
-
* You can get this [in your dashboard](https://dashboard.stripe.com/webhooks).
|
|
15
|
-
*/
|
|
16
|
-
secret: string;
|
|
17
|
-
/**
|
|
18
|
-
* Seconds of tolerance on timestamps.
|
|
19
|
-
*/
|
|
20
|
-
tolerance?: number;
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
declare global {
|
|
25
|
-
namespace TsED {
|
|
26
|
-
interface Configuration {
|
|
27
|
-
stripe: StripeSettings;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Automatically generated by @tsed/barrels.
|
|
3
|
-
*/
|
|
4
|
-
export * from "./constants/constants.js";
|
|
5
|
-
export * from "./decorators/webhookEvent.js";
|
|
6
|
-
export * from "./domain/StripeSettings.js";
|
|
7
|
-
export * from "./middlewares/WebhookEventMiddleware.js";
|
|
8
|
-
export * from "./services/StripeFactory.js";
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import "../index.js";
|
|
2
|
-
|
|
3
|
-
import {catchError} from "@tsed/core";
|
|
4
|
-
import {EndpointMetadata} from "@tsed/platform-http";
|
|
5
|
-
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
6
|
-
import {Stripe} from "stripe";
|
|
7
|
-
|
|
8
|
-
import {STRIPE_WEBHOOK_EVENT, STRIPE_WEBHOOK_SIGNATURE} from "../constants/constants.js";
|
|
9
|
-
import {WebhookEventMiddleware} from "./WebhookEventMiddleware.js";
|
|
10
|
-
|
|
11
|
-
class Ctrl {
|
|
12
|
-
get() {}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
describe("WebhookEventMiddleware", () => {
|
|
16
|
-
beforeEach(() =>
|
|
17
|
-
PlatformTest.create({
|
|
18
|
-
stripe: {
|
|
19
|
-
apiKey: "the_api_key",
|
|
20
|
-
apiVersion: "2025-02-24.acacia",
|
|
21
|
-
webhooks: {
|
|
22
|
-
secret: "whsec_test_secret",
|
|
23
|
-
tolerance: 1
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
})
|
|
27
|
-
);
|
|
28
|
-
afterEach(PlatformTest.reset);
|
|
29
|
-
|
|
30
|
-
it("should construct event", async () => {
|
|
31
|
-
const stripe = PlatformTest.get<Stripe>(Stripe);
|
|
32
|
-
const ctx = PlatformTest.createRequestContext();
|
|
33
|
-
ctx.endpoint = EndpointMetadata.get(Ctrl, "get");
|
|
34
|
-
|
|
35
|
-
const payload = {
|
|
36
|
-
id: "evt_test_webhook",
|
|
37
|
-
object: "event"
|
|
38
|
-
};
|
|
39
|
-
const payloadString = JSON.stringify(payload, null, 2);
|
|
40
|
-
|
|
41
|
-
const signature = stripe.webhooks.generateTestHeaderString({
|
|
42
|
-
payload: payloadString,
|
|
43
|
-
secret: "whsec_test_secret"
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const middleware = await PlatformTest.invoke<WebhookEventMiddleware>(WebhookEventMiddleware);
|
|
47
|
-
|
|
48
|
-
middleware.use(signature, Buffer.from(payloadString), ctx);
|
|
49
|
-
|
|
50
|
-
expect(ctx.get(STRIPE_WEBHOOK_EVENT)).toEqual(payload);
|
|
51
|
-
expect(ctx.get(STRIPE_WEBHOOK_SIGNATURE)).toEqual(signature);
|
|
52
|
-
});
|
|
53
|
-
it("should construct event based on endpoint options", async () => {
|
|
54
|
-
const stripe = PlatformTest.get<Stripe>(Stripe);
|
|
55
|
-
const ctx = PlatformTest.createRequestContext();
|
|
56
|
-
ctx.endpoint = EndpointMetadata.get(Ctrl, "get");
|
|
57
|
-
ctx.endpoint = EndpointMetadata.get(Ctrl, "get");
|
|
58
|
-
ctx.endpoint.store.set(WebhookEventMiddleware, {
|
|
59
|
-
secret: "whsec_test_secret1"
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const payload = {
|
|
63
|
-
id: "evt_test_webhook",
|
|
64
|
-
object: "event"
|
|
65
|
-
};
|
|
66
|
-
const payloadString = JSON.stringify(payload, null, 2);
|
|
67
|
-
|
|
68
|
-
const signature = stripe.webhooks.generateTestHeaderString({
|
|
69
|
-
payload: payloadString,
|
|
70
|
-
secret: "whsec_test_secret1"
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
const middleware = await PlatformTest.invoke<WebhookEventMiddleware>(WebhookEventMiddleware);
|
|
74
|
-
|
|
75
|
-
middleware.use(signature, Buffer.from(payloadString), ctx);
|
|
76
|
-
|
|
77
|
-
expect(ctx.get(STRIPE_WEBHOOK_EVENT)).toEqual(payload);
|
|
78
|
-
expect(ctx.get(STRIPE_WEBHOOK_SIGNATURE)).toEqual(signature);
|
|
79
|
-
});
|
|
80
|
-
it("should throw error when signature isn't valid", async () => {
|
|
81
|
-
const stripe = PlatformTest.get<Stripe>(Stripe);
|
|
82
|
-
const ctx = PlatformTest.createRequestContext();
|
|
83
|
-
ctx.endpoint = EndpointMetadata.get(Ctrl, "get");
|
|
84
|
-
|
|
85
|
-
const payload = {
|
|
86
|
-
id: "evt_test_webhook",
|
|
87
|
-
object: "event"
|
|
88
|
-
};
|
|
89
|
-
const payloadString = JSON.stringify(payload, null, 2);
|
|
90
|
-
|
|
91
|
-
const signature = stripe.webhooks.generateTestHeaderString({
|
|
92
|
-
payload: payloadString,
|
|
93
|
-
secret: "whsec_test_secretooo"
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const middleware = await PlatformTest.invoke<WebhookEventMiddleware>(WebhookEventMiddleware);
|
|
97
|
-
|
|
98
|
-
const actualError: any = catchError(() => middleware.use(signature, Buffer.from(payloadString), ctx));
|
|
99
|
-
|
|
100
|
-
expect(actualError.message).toEqual(
|
|
101
|
-
`Stripe webhook error: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?
|
|
102
|
-
If a webhook request is being forwarded by a third-party tool, ensure that the exact request body, including JSON formatting and new line style, is preserved.
|
|
103
|
-
|
|
104
|
-
Learn more about webhook signing and explore webhook integration examples for various frameworks at https://docs.stripe.com/webhooks/signature
|
|
105
|
-
, innerException: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?
|
|
106
|
-
If a webhook request is being forwarded by a third-party tool, ensure that the exact request body, including JSON formatting and new line style, is preserved.
|
|
107
|
-
|
|
108
|
-
Learn more about webhook signing and explore webhook integration examples for various frameworks at https://docs.stripe.com/webhooks/signature`
|
|
109
|
-
);
|
|
110
|
-
});
|
|
111
|
-
it("should throw error when secret is missing", async () => {
|
|
112
|
-
const stripe = PlatformTest.get<Stripe>(Stripe);
|
|
113
|
-
const ctx = PlatformTest.createRequestContext();
|
|
114
|
-
ctx.endpoint = EndpointMetadata.get(Ctrl, "get");
|
|
115
|
-
ctx.endpoint.store.set(WebhookEventMiddleware, {
|
|
116
|
-
secret: null
|
|
117
|
-
});
|
|
118
|
-
const payload = {
|
|
119
|
-
id: "evt_test_webhook",
|
|
120
|
-
object: "event"
|
|
121
|
-
};
|
|
122
|
-
const payloadString = JSON.stringify(payload, null, 2);
|
|
123
|
-
|
|
124
|
-
const signature = stripe.webhooks.generateTestHeaderString({
|
|
125
|
-
payload: payloadString,
|
|
126
|
-
secret: "whsec_test_secretooo"
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
const middleware = await PlatformTest.invoke<WebhookEventMiddleware>(WebhookEventMiddleware);
|
|
130
|
-
|
|
131
|
-
const actualError: any = catchError(() => middleware.use(signature, Buffer.from(payloadString), ctx));
|
|
132
|
-
|
|
133
|
-
expect(actualError.message).toEqual(
|
|
134
|
-
"Missing Stripe webhooks secret key. You can get this in your dashboard. See: https://dashboard.stripe.com/webhooks."
|
|
135
|
-
);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import "../services/StripeFactory.js";
|
|
2
|
-
|
|
3
|
-
import {Constant, Inject} from "@tsed/di";
|
|
4
|
-
import {BadRequest, InternalServerError} from "@tsed/exceptions";
|
|
5
|
-
import {Middleware, MiddlewareMethods} from "@tsed/platform-middlewares";
|
|
6
|
-
import {Context, HeaderParams, RawBodyParams} from "@tsed/platform-params";
|
|
7
|
-
import {Stripe} from "stripe";
|
|
8
|
-
|
|
9
|
-
import {STRIPE_WEBHOOK_EVENT, STRIPE_WEBHOOK_SIGNATURE} from "../constants/constants.js";
|
|
10
|
-
|
|
11
|
-
export interface WebhookEventOptions {
|
|
12
|
-
secret: string;
|
|
13
|
-
tolerance: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
@Middleware()
|
|
17
|
-
export class WebhookEventMiddleware implements MiddlewareMethods {
|
|
18
|
-
@Inject()
|
|
19
|
-
protected stripe: Stripe;
|
|
20
|
-
|
|
21
|
-
@Constant("stripe.webhooks")
|
|
22
|
-
protected webhooks: WebhookEventOptions;
|
|
23
|
-
|
|
24
|
-
use(@HeaderParams("stripe-signature") signature: string, @RawBodyParams() body: Buffer, @Context() ctx: Context): any {
|
|
25
|
-
const {secret, tolerance}: WebhookEventOptions = {
|
|
26
|
-
...this.webhooks,
|
|
27
|
-
...ctx.endpoint.store.get(WebhookEventMiddleware)
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
if (!secret) {
|
|
31
|
-
throw new InternalServerError(
|
|
32
|
-
"Missing Stripe webhooks secret key. You can get this in your dashboard. See: https://dashboard.stripe.com/webhooks."
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
ctx.set(STRIPE_WEBHOOK_SIGNATURE, signature);
|
|
38
|
-
ctx.set(STRIPE_WEBHOOK_EVENT, this.stripe.webhooks.constructEvent(body, signature, secret, tolerance));
|
|
39
|
-
} catch (err) {
|
|
40
|
-
throw new BadRequest(`Stripe webhook error: ${err.message}`, err);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import "../index.js";
|
|
2
|
-
|
|
3
|
-
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
4
|
-
import {Stripe} from "stripe";
|
|
5
|
-
|
|
6
|
-
describe("StripeFactory", () => {
|
|
7
|
-
describe("when there is configuration", () => {
|
|
8
|
-
beforeEach(() =>
|
|
9
|
-
PlatformTest.create({
|
|
10
|
-
stripe: {
|
|
11
|
-
apiKey: "the_api_key",
|
|
12
|
-
apiVersion: "2025-02-24.acacia"
|
|
13
|
-
}
|
|
14
|
-
})
|
|
15
|
-
);
|
|
16
|
-
afterEach(PlatformTest.reset);
|
|
17
|
-
|
|
18
|
-
it("should inject the strip instance", () => {
|
|
19
|
-
const stripe = PlatformTest.get<Stripe>(Stripe);
|
|
20
|
-
|
|
21
|
-
expect(stripe).toBeInstanceOf(Stripe);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
describe("when there is no configuration", () => {
|
|
25
|
-
beforeEach(() => PlatformTest.create({}));
|
|
26
|
-
afterEach(PlatformTest.reset);
|
|
27
|
-
|
|
28
|
-
it("should inject the strip instance", () => {
|
|
29
|
-
const stripe = PlatformTest.get<Stripe>(Stripe);
|
|
30
|
-
|
|
31
|
-
expect(stripe).not.toBeInstanceOf(Stripe);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import {Configuration, registerProvider} from "@tsed/di";
|
|
2
|
-
import {Stripe} from "stripe";
|
|
3
|
-
|
|
4
|
-
import {StripeSettings} from "../domain/StripeSettings.js";
|
|
5
|
-
|
|
6
|
-
export const StripeFactory = Stripe;
|
|
7
|
-
|
|
8
|
-
registerProvider({
|
|
9
|
-
token: Stripe,
|
|
10
|
-
deps: [Configuration],
|
|
11
|
-
useFactory(settings: Configuration) {
|
|
12
|
-
const {apiKey, webhooks, ...options} = settings.get<StripeSettings>("stripe", {} as any);
|
|
13
|
-
|
|
14
|
-
settings.set("rawBody", true);
|
|
15
|
-
|
|
16
|
-
if (apiKey) {
|
|
17
|
-
return new Stripe(apiKey, {
|
|
18
|
-
...options,
|
|
19
|
-
typescript: true
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return {};
|
|
24
|
-
}
|
|
25
|
-
});
|
package/vitest.config.mts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// @ts-ignore
|
|
2
|
-
import {presets} from "@tsed/vitest/presets";
|
|
3
|
-
import {defineConfig} from "vitest/config";
|
|
4
|
-
|
|
5
|
-
export default defineConfig(
|
|
6
|
-
{
|
|
7
|
-
...presets,
|
|
8
|
-
test: {
|
|
9
|
-
...presets.test,
|
|
10
|
-
coverage: {
|
|
11
|
-
...presets.test.coverage,
|
|
12
|
-
thresholds: {
|
|
13
|
-
statements: 0,
|
|
14
|
-
branches: 0,
|
|
15
|
-
functions: 0,
|
|
16
|
-
lines: 0
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
);
|