@deenruv/payments-plugin 1.0.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/LICENSE +23 -0
- package/README.md +157 -0
- package/package/braintree/braintree-common.d.ts +11 -0
- package/package/braintree/braintree-common.js +79 -0
- package/package/braintree/braintree-common.js.map +1 -0
- package/package/braintree/braintree.handler.d.ts +28 -0
- package/package/braintree/braintree.handler.js +147 -0
- package/package/braintree/braintree.handler.js.map +1 -0
- package/package/braintree/braintree.plugin.d.ts +238 -0
- package/package/braintree/braintree.plugin.js +294 -0
- package/package/braintree/braintree.plugin.js.map +1 -0
- package/package/braintree/braintree.resolver.d.ts +14 -0
- package/package/braintree/braintree.resolver.js +109 -0
- package/package/braintree/braintree.resolver.js.map +1 -0
- package/package/braintree/constants.d.ts +2 -0
- package/package/braintree/constants.js +6 -0
- package/package/braintree/constants.js.map +1 -0
- package/package/braintree/index.d.ts +5 -0
- package/package/braintree/index.js +22 -0
- package/package/braintree/index.js.map +1 -0
- package/package/braintree/types.d.ts +94 -0
- package/package/braintree/types.js +4 -0
- package/package/braintree/types.js.map +1 -0
- package/package/index.d.ts +4 -0
- package/package/index.js +8 -0
- package/package/index.js.map +1 -0
- package/package/mollie/api-extensions.d.ts +2 -0
- package/package/mollie/api-extensions.js +88 -0
- package/package/mollie/api-extensions.js.map +1 -0
- package/package/mollie/constants.d.ts +2 -0
- package/package/mollie/constants.js +6 -0
- package/package/mollie/constants.js.map +1 -0
- package/package/mollie/custom-fields.d.ts +7 -0
- package/package/mollie/custom-fields.js +12 -0
- package/package/mollie/custom-fields.js.map +1 -0
- package/package/mollie/extended-mollie-client.d.ts +51 -0
- package/package/mollie/extended-mollie-client.js +39 -0
- package/package/mollie/extended-mollie-client.js.map +1 -0
- package/package/mollie/graphql/generated-shop-types.d.ts +3212 -0
- package/package/mollie/graphql/generated-shop-types.js +977 -0
- package/package/mollie/graphql/generated-shop-types.js.map +1 -0
- package/package/mollie/index.d.ts +3 -0
- package/package/mollie/index.js +23 -0
- package/package/mollie/index.js.map +1 -0
- package/package/mollie/mollie.common-resolver.d.ts +9 -0
- package/package/mollie/mollie.common-resolver.js +55 -0
- package/package/mollie/mollie.common-resolver.js.map +1 -0
- package/package/mollie/mollie.controller.d.ts +10 -0
- package/package/mollie/mollie.controller.js +71 -0
- package/package/mollie/mollie.controller.js.map +1 -0
- package/package/mollie/mollie.handler.d.ts +36 -0
- package/package/mollie/mollie.handler.js +141 -0
- package/package/mollie/mollie.handler.js.map +1 -0
- package/package/mollie/mollie.helpers.d.ts +33 -0
- package/package/mollie/mollie.helpers.js +147 -0
- package/package/mollie/mollie.helpers.js.map +1 -0
- package/package/mollie/mollie.plugin.d.ts +176 -0
- package/package/mollie/mollie.plugin.js +167 -0
- package/package/mollie/mollie.plugin.js.map +1 -0
- package/package/mollie/mollie.service.d.ts +64 -0
- package/package/mollie/mollie.service.js +438 -0
- package/package/mollie/mollie.service.js.map +1 -0
- package/package/mollie/mollie.shop-resolver.d.ts +8 -0
- package/package/mollie/mollie.shop-resolver.js +40 -0
- package/package/mollie/mollie.shop-resolver.js.map +1 -0
- package/package/stripe/constants.d.ts +2 -0
- package/package/stripe/constants.js +6 -0
- package/package/stripe/constants.js.map +1 -0
- package/package/stripe/index.d.ts +1 -0
- package/package/stripe/index.js +6 -0
- package/package/stripe/index.js.map +1 -0
- package/package/stripe/metadata-sanitize.d.ts +13 -0
- package/package/stripe/metadata-sanitize.js +33 -0
- package/package/stripe/metadata-sanitize.js.map +1 -0
- package/package/stripe/raw-body.middleware.d.ts +6 -0
- package/package/stripe/raw-body.middleware.js +18 -0
- package/package/stripe/raw-body.middleware.js.map +1 -0
- package/package/stripe/stripe-client.d.ts +9 -0
- package/package/stripe/stripe-client.js +21 -0
- package/package/stripe/stripe-client.js.map +1 -0
- package/package/stripe/stripe-utils.d.ts +19 -0
- package/package/stripe/stripe-utils.js +40 -0
- package/package/stripe/stripe-utils.js.map +1 -0
- package/package/stripe/stripe.controller.d.ts +15 -0
- package/package/stripe/stripe.controller.js +135 -0
- package/package/stripe/stripe.controller.js.map +1 -0
- package/package/stripe/stripe.handler.d.ts +30 -0
- package/package/stripe/stripe.handler.js +103 -0
- package/package/stripe/stripe.handler.js.map +1 -0
- package/package/stripe/stripe.plugin.d.ts +158 -0
- package/package/stripe/stripe.plugin.js +218 -0
- package/package/stripe/stripe.plugin.js.map +1 -0
- package/package/stripe/stripe.resolver.d.ts +8 -0
- package/package/stripe/stripe.resolver.js +48 -0
- package/package/stripe/stripe.resolver.js.map +1 -0
- package/package/stripe/stripe.service.d.ts +28 -0
- package/package/stripe/stripe.service.js +149 -0
- package/package/stripe/stripe.service.js.map +1 -0
- package/package/stripe/types.d.ts +137 -0
- package/package/stripe/types.js +4 -0
- package/package/stripe/types.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var StripePlugin_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.StripePlugin = void 0;
|
|
11
|
+
const core_1 = require("@deenruv/core");
|
|
12
|
+
const graphql_tag_1 = require("graphql-tag");
|
|
13
|
+
const constants_1 = require("./constants");
|
|
14
|
+
const raw_body_middleware_1 = require("./raw-body.middleware");
|
|
15
|
+
const stripe_controller_1 = require("./stripe.controller");
|
|
16
|
+
const stripe_handler_1 = require("./stripe.handler");
|
|
17
|
+
const stripe_resolver_1 = require("./stripe.resolver");
|
|
18
|
+
const stripe_service_1 = require("./stripe.service");
|
|
19
|
+
/**
|
|
20
|
+
* @description
|
|
21
|
+
* Plugin to enable payments through [Stripe](https://stripe.com/docs) via the Payment Intents API.
|
|
22
|
+
*
|
|
23
|
+
* ## Requirements
|
|
24
|
+
*
|
|
25
|
+
* 1. You will need to create a Stripe account and get your secret key in the dashboard.
|
|
26
|
+
* 2. Create a webhook endpoint in the Stripe dashboard (Developers -> Webhooks, "Add an endpoint") which listens to the `payment_intent.succeeded`
|
|
27
|
+
* and `payment_intent.payment_failed` events. The URL should be `https://my-server.com/payments/stripe`, where
|
|
28
|
+
* `my-server.com` is the host of your Deenruv server. *Note:* for local development, you'll need to use
|
|
29
|
+
* the Stripe CLI to test your webhook locally. See the _local development_ section below.
|
|
30
|
+
* 3. Get the signing secret for the newly created webhook.
|
|
31
|
+
* 4. Install the Payments plugin and the Stripe Node library:
|
|
32
|
+
*
|
|
33
|
+
* `yarn add \@deenruv/payments-plugin stripe`
|
|
34
|
+
*
|
|
35
|
+
* or
|
|
36
|
+
*
|
|
37
|
+
* `npm install \@deenruv/payments-plugin stripe`
|
|
38
|
+
*
|
|
39
|
+
* ## Setup
|
|
40
|
+
*
|
|
41
|
+
* 1. Add the plugin to your DeenruvConfig `plugins` array:
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { StripePlugin } from '\@deenruv/payments-plugin/package/stripe';
|
|
44
|
+
*
|
|
45
|
+
* // ...
|
|
46
|
+
*
|
|
47
|
+
* plugins: [
|
|
48
|
+
* StripePlugin.init({
|
|
49
|
+
* // This prevents different customers from using the same PaymentIntent
|
|
50
|
+
* storeCustomersInStripe: true,
|
|
51
|
+
* }),
|
|
52
|
+
* ]
|
|
53
|
+
* ````
|
|
54
|
+
* For all the plugin options, see the {@link StripePluginOptions} type.
|
|
55
|
+
* 2. Create a new PaymentMethod in the Admin UI, and select "Stripe payments" as the handler.
|
|
56
|
+
* 3. Set the webhook secret and API key in the PaymentMethod form.
|
|
57
|
+
*
|
|
58
|
+
* ## Storefront usage
|
|
59
|
+
*
|
|
60
|
+
* The plugin is designed to work with the [Custom payment flow](https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements).
|
|
61
|
+
* In this flow, Stripe provides libraries which handle the payment UI and confirmation for you. You can install it in your storefront project
|
|
62
|
+
* with:
|
|
63
|
+
*
|
|
64
|
+
* ```shell
|
|
65
|
+
* yarn add \@stripe/stripe-js
|
|
66
|
+
* # or
|
|
67
|
+
* npm install \@stripe/stripe-js
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* If you are using React, you should also consider installing `@stripe/react-stripe-js`, which is a wrapper around Stripe Elements.
|
|
71
|
+
*
|
|
72
|
+
* The high-level workflow is:
|
|
73
|
+
* 1. Create a "payment intent" on the server by executing the `createStripePaymentIntent` mutation which is exposed by this plugin.
|
|
74
|
+
* 2. Use the returned client secret to instantiate the Stripe Payment Element:
|
|
75
|
+
* ```ts
|
|
76
|
+
* import { Elements } from '\@stripe/react-stripe-js';
|
|
77
|
+
* import { loadStripe, Stripe } from '\@stripe/stripe-js';
|
|
78
|
+
* import { CheckoutForm } from './CheckoutForm';
|
|
79
|
+
*
|
|
80
|
+
* const stripePromise = getStripe('pk_test_....wr83u');
|
|
81
|
+
*
|
|
82
|
+
* type StripePaymentsProps = {
|
|
83
|
+
* clientSecret: string;
|
|
84
|
+
* orderCode: string;
|
|
85
|
+
* }
|
|
86
|
+
*
|
|
87
|
+
* export function StripePayments({ clientSecret, orderCode }: StripePaymentsProps) {
|
|
88
|
+
* const options = {
|
|
89
|
+
* // passing the client secret obtained from the server
|
|
90
|
+
* clientSecret,
|
|
91
|
+
* }
|
|
92
|
+
* return (
|
|
93
|
+
* <Elements stripe={stripePromise} options={options}>
|
|
94
|
+
* <CheckoutForm orderCode={orderCode} />
|
|
95
|
+
* </Elements>
|
|
96
|
+
* );
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
* ```ts
|
|
100
|
+
* // CheckoutForm.tsx
|
|
101
|
+
* import { useStripe, useElements, PaymentElement } from '\@stripe/react-stripe-js';
|
|
102
|
+
* import { FormEvent } from 'react';
|
|
103
|
+
*
|
|
104
|
+
* export const CheckoutForm = ({ orderCode }: { orderCode: string }) => {
|
|
105
|
+
* const stripe = useStripe();
|
|
106
|
+
* const elements = useElements();
|
|
107
|
+
*
|
|
108
|
+
* const handleSubmit = async (event: FormEvent) => {
|
|
109
|
+
* // We don't want to let default form submission happen here,
|
|
110
|
+
* // which would refresh the page.
|
|
111
|
+
* event.preventDefault();
|
|
112
|
+
*
|
|
113
|
+
* if (!stripe || !elements) {
|
|
114
|
+
* // Stripe.js has not yet loaded.
|
|
115
|
+
* // Make sure to disable form submission until Stripe.js has loaded.
|
|
116
|
+
* return;
|
|
117
|
+
* }
|
|
118
|
+
*
|
|
119
|
+
* const result = await stripe.confirmPayment({
|
|
120
|
+
* //`Elements` instance that was used to create the Payment Element
|
|
121
|
+
* elements,
|
|
122
|
+
* confirmParams: {
|
|
123
|
+
* return_url: location.origin + `/checkout/confirmation/${orderCode}`,
|
|
124
|
+
* },
|
|
125
|
+
* });
|
|
126
|
+
*
|
|
127
|
+
* if (result.error) {
|
|
128
|
+
* // Show error to your customer (for example, payment details incomplete)
|
|
129
|
+
* console.log(result.error.message);
|
|
130
|
+
* } else {
|
|
131
|
+
* // Your customer will be redirected to your `return_url`. For some payment
|
|
132
|
+
* // methods like iDEAL, your customer will be redirected to an intermediate
|
|
133
|
+
* // site first to authorize the payment, then redirected to the `return_url`.
|
|
134
|
+
* }
|
|
135
|
+
* };
|
|
136
|
+
*
|
|
137
|
+
* return (
|
|
138
|
+
* <form onSubmit={handleSubmit}>
|
|
139
|
+
* <PaymentElement />
|
|
140
|
+
* <button disabled={!stripe}>Submit</button>
|
|
141
|
+
* </form>
|
|
142
|
+
* );
|
|
143
|
+
* };
|
|
144
|
+
* ```
|
|
145
|
+
* 3. Once the form is submitted and Stripe processes the payment, the webhook takes care of updating the order without additional action
|
|
146
|
+
* in the storefront. As in the code above, the customer will be redirected to `/checkout/confirmation/${orderCode}`.
|
|
147
|
+
*
|
|
148
|
+
* :::info
|
|
149
|
+
* A full working storefront example of the Stripe integration can be found in the
|
|
150
|
+
* [Remix Starter repo](https://github.com/deenruv-ecommerce/storefront-remix-starter/tree/master/app/components/checkout/stripe)
|
|
151
|
+
* :::
|
|
152
|
+
*
|
|
153
|
+
* ## Local development
|
|
154
|
+
*
|
|
155
|
+
* 1. Download & install the Stripe CLI: https://stripe.com/docs/stripe-cli
|
|
156
|
+
* 2. From your Stripe dashboard, go to Developers -> Webhooks and click "Add an endpoint" and follow the instructions
|
|
157
|
+
* under "Test in a local environment".
|
|
158
|
+
* 3. The Stripe CLI command will look like
|
|
159
|
+
* ```shell
|
|
160
|
+
* stripe listen --forward-to localhost:3000/payments/stripe
|
|
161
|
+
* ```
|
|
162
|
+
* 4. The Stripe CLI will create a webhook signing secret you can then use in your config of the StripePlugin.
|
|
163
|
+
*
|
|
164
|
+
* @docsCategory core plugins/PaymentsPlugin
|
|
165
|
+
* @docsPage StripePlugin
|
|
166
|
+
*/
|
|
167
|
+
let StripePlugin = exports.StripePlugin = StripePlugin_1 = class StripePlugin {
|
|
168
|
+
/**
|
|
169
|
+
* @description
|
|
170
|
+
* Initialize the Stripe payment plugin
|
|
171
|
+
*/
|
|
172
|
+
static init(options) {
|
|
173
|
+
this.options = options;
|
|
174
|
+
return StripePlugin_1;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
exports.StripePlugin = StripePlugin = StripePlugin_1 = __decorate([
|
|
178
|
+
(0, core_1.DeenruvPlugin)({
|
|
179
|
+
imports: [core_1.PluginCommonModule],
|
|
180
|
+
controllers: [stripe_controller_1.StripeController],
|
|
181
|
+
providers: [
|
|
182
|
+
{
|
|
183
|
+
provide: constants_1.STRIPE_PLUGIN_OPTIONS,
|
|
184
|
+
useFactory: () => StripePlugin_1.options,
|
|
185
|
+
},
|
|
186
|
+
stripe_service_1.StripeService,
|
|
187
|
+
],
|
|
188
|
+
configuration: (config) => {
|
|
189
|
+
config.paymentOptions.paymentMethodHandlers.push(stripe_handler_1.stripePaymentMethodHandler);
|
|
190
|
+
config.apiOptions.middleware.push({
|
|
191
|
+
route: "/payments/stripe",
|
|
192
|
+
handler: raw_body_middleware_1.rawBodyMiddleware,
|
|
193
|
+
beforeListen: true,
|
|
194
|
+
});
|
|
195
|
+
if (StripePlugin_1.options.storeCustomersInStripe) {
|
|
196
|
+
config.customFields.Customer.push({
|
|
197
|
+
name: "stripeCustomerId",
|
|
198
|
+
type: "string",
|
|
199
|
+
label: [{ languageCode: core_1.LanguageCode.en, value: "Stripe Customer ID" }],
|
|
200
|
+
nullable: true,
|
|
201
|
+
public: false,
|
|
202
|
+
readonly: true,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return config;
|
|
206
|
+
},
|
|
207
|
+
shopApiExtensions: {
|
|
208
|
+
schema: (0, graphql_tag_1.gql) `
|
|
209
|
+
extend type Mutation {
|
|
210
|
+
createStripePaymentIntent: String!
|
|
211
|
+
}
|
|
212
|
+
`,
|
|
213
|
+
resolvers: [stripe_resolver_1.StripeResolver],
|
|
214
|
+
},
|
|
215
|
+
compatibility: "^0.0.0",
|
|
216
|
+
})
|
|
217
|
+
], StripePlugin);
|
|
218
|
+
//# sourceMappingURL=stripe.plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe.plugin.js","sourceRoot":"","sources":["../../src/stripe/stripe.plugin.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,wCAKuB;AAEvB,6CAAkC;AAElC,2CAAoD;AACpD,+DAA0D;AAC1D,2DAAuD;AACvD,qDAA8D;AAC9D,uDAAmD;AACnD,qDAAiD;AAGjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmJG;AA6CI,IAAM,YAAY,2CAAlB,MAAM,YAAY;IAGvB;;;OAGG;IACH,MAAM,CAAC,IAAI,CAAC,OAA4B;QACtC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,OAAO,cAAY,CAAC;IACtB,CAAC;CACF,CAAA;uBAXY,YAAY;IA5CxB,IAAA,oBAAa,EAAC;QACb,OAAO,EAAE,CAAC,yBAAkB,CAAC;QAC7B,WAAW,EAAE,CAAC,oCAAgB,CAAC;QAC/B,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,iCAAqB;gBAC9B,UAAU,EAAE,GAAwB,EAAE,CAAC,cAAY,CAAC,OAAO;aAC5D;YACD,8BAAa;SACd;QACD,aAAa,EAAE,CAAC,MAAM,EAAE,EAAE;YACxB,MAAM,CAAC,cAAc,CAAC,qBAAqB,CAAC,IAAI,CAC9C,2CAA0B,CAC3B,CAAC;YAEF,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC;gBAChC,KAAK,EAAE,kBAAkB;gBACzB,OAAO,EAAE,uCAAiB;gBAC1B,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;YAEH,IAAI,cAAY,CAAC,OAAO,CAAC,sBAAsB,EAAE;gBAC/C,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAChC,IAAI,EAAE,kBAAkB;oBACxB,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE,CAAC,EAAE,YAAY,EAAE,mBAAY,CAAC,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;oBACvE,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE,KAAK;oBACb,QAAQ,EAAE,IAAI;iBACf,CAAC,CAAC;aACJ;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,iBAAiB,EAAE;YACjB,MAAM,EAAE,IAAA,iBAAG,EAAA;;;;KAIV;YACD,SAAS,EAAE,CAAC,gCAAc,CAAC;SAC5B;QACD,aAAa,EAAE,QAAQ;KACxB,CAAC;GACW,YAAY,CAWxB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ActiveOrderService, RequestContext } from "@deenruv/core";
|
|
2
|
+
import { StripeService } from "./stripe.service";
|
|
3
|
+
export declare class StripeResolver {
|
|
4
|
+
private stripeService;
|
|
5
|
+
private activeOrderService;
|
|
6
|
+
constructor(stripeService: StripeService, activeOrderService: ActiveOrderService);
|
|
7
|
+
createStripePaymentIntent(ctx: RequestContext): Promise<string>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.StripeResolver = void 0;
|
|
16
|
+
const graphql_1 = require("@nestjs/graphql");
|
|
17
|
+
const core_1 = require("@deenruv/core");
|
|
18
|
+
const stripe_service_1 = require("./stripe.service");
|
|
19
|
+
let StripeResolver = exports.StripeResolver = class StripeResolver {
|
|
20
|
+
constructor(stripeService, activeOrderService) {
|
|
21
|
+
this.stripeService = stripeService;
|
|
22
|
+
this.activeOrderService = activeOrderService;
|
|
23
|
+
}
|
|
24
|
+
async createStripePaymentIntent(ctx) {
|
|
25
|
+
if (!ctx.authorizedAsOwnerOnly) {
|
|
26
|
+
throw new core_1.UnauthorizedError();
|
|
27
|
+
}
|
|
28
|
+
const sessionOrder = await this.activeOrderService.getActiveOrder(ctx, undefined);
|
|
29
|
+
if (!sessionOrder) {
|
|
30
|
+
throw new core_1.UserInputError("No active order found for session");
|
|
31
|
+
}
|
|
32
|
+
return this.stripeService.createPaymentIntent(ctx, sessionOrder);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, graphql_1.Mutation)(),
|
|
37
|
+
(0, core_1.Allow)(core_1.Permission.Owner),
|
|
38
|
+
__param(0, (0, core_1.Ctx)()),
|
|
39
|
+
__metadata("design:type", Function),
|
|
40
|
+
__metadata("design:paramtypes", [core_1.RequestContext]),
|
|
41
|
+
__metadata("design:returntype", Promise)
|
|
42
|
+
], StripeResolver.prototype, "createStripePaymentIntent", null);
|
|
43
|
+
exports.StripeResolver = StripeResolver = __decorate([
|
|
44
|
+
(0, graphql_1.Resolver)(),
|
|
45
|
+
__metadata("design:paramtypes", [stripe_service_1.StripeService,
|
|
46
|
+
core_1.ActiveOrderService])
|
|
47
|
+
], StripeResolver);
|
|
48
|
+
//# sourceMappingURL=stripe.resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe.resolver.js","sourceRoot":"","sources":["../../src/stripe/stripe.resolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6CAAqD;AACrD,wCAQuB;AAEvB,qDAAiD;AAG1C,IAAM,cAAc,4BAApB,MAAM,cAAc;IACzB,YACU,aAA4B,EAC5B,kBAAsC;QADtC,kBAAa,GAAb,aAAa,CAAe;QAC5B,uBAAkB,GAAlB,kBAAkB,CAAoB;IAC7C,CAAC;IAIE,AAAN,KAAK,CAAC,yBAAyB,CAAQ,GAAmB;QACxD,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE;YAC9B,MAAM,IAAI,wBAAiB,EAAE,CAAC;SAC/B;QACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAC/D,GAAG,EACH,SAAS,CACV,CAAC;QACF,IAAI,CAAC,YAAY,EAAE;YACjB,MAAM,IAAI,qBAAc,CAAC,mCAAmC,CAAC,CAAC;SAC/D;QACD,OAAO,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACnE,CAAC;CACF,CAAA;AAbO;IAFL,IAAA,kBAAQ,GAAE;IACV,IAAA,YAAK,EAAC,iBAAU,CAAC,KAAK,CAAC;IACS,WAAA,IAAA,UAAG,GAAE,CAAA;;qCAAM,qBAAc;;+DAYzD;yBApBU,cAAc;IAD1B,IAAA,kBAAQ,GAAE;qCAGgB,8BAAa;QACR,yBAAkB;GAHrC,cAAc,CAqB1B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { ModuleRef } from "@nestjs/core";
|
|
4
|
+
import { Order, Payment, PaymentMethodService, RequestContext, TransactionalConnection } from "@deenruv/core";
|
|
5
|
+
import Stripe from "stripe";
|
|
6
|
+
import { DeenruvStripeClient } from "./stripe-client";
|
|
7
|
+
import { StripePluginOptions } from "./types";
|
|
8
|
+
export declare class StripeService {
|
|
9
|
+
private options;
|
|
10
|
+
private connection;
|
|
11
|
+
private paymentMethodService;
|
|
12
|
+
private moduleRef;
|
|
13
|
+
constructor(options: StripePluginOptions, connection: TransactionalConnection, paymentMethodService: PaymentMethodService, moduleRef: ModuleRef);
|
|
14
|
+
createPaymentIntent(ctx: RequestContext, order: Order): Promise<string>;
|
|
15
|
+
constructEventFromPayload(ctx: RequestContext, order: Order, payload: Buffer, signature: string): Promise<Stripe.Event>;
|
|
16
|
+
createRefund(ctx: RequestContext, order: Order, payment: Payment, amount: number): Promise<Stripe.Response<Stripe.Refund>>;
|
|
17
|
+
/**
|
|
18
|
+
* Get Stripe client based on eligible payment methods for order
|
|
19
|
+
*/
|
|
20
|
+
getStripeClient(ctx: RequestContext, order: Order): Promise<DeenruvStripeClient>;
|
|
21
|
+
private findOrThrowArgValue;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the stripeCustomerId if the Customer has one. If that's not the case, queries Stripe to check
|
|
24
|
+
* if the customer is already registered, in which case it saves the id as stripeCustomerId and returns it.
|
|
25
|
+
* Otherwise, creates a new Customer record in Stripe and returns the generated id.
|
|
26
|
+
*/
|
|
27
|
+
private getStripeCustomerId;
|
|
28
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.StripeService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const core_1 = require("@nestjs/core");
|
|
18
|
+
const core_2 = require("@deenruv/core");
|
|
19
|
+
const constants_1 = require("./constants");
|
|
20
|
+
const metadata_sanitize_1 = require("./metadata-sanitize");
|
|
21
|
+
const stripe_client_1 = require("./stripe-client");
|
|
22
|
+
const stripe_utils_1 = require("./stripe-utils");
|
|
23
|
+
const stripe_handler_1 = require("./stripe.handler");
|
|
24
|
+
let StripeService = exports.StripeService = class StripeService {
|
|
25
|
+
constructor(options, connection, paymentMethodService, moduleRef) {
|
|
26
|
+
this.options = options;
|
|
27
|
+
this.connection = connection;
|
|
28
|
+
this.paymentMethodService = paymentMethodService;
|
|
29
|
+
this.moduleRef = moduleRef;
|
|
30
|
+
}
|
|
31
|
+
async createPaymentIntent(ctx, order) {
|
|
32
|
+
var _a, _b, _c;
|
|
33
|
+
let customerId;
|
|
34
|
+
const stripe = await this.getStripeClient(ctx, order);
|
|
35
|
+
if (this.options.storeCustomersInStripe && ctx.activeUserId) {
|
|
36
|
+
customerId = await this.getStripeCustomerId(ctx, order);
|
|
37
|
+
}
|
|
38
|
+
const amountInMinorUnits = (0, stripe_utils_1.getAmountInStripeMinorUnits)(order);
|
|
39
|
+
const additionalParams = await ((_b = (_a = this.options).paymentIntentCreateParams) === null || _b === void 0 ? void 0 : _b.call(_a, new core_2.Injector(this.moduleRef), ctx, order));
|
|
40
|
+
const metadata = (0, metadata_sanitize_1.sanitizeMetadata)(Object.assign(Object.assign({}, (typeof this.options.metadata === "function"
|
|
41
|
+
? await this.options.metadata(new core_2.Injector(this.moduleRef), ctx, order)
|
|
42
|
+
: {})), { channelToken: ctx.channel.token, orderId: order.id, orderCode: order.code }));
|
|
43
|
+
const allMetadata = Object.assign(Object.assign({}, metadata), (0, metadata_sanitize_1.sanitizeMetadata)((_c = additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.metadata) !== null && _c !== void 0 ? _c : {}));
|
|
44
|
+
const { client_secret } = await stripe.paymentIntents.create(Object.assign(Object.assign({ amount: amountInMinorUnits, currency: order.currencyCode.toLowerCase(), customer: customerId, automatic_payment_methods: {
|
|
45
|
+
enabled: true,
|
|
46
|
+
} }, (additionalParams !== null && additionalParams !== void 0 ? additionalParams : {})), { metadata: allMetadata }), { idempotencyKey: `${order.code}_${amountInMinorUnits}` });
|
|
47
|
+
if (!client_secret) {
|
|
48
|
+
// This should never happen
|
|
49
|
+
core_2.Logger.warn(`Payment intent creation for order ${order.code} did not return client secret`, constants_1.loggerCtx);
|
|
50
|
+
throw Error("Failed to create payment intent");
|
|
51
|
+
}
|
|
52
|
+
return client_secret !== null && client_secret !== void 0 ? client_secret : undefined;
|
|
53
|
+
}
|
|
54
|
+
async constructEventFromPayload(ctx, order, payload, signature) {
|
|
55
|
+
const stripe = await this.getStripeClient(ctx, order);
|
|
56
|
+
return stripe.webhooks.constructEvent(payload, signature, stripe.webhookSecret);
|
|
57
|
+
}
|
|
58
|
+
async createRefund(ctx, order, payment, amount) {
|
|
59
|
+
const stripe = await this.getStripeClient(ctx, order);
|
|
60
|
+
return stripe.refunds.create({
|
|
61
|
+
payment_intent: payment.transactionId,
|
|
62
|
+
amount,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get Stripe client based on eligible payment methods for order
|
|
67
|
+
*/
|
|
68
|
+
async getStripeClient(ctx, order) {
|
|
69
|
+
const [eligiblePaymentMethods, paymentMethods] = await Promise.all([
|
|
70
|
+
this.paymentMethodService.getEligiblePaymentMethods(ctx, order),
|
|
71
|
+
this.paymentMethodService.findAll(ctx, {
|
|
72
|
+
filter: {
|
|
73
|
+
enabled: { eq: true },
|
|
74
|
+
},
|
|
75
|
+
}),
|
|
76
|
+
]);
|
|
77
|
+
const stripePaymentMethod = paymentMethods.items.find((pm) => pm.handler.code === stripe_handler_1.stripePaymentMethodHandler.code);
|
|
78
|
+
if (!stripePaymentMethod) {
|
|
79
|
+
throw new core_2.UserInputError("No enabled Stripe payment method found");
|
|
80
|
+
}
|
|
81
|
+
const isEligible = eligiblePaymentMethods.some((pm) => pm.code === stripePaymentMethod.code);
|
|
82
|
+
if (!isEligible) {
|
|
83
|
+
throw new core_2.UserInputError(`Stripe payment method is not eligible for order ${order.code}`);
|
|
84
|
+
}
|
|
85
|
+
const apiKey = this.findOrThrowArgValue(stripePaymentMethod.handler.args, "apiKey");
|
|
86
|
+
const webhookSecret = this.findOrThrowArgValue(stripePaymentMethod.handler.args, "webhookSecret");
|
|
87
|
+
return new stripe_client_1.DeenruvStripeClient(apiKey, webhookSecret);
|
|
88
|
+
}
|
|
89
|
+
findOrThrowArgValue(args, name) {
|
|
90
|
+
var _a;
|
|
91
|
+
const value = (_a = args.find((arg) => arg.name === name)) === null || _a === void 0 ? void 0 : _a.value;
|
|
92
|
+
if (!value) {
|
|
93
|
+
throw Error(`No argument named '${name}' found!`);
|
|
94
|
+
}
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Returns the stripeCustomerId if the Customer has one. If that's not the case, queries Stripe to check
|
|
99
|
+
* if the customer is already registered, in which case it saves the id as stripeCustomerId and returns it.
|
|
100
|
+
* Otherwise, creates a new Customer record in Stripe and returns the generated id.
|
|
101
|
+
*/
|
|
102
|
+
async getStripeCustomerId(ctx, activeOrder) {
|
|
103
|
+
var _a, _b;
|
|
104
|
+
const [stripe, order] = await Promise.all([
|
|
105
|
+
this.getStripeClient(ctx, activeOrder),
|
|
106
|
+
// Load relation with customer not available in the response from activeOrderService.getOrderFromContext()
|
|
107
|
+
this.connection.getRepository(ctx, core_2.Order).findOne({
|
|
108
|
+
where: { id: activeOrder.id },
|
|
109
|
+
relations: ["customer"],
|
|
110
|
+
}),
|
|
111
|
+
]);
|
|
112
|
+
if (!order || !order.customer) {
|
|
113
|
+
// This should never happen
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
const { customer } = order;
|
|
117
|
+
if (customer.customFields.stripeCustomerId) {
|
|
118
|
+
return customer.customFields.stripeCustomerId;
|
|
119
|
+
}
|
|
120
|
+
let stripeCustomerId;
|
|
121
|
+
const stripeCustomers = await stripe.customers.list({
|
|
122
|
+
email: customer.emailAddress,
|
|
123
|
+
});
|
|
124
|
+
if (stripeCustomers.data.length > 0) {
|
|
125
|
+
stripeCustomerId = stripeCustomers.data[0].id;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const additionalParams = await ((_b = (_a = this.options).customerCreateParams) === null || _b === void 0 ? void 0 : _b.call(_a, new core_2.Injector(this.moduleRef), ctx, order));
|
|
129
|
+
const newStripeCustomer = await stripe.customers.create(Object.assign(Object.assign({ email: customer.emailAddress, name: `${customer.firstName} ${customer.lastName}` }, (additionalParams !== null && additionalParams !== void 0 ? additionalParams : {})), ((additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.metadata)
|
|
130
|
+
? { metadata: (0, metadata_sanitize_1.sanitizeMetadata)(additionalParams.metadata) }
|
|
131
|
+
: {})));
|
|
132
|
+
stripeCustomerId = newStripeCustomer.id;
|
|
133
|
+
core_2.Logger.info(`Created Stripe Customer record for customerId ${customer.id}`, constants_1.loggerCtx);
|
|
134
|
+
}
|
|
135
|
+
customer.customFields.stripeCustomerId = stripeCustomerId;
|
|
136
|
+
await this.connection
|
|
137
|
+
.getRepository(ctx, core_2.Customer)
|
|
138
|
+
.save(customer, { reload: false });
|
|
139
|
+
return stripeCustomerId;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
exports.StripeService = StripeService = __decorate([
|
|
143
|
+
(0, common_1.Injectable)(),
|
|
144
|
+
__param(0, (0, common_1.Inject)(constants_1.STRIPE_PLUGIN_OPTIONS)),
|
|
145
|
+
__metadata("design:paramtypes", [Object, core_2.TransactionalConnection,
|
|
146
|
+
core_2.PaymentMethodService,
|
|
147
|
+
core_1.ModuleRef])
|
|
148
|
+
], StripeService);
|
|
149
|
+
//# sourceMappingURL=stripe.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe.service.js","sourceRoot":"","sources":["../../src/stripe/stripe.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import "@deenruv/core/dist/entity/custom-entity-fields";
|
|
4
|
+
import type { Injector, Order, RequestContext } from "@deenruv/core";
|
|
5
|
+
import type { Request } from "express";
|
|
6
|
+
import type Stripe from "stripe";
|
|
7
|
+
declare module "@deenruv/core/dist/entity/custom-entity-fields" {
|
|
8
|
+
interface CustomCustomerFields {
|
|
9
|
+
stripeCustomerId?: string;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
type AdditionalPaymentIntentCreateParams = Partial<Omit<Stripe.PaymentIntentCreateParams, "amount" | "currency" | "customer">>;
|
|
13
|
+
type AdditionalCustomerCreateParams = Partial<Omit<Stripe.CustomerCreateParams, "email">>;
|
|
14
|
+
/**
|
|
15
|
+
* @description
|
|
16
|
+
* Configuration options for the Stripe payments plugin.
|
|
17
|
+
*
|
|
18
|
+
* @docsCategory core plugins/PaymentsPlugin
|
|
19
|
+
* @docsPage StripePlugin
|
|
20
|
+
*/
|
|
21
|
+
export interface StripePluginOptions {
|
|
22
|
+
/**
|
|
23
|
+
* @description
|
|
24
|
+
* If set to `true`, a [Customer](https://stripe.com/docs/api/customers) object will be created in Stripe - if
|
|
25
|
+
* it doesn't already exist - for authenticated users, which prevents payment methods attached to other Customers
|
|
26
|
+
* to be used with the same PaymentIntent. This is done by adding a custom field to the Customer entity to store
|
|
27
|
+
* the Stripe customer ID, so switching this on will require a database migration / synchronization.
|
|
28
|
+
*
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
storeCustomersInStripe?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* @description
|
|
34
|
+
* Attach extra metadata to Stripe payment intent creation call.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* import { EntityHydrator, DeenruvConfig } from '\@deenruv/core';
|
|
39
|
+
* import { StripePlugin } from '\@deenruv/payments-plugin/package/stripe';
|
|
40
|
+
*
|
|
41
|
+
* export const config: DeenruvConfig = {
|
|
42
|
+
* // ...
|
|
43
|
+
* plugins: [
|
|
44
|
+
* StripePlugin.init({
|
|
45
|
+
* metadata: async (injector, ctx, order) => {
|
|
46
|
+
* const hydrator = injector.get(EntityHydrator);
|
|
47
|
+
* await hydrator.hydrate(ctx, order, { relations: ['customer'] });
|
|
48
|
+
* return {
|
|
49
|
+
* description: `Order #${order.code} for ${order.customer!.emailAddress}`
|
|
50
|
+
* },
|
|
51
|
+
* }
|
|
52
|
+
* }),
|
|
53
|
+
* ],
|
|
54
|
+
* };
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* Note: If the `paymentIntentCreateParams` is also used and returns a `metadata` key, then the values
|
|
58
|
+
* returned by both functions will be merged.
|
|
59
|
+
*
|
|
60
|
+
* @since 1.9.7
|
|
61
|
+
*/
|
|
62
|
+
metadata?: (injector: Injector, ctx: RequestContext, order: Order) => Stripe.MetadataParam | Promise<Stripe.MetadataParam>;
|
|
63
|
+
/**
|
|
64
|
+
* @description
|
|
65
|
+
* Provide additional parameters to the Stripe payment intent creation. By default,
|
|
66
|
+
* the plugin will already pass the `amount`, `currency`, `customer` and `automatic_payment_methods: { enabled: true }` parameters.
|
|
67
|
+
*
|
|
68
|
+
* For example, if you want to provide a `description` for the payment intent, you can do so like this:
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* import { DeenruvConfig } from '\@deenruv/core';
|
|
73
|
+
* import { StripePlugin } from '\@deenruv/payments-plugin/package/stripe';
|
|
74
|
+
*
|
|
75
|
+
* export const config: DeenruvConfig = {
|
|
76
|
+
* // ...
|
|
77
|
+
* plugins: [
|
|
78
|
+
* StripePlugin.init({
|
|
79
|
+
* paymentIntentCreateParams: (injector, ctx, order) => {
|
|
80
|
+
* return {
|
|
81
|
+
* description: `Order #${order.code} for ${order.customer?.emailAddress}`
|
|
82
|
+
* },
|
|
83
|
+
* }
|
|
84
|
+
* }),
|
|
85
|
+
* ],
|
|
86
|
+
* };
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @since 2.1.0
|
|
90
|
+
*
|
|
91
|
+
*/
|
|
92
|
+
paymentIntentCreateParams?: (injector: Injector, ctx: RequestContext, order: Order) => AdditionalPaymentIntentCreateParams | Promise<AdditionalPaymentIntentCreateParams>;
|
|
93
|
+
/**
|
|
94
|
+
* @description
|
|
95
|
+
* Provide additional parameters to the Stripe customer creation. By default,
|
|
96
|
+
* the plugin will already pass the `email` and `name` parameters.
|
|
97
|
+
*
|
|
98
|
+
* For example, if you want to provide an address for the customer:
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* import { EntityHydrator, DeenruvConfig } from '\@deenruv/core';
|
|
103
|
+
* import { StripePlugin } from '\@deenruv/payments-plugin/package/stripe';
|
|
104
|
+
*
|
|
105
|
+
* export const config: DeenruvConfig = {
|
|
106
|
+
* // ...
|
|
107
|
+
* plugins: [
|
|
108
|
+
* StripePlugin.init({
|
|
109
|
+
* storeCustomersInStripe: true,
|
|
110
|
+
* customerCreateParams: async (injector, ctx, order) => {
|
|
111
|
+
* const entityHydrator = injector.get(EntityHydrator);
|
|
112
|
+
* const customer = order.customer;
|
|
113
|
+
* await entityHydrator.hydrate(ctx, customer, { relations: ['addresses'] });
|
|
114
|
+
* const defaultBillingAddress = customer.addresses.find(a => a.defaultBillingAddress) ?? customer.addresses[0];
|
|
115
|
+
* return {
|
|
116
|
+
* address: {
|
|
117
|
+
* line1: defaultBillingAddress.streetLine1 || order.shippingAddress?.streetLine1,
|
|
118
|
+
* postal_code: defaultBillingAddress.postalCode || order.shippingAddress?.postalCode,
|
|
119
|
+
* city: defaultBillingAddress.city || order.shippingAddress?.city,
|
|
120
|
+
* state: defaultBillingAddress.province || order.shippingAddress?.province,
|
|
121
|
+
* country: defaultBillingAddress.country.code || order.shippingAddress?.countryCode,
|
|
122
|
+
* },
|
|
123
|
+
* },
|
|
124
|
+
* }
|
|
125
|
+
* }),
|
|
126
|
+
* ],
|
|
127
|
+
* };
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* @since 2.1.0
|
|
131
|
+
*/
|
|
132
|
+
customerCreateParams?: (injector: Injector, ctx: RequestContext, order: Order) => AdditionalCustomerCreateParams | Promise<AdditionalCustomerCreateParams>;
|
|
133
|
+
}
|
|
134
|
+
export interface RequestWithRawBody extends Request {
|
|
135
|
+
rawBody: Buffer;
|
|
136
|
+
}
|
|
137
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/stripe/types.ts"],"names":[],"mappings":";;AAAA,0DAAwD"}
|