@payloadcms/plugin-stripe 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -10
- package/dist/routes/rest.d.ts +1 -1
- package/dist/routes/rest.js +21 -32
- package/dist/routes/rest.js.map +1 -1
- package/dist/types.d.ts +11 -2
- package/dist/utilities/stripeProxy.d.ts +2 -0
- package/dist/utilities/stripeProxy.js +84 -0
- package/dist/utilities/stripeProxy.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@payloadcms/plugin-stripe)
|
|
4
4
|
|
|
5
|
-
A plugin for [Payload CMS](https://github.com/payloadcms/payload) to manage
|
|
5
|
+
A plugin for [Payload CMS](https://github.com/payloadcms/payload) to manage [Stripe](https://stripe.com) through Payload.
|
|
6
6
|
|
|
7
7
|
Core features:
|
|
8
|
-
- Layers your Stripe account
|
|
9
|
-
-
|
|
10
|
-
|
|
8
|
+
- Layers your Stripe account behind [Payload access control](https://payloadcms.com/docs/access-control/overview)
|
|
9
|
+
- Enables a two-way communication channel between Stripe and Payload
|
|
10
|
+
- Proxies the [Stripe REST API](https://stripe.com/docs/api)
|
|
11
|
+
- Proxies [Stripe webhooks](https://stripe.com/docs/webhooks)
|
|
11
12
|
|
|
12
13
|
## Installation
|
|
13
14
|
|
|
@@ -50,21 +51,27 @@ export default config;
|
|
|
50
51
|
|
|
51
52
|
Optional. An object of Stripe webhook handlers, keyed to the name of the event. See [webhooks](#webhooks) for more details or for a list of all available webhooks, see [here](https://stripe.com/docs/cli/trigger#trigger-event).
|
|
52
53
|
|
|
53
|
-
###
|
|
54
|
+
### Endpoints
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
One core functionality of this plugin is to enable a two-way communication channel between Stripe and Payload. To do this, the following custom endpoints are automatically opened for you:
|
|
56
57
|
|
|
57
58
|
>NOTE: the `/api` part of these routes may be different based on the settings defined in your Payload config.
|
|
58
59
|
|
|
59
60
|
- `POST /api/stripe/rest`
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
Proxies the [Stripe REST API](https://stripe.com/docs/api) behind [Payload access control](https://payloadcms.com/docs/access-control/overview) and returns the result. If you need to proxy the API server-side, use the [stripeProxy](#node) function.
|
|
62
63
|
|
|
63
|
-
```
|
|
64
|
+
```js
|
|
64
65
|
const res = await fetch(`/api/stripe/rest`, {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
credentials: 'include',
|
|
68
|
+
headers: {
|
|
69
|
+
ContentType: 'application/json',
|
|
70
|
+
// Authorization: `JWT ${token}` // NOTE: do this if not in a browser (i.e. curl or Postman)
|
|
71
|
+
},
|
|
65
72
|
body: JSON.stringify({
|
|
66
73
|
stripeMethod: "stripe.subscriptions.list",
|
|
67
|
-
|
|
74
|
+
stripeArgs: {
|
|
68
75
|
customer: "abc"
|
|
69
76
|
}
|
|
70
77
|
})
|
|
@@ -105,6 +112,36 @@ export default config;
|
|
|
105
112
|
|
|
106
113
|
For a full list of available webhooks, see [here](https://stripe.com/docs/cli/trigger#trigger-event).
|
|
107
114
|
|
|
115
|
+
### Node
|
|
116
|
+
|
|
117
|
+
You can also proxy the Stripe API server-side using the `stripeProxy` function exported by the plugin. This is exactly what the `/api/stripe/rest` endpoint does behind-the-scenes. Here's an example:
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
import { stripeProxy } from '@payloadcms/plugin-stripe';
|
|
121
|
+
|
|
122
|
+
export const MyFunction = async () => {
|
|
123
|
+
try {
|
|
124
|
+
const customer = await stripeProxy({
|
|
125
|
+
stripeSecretKey: process.env.STRIPE_SECRET_KEY,
|
|
126
|
+
stripeMethod: 'customers.create',
|
|
127
|
+
stripeArgs: {
|
|
128
|
+
email: data.email,
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
if (customer.status === 200) {
|
|
133
|
+
// DO SOMETHING
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (customer.status >= 400) {
|
|
137
|
+
throw new Error(customer.message);
|
|
138
|
+
}
|
|
139
|
+
} catch (error) {
|
|
140
|
+
console.error(error.message);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
108
145
|
## TypeScript
|
|
109
146
|
|
|
110
147
|
All types can be directly imported:
|
|
@@ -112,7 +149,8 @@ All types can be directly imported:
|
|
|
112
149
|
```js
|
|
113
150
|
import {
|
|
114
151
|
StripeConfig,
|
|
115
|
-
|
|
152
|
+
StripeWebhookHandler.
|
|
153
|
+
StripeProxy
|
|
116
154
|
} from '@payloadcms/plugin-stripe/dist/types';
|
|
117
155
|
```
|
|
118
156
|
|
package/dist/routes/rest.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { PayloadRequest } from 'payload/types';
|
|
2
2
|
import { StripeConfig } from '../types';
|
|
3
3
|
import { Response } from 'express';
|
|
4
|
-
export declare const stripeREST: (req: PayloadRequest, res: Response, next: any, stripeConfig: StripeConfig) => Promise<any>;
|
|
4
|
+
export declare const stripeREST: (req: PayloadRequest, res: Response, next: any, stripeConfig: StripeConfig) => Promise<Response<any, Record<string, any>> | undefined>;
|
package/dist/routes/rest.js
CHANGED
|
@@ -35,53 +35,42 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
35
35
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
-
};
|
|
41
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
39
|
exports.stripeREST = void 0;
|
|
43
40
|
var errors_1 = require("payload/errors");
|
|
44
|
-
var
|
|
45
|
-
var lodash_get_1 = __importDefault(require("lodash.get"));
|
|
41
|
+
var stripeProxy_1 = require("../utilities/stripeProxy");
|
|
46
42
|
var stripeREST = function (req, res, next, stripeConfig) { return __awaiter(void 0, void 0, void 0, function () {
|
|
47
|
-
var
|
|
48
|
-
,
|
|
43
|
+
var payload, user, _a, stripeMethod, stripeArgs // example: 'cus_MGgt3Tuj3D66f2'
|
|
44
|
+
, stripeSecretKey, pluginRes, status_1, error_1, message;
|
|
49
45
|
return __generator(this, function (_b) {
|
|
50
46
|
switch (_b.label) {
|
|
51
47
|
case 0:
|
|
48
|
+
payload = req.payload, user = req.user, _a = req.body, stripeMethod = _a.stripeMethod, stripeArgs = _a.stripeArgs;
|
|
52
49
|
stripeSecretKey = stripeConfig.stripeSecretKey;
|
|
53
|
-
stripe = new stripe_1.default(stripeSecretKey, { apiVersion: '2022-08-01' });
|
|
54
50
|
_b.label = 1;
|
|
55
51
|
case 1:
|
|
56
|
-
_b.trys.push([1,
|
|
57
|
-
_a = req.body, stripeMethod = _a.stripeMethod, stripeArgs = _a.stripeArgs, user = req.user;
|
|
52
|
+
_b.trys.push([1, 3, , 4]);
|
|
58
53
|
if (!user) { // TODO: make this customizable from the config
|
|
59
54
|
throw new errors_1.Forbidden();
|
|
60
55
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return [4 /*yield*/, foundMethod(stripeArgs)];
|
|
56
|
+
return [4 /*yield*/, (0, stripeProxy_1.stripeProxy)({
|
|
57
|
+
stripeSecretKey: stripeSecretKey,
|
|
58
|
+
stripeMethod: stripeMethod,
|
|
59
|
+
stripeArgs: stripeArgs // example: 'cus_MGgt3Tuj3D66f2'
|
|
60
|
+
})];
|
|
67
61
|
case 2:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return [2 /*return*/, res.json(stripeResponse)];
|
|
62
|
+
pluginRes = _b.sent();
|
|
63
|
+
status_1 = pluginRes.status;
|
|
64
|
+
res.status(status_1).json(pluginRes);
|
|
65
|
+
return [3 /*break*/, 4];
|
|
73
66
|
case 3:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
case
|
|
81
|
-
case 7:
|
|
82
|
-
err_1 = _b.sent();
|
|
83
|
-
return [2 /*return*/, next(err_1)];
|
|
84
|
-
case 8: return [2 /*return*/];
|
|
67
|
+
error_1 = _b.sent();
|
|
68
|
+
message = "An error has occurred in the Stripe plugin REST handler: '".concat(error_1, "'");
|
|
69
|
+
payload.logger.error(message);
|
|
70
|
+
return [2 /*return*/, res.status(500).json({
|
|
71
|
+
message: message
|
|
72
|
+
})];
|
|
73
|
+
case 4: return [2 /*return*/];
|
|
85
74
|
}
|
|
86
75
|
});
|
|
87
76
|
}); };
|
package/dist/routes/rest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../src/routes/rest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../src/routes/rest.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,yCAA2C;AAG3C,wDAAuD;AAEhD,IAAM,UAAU,GAAG,UACxB,GAAmB,EACnB,GAAa,EACb,IAAS,EACT,YAA0B;;;;;;gBAGxB,OAAO,GAML,GAAG,QANE,EACP,IAAI,GAKF,GAAG,KALD,EACJ,KAIE,GAAG,KADJ,EAFC,YAAY,kBAAA,EACZ,UAAU,gBAAA,CAEN;gBAEA,eAAe,GAAK,YAAY,gBAAjB,CAAkB;;;;gBAGvC,IAAI,CAAC,IAAI,EAAE,EAAE,+CAA+C;oBAC1D,MAAM,IAAI,kBAAS,EAAE,CAAC;iBACvB;gBAEiB,qBAAM,IAAA,yBAAW,EAAC;wBAClC,eAAe,iBAAA;wBACf,YAAY,cAAA;wBACZ,UAAU,YAAA,CAAC,gCAAgC;qBAC5C,CAAC,EAAA;;gBAJI,SAAS,GAAG,SAIhB;gBAGA,WACE,SAAS,OADL,CACM;gBAEd,GAAG,CAAC,MAAM,CAAC,QAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;;;;gBAG7B,OAAO,GAAG,oEAA6D,OAAK,MAAG,CAAC;gBACtF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC9B,sBAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBAC1B,OAAO,SAAA;qBACR,CAAC,EAAC;;;;KAEN,CAAC;AAzCW,QAAA,UAAU,cAyCrB"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import Stripe from "stripe";
|
|
2
|
-
export declare type
|
|
2
|
+
export declare type StripeWebhookHandler = (event: any, stripe: Stripe, stripeConfig: StripeConfig) => void;
|
|
3
3
|
export declare type StripeConfig = {
|
|
4
4
|
stripeSecretKey: string;
|
|
5
5
|
stripeWebhookEndpointSecret?: string;
|
|
6
6
|
webhooks?: {
|
|
7
|
-
[webhookName: string]:
|
|
7
|
+
[webhookName: string]: StripeWebhookHandler;
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
|
+
export declare type StripeProxy = (args: {
|
|
11
|
+
stripeSecretKey: string;
|
|
12
|
+
stripeMethod: string;
|
|
13
|
+
stripeArgs: any[];
|
|
14
|
+
}) => Promise<{
|
|
15
|
+
status: number;
|
|
16
|
+
message?: string;
|
|
17
|
+
data?: any;
|
|
18
|
+
}>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (_) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.stripeProxy = void 0;
|
|
43
|
+
var lodash_get_1 = __importDefault(require("lodash.get"));
|
|
44
|
+
var stripe_1 = __importDefault(require("stripe"));
|
|
45
|
+
var stripeProxy = function (_a) {
|
|
46
|
+
var stripeSecretKey = _a.stripeSecretKey, stripeMethod = _a.stripeMethod, stripeArgs = _a.stripeArgs;
|
|
47
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
48
|
+
var stripe, topLevelMethod, contextToBind, foundMethod, stripeResponse, error_1;
|
|
49
|
+
return __generator(this, function (_b) {
|
|
50
|
+
switch (_b.label) {
|
|
51
|
+
case 0:
|
|
52
|
+
stripe = new stripe_1.default(stripeSecretKey, { apiVersion: '2022-08-01' });
|
|
53
|
+
if (!(typeof stripeMethod === 'string')) return [3 /*break*/, 7];
|
|
54
|
+
topLevelMethod = stripeMethod.split('.')[0];
|
|
55
|
+
contextToBind = stripe[topLevelMethod];
|
|
56
|
+
foundMethod = (0, lodash_get_1.default)(stripe, stripeMethod).bind(contextToBind);
|
|
57
|
+
if (!(typeof foundMethod === 'function')) return [3 /*break*/, 5];
|
|
58
|
+
_b.label = 1;
|
|
59
|
+
case 1:
|
|
60
|
+
_b.trys.push([1, 3, , 4]);
|
|
61
|
+
return [4 /*yield*/, foundMethod.apply(void 0, stripeArgs)];
|
|
62
|
+
case 2:
|
|
63
|
+
stripeResponse = _b.sent();
|
|
64
|
+
return [2 /*return*/, {
|
|
65
|
+
status: 200,
|
|
66
|
+
data: stripeResponse
|
|
67
|
+
}];
|
|
68
|
+
case 3:
|
|
69
|
+
error_1 = _b.sent();
|
|
70
|
+
return [2 /*return*/, {
|
|
71
|
+
status: 404,
|
|
72
|
+
message: "A Stripe API error has occurred: ".concat(error_1)
|
|
73
|
+
}];
|
|
74
|
+
case 4: return [3 /*break*/, 6];
|
|
75
|
+
case 5: throw Error("The provided Stripe method of '".concat(stripeMethod, "' is not a part of the Stripe API."));
|
|
76
|
+
case 6: return [3 /*break*/, 8];
|
|
77
|
+
case 7: throw Error('You must provide a Stripe method to call.');
|
|
78
|
+
case 8: return [2 /*return*/];
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
exports.stripeProxy = stripeProxy;
|
|
84
|
+
//# sourceMappingURL=stripeProxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripeProxy.js","sourceRoot":"","sources":["../../src/utilities/stripeProxy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0DAAmC;AACnC,kDAA4B;AAGrB,IAAM,WAAW,GAAgB,UAAO,EAI9C;QAHC,eAAe,qBAAA,EACf,YAAY,kBAAA,EACZ,UAAU,gBAAA;;;;;;oBAEJ,MAAM,GAAG,IAAI,gBAAM,CAAC,eAAe,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC;yBAErE,CAAA,OAAO,YAAY,KAAK,QAAQ,CAAA,EAAhC,wBAAgC;oBAC5B,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAiB,CAAC;oBAC5D,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;oBAGvC,WAAW,GAAG,IAAA,oBAAS,EAAC,MAAM,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;yBAEpE,CAAA,OAAO,WAAW,KAAK,UAAU,CAAA,EAAjC,wBAAiC;;;;oBAEV,qBAAM,WAAW,eAAI,UAAU,GAAC;;oBAAjD,cAAc,GAAG,SAAgC;oBACvD,sBAAO;4BACL,MAAM,EAAE,GAAG;4BACX,IAAI,EAAE,cAAc;yBACrB,EAAC;;;oBAEF,sBAAO;4BACL,MAAM,EAAE,GAAG;4BACX,OAAO,EAAE,2CAAoC,OAAK,CAAE;yBACrD,EAAC;;wBAGJ,MAAM,KAAK,CAAC,yCAAkC,YAAY,uCAAoC,CAAC,CAAA;;wBAGjG,MAAM,KAAK,CAAC,2CAA2C,CAAC,CAAA;;;;;CAE3D,CAAA;AAjCY,QAAA,WAAW,eAiCvB"}
|