@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 CHANGED
@@ -2,12 +2,13 @@
2
2
 
3
3
  [![NPM](https://img.shields.io/npm/v/@payloadcms/plugin-stripe)](https://www.npmjs.com/package/@payloadcms/plugin-stripe)
4
4
 
5
- A plugin for [Payload CMS](https://github.com/payloadcms/payload) to manage a [Stripe](https://stripe.com/) account through Payload.
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 with Payload access control
9
- - Opens custom routes to interface with the Stripe REST API
10
- - Handles Stripe webhooks to allow for a two-way data sync
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
- ### Routes
54
+ ### Endpoints
54
55
 
55
- The following routes are automatically opened to allow you to interact with the Stripe API behind Payload access control. This allows you to read and make updates to your account.
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
- Calls the given [Stripe REST API](https://stripe.com/docs/api) method and returns the result.
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
- stripeMethodArgs: {
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
- WebhookHandler
152
+ StripeWebhookHandler.
153
+ StripeProxy
116
154
  } from '@payloadcms/plugin-stripe/dist/types';
117
155
  ```
118
156
 
@@ -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>;
@@ -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 stripe_1 = __importDefault(require("stripe"));
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 stripeSecretKey, stripe, _a, stripeMethod, stripeArgs // 'cus_MGgt3Tuj3D66f2'
48
- , user, topLevelMethod, contextToBind, foundMethod, stripeResponse, err_1;
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, 7, , 8]);
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
- if (!(typeof stripeMethod === 'string')) return [3 /*break*/, 5];
62
- topLevelMethod = stripeMethod.split('.')[0];
63
- contextToBind = stripe[topLevelMethod];
64
- foundMethod = (0, lodash_get_1.default)(stripe, stripeMethod).bind(contextToBind);
65
- if (!(typeof foundMethod === 'function')) return [3 /*break*/, 3];
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
- stripeResponse = _b.sent();
69
- if (!(stripeResponse === null || stripeResponse === void 0 ? void 0 : stripeResponse.data)) {
70
- return [2 /*return*/, res.status(404)];
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
- console.warn("The provide Stripe method of '".concat(stripeMethod, "' is not a part of the Stripe API."));
75
- return [2 /*return*/, next()];
76
- case 4: return [3 /*break*/, 6];
77
- case 5:
78
- console.warn('You must provide a Stripe method to call.');
79
- return [2 /*return*/, next()];
80
- case 6: return [3 /*break*/, 8];
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
  }); };
@@ -1 +1 @@
1
- {"version":3,"file":"rest.js","sourceRoot":"","sources":["../../src/routes/rest.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,yCAA2C;AAC3C,kDAA4B;AAE5B,0DAAmC;AAG5B,IAAM,UAAU,GAAG,UACxB,GAAmB,EACnB,GAAa,EACb,IAAS,EACT,YAA0B;;;;;;gBAElB,eAAe,GAAK,YAAY,gBAAjB,CAAkB;gBAEnC,MAAM,GAAG,IAAI,gBAAM,CAAC,eAAe,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC;;;;gBAIrE,KAKE,GAAG,KAFJ,EAFC,YAAY,kBAAA,EACZ,UAAU,gBAAA,EAEZ,IAAI,GACF,GAAG,KADD,CACE;gBAER,IAAI,CAAC,IAAI,EAAE,EAAE,+CAA+C;oBAC1D,MAAM,IAAI,kBAAS,EAAE,CAAC;iBACvB;qBAEG,CAAA,OAAO,YAAY,KAAK,QAAQ,CAAA,EAAhC,wBAAgC;gBAC5B,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAiB,CAAC;gBAC5D,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;gBACvC,WAAW,GAAG,IAAA,oBAAS,EAAC,MAAM,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;qBAEpE,CAAA,OAAO,WAAW,KAAK,UAAU,CAAA,EAAjC,wBAAiC;gBACZ,qBAAM,WAAW,CAAC,UAAU,CAAC,EAAA;;gBAA9C,cAAc,GAAG,SAA6B;gBAEpD,IAAI,CAAC,CAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,IAAI,CAAA,EAAE;oBACzB,sBAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAC;iBACxB;gBAED,sBAAO,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,EAAC;;gBAEhC,OAAO,CAAC,IAAI,CAAC,wCAAiC,YAAY,uCAAoC,CAAC,CAAC;gBAChG,sBAAO,IAAI,EAAE,EAAC;;;gBAGhB,OAAO,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;gBAC1D,sBAAO,IAAI,EAAE,EAAC;;;;gBAIhB,sBAAO,IAAI,CAAC,KAAG,CAAC,EAAC;;;;KAEpB,CAAC;AAhDW,QAAA,UAAU,cAgDrB"}
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 WebhookHandler = (event: any, stripe: Stripe, stripeConfig: StripeConfig) => void;
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]: WebhookHandler;
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,2 @@
1
+ import { StripeProxy } from '../types';
2
+ export declare const stripeProxy: StripeProxy;
@@ -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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-stripe",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "homepage:": "https://payloadcms.com",
5
5
  "repository": "git@github.com:payloadcms/plugin-stripe.git",
6
6
  "description": "Stripe plugin for Payload CMS",