From b0fa63a8283d6099a2e822068a0fcff0de8a7f2b Mon Sep 17 00:00:00 2001 From: adrien2p Date: Tue, 14 Feb 2023 12:54:20 +0100 Subject: [PATCH 01/36] WIP --- .../jest.config.js | 24 ++ .../package.json | 45 +++ .../src/helpers/__tests__/stripe-base.js | 284 ++++++++++++++++++ .../src/helpers/stripe-base.ts | 86 ++++++ .../src/services/stripe-bancontact.ts | 18 ++ .../src/services/stripe-blik.ts | 18 ++ .../src/services/stripe-giropay.ts | 18 ++ .../src/services/stripe-ideal.ts | 18 ++ .../src/services/stripe-provider.ts | 15 + .../src/services/stripe-przelewy24.ts | 18 ++ .../src/types.ts | 14 + .../tsconfig.json | 33 ++ .../tsconfig.spec.json | 10 + 13 files changed, 601 insertions(+) create mode 100644 packages/medusa-payment-stripe-processor/jest.config.js create mode 100644 packages/medusa-payment-stripe-processor/package.json create mode 100644 packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.js create mode 100644 packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts create mode 100644 packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts create mode 100644 packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts create mode 100644 packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts create mode 100644 packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts create mode 100644 packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts create mode 100644 packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts create mode 100644 packages/medusa-payment-stripe-processor/src/types.ts create mode 100644 packages/medusa-payment-stripe-processor/tsconfig.json create mode 100644 packages/medusa-payment-stripe-processor/tsconfig.spec.json diff --git a/packages/medusa-payment-stripe-processor/jest.config.js b/packages/medusa-payment-stripe-processor/jest.config.js new file mode 100644 index 0000000000000..adffb81889622 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/jest.config.js @@ -0,0 +1,24 @@ +module.exports = { + //moduleNameMapper: { + // "^highlight.js$": `/node_modules/highlight.js/lib/index.js`, + //}, + //snapshotSerializers: [`jest-serializer-path`], + // collectCoverageFrom: coverageDirs, + //reporters: process.env.CI + // ? [[`jest-silent-reporter`, { useDots: true }]].concat( + // useCoverage ? `jest-junit` : [] + // ) + // : [`default`].concat(useCoverage ? `jest-junit` : []), + globals: { + "ts-jest": { + tsConfig: "tsconfig.spec.json", + isolatedModules: false, + }, + }, + transform: { + "^.+\\.[jt]s?$": "ts-jest", + }, + testEnvironment: `node`, + moduleFileExtensions: [`js`, `jsx`, `ts`, `tsx`, `json`], + setupFilesAfterEnv: ["/setupTests.js"], +} diff --git a/packages/medusa-payment-stripe-processor/package.json b/packages/medusa-payment-stripe-processor/package.json new file mode 100644 index 0000000000000..5d489c467e91a --- /dev/null +++ b/packages/medusa-payment-stripe-processor/package.json @@ -0,0 +1,45 @@ +{ + "name": "medusa-payment-stripe-processor", + "version": "0.0.1", + "description": "Stripe Payment provider for Meduas Commerce", + "main": "index.js", + "keywords": [ + "medusa-plugin", + "medusa-plugin-payment" + ], + "repository": { + "type": "git", + "url": "https://github.com/medusajs/medusa", + "directory": "packages/medusa-payment-stripe-processor" + }, + "publishConfig": { + "access": "public" + }, + "files": [ + "dist" + ], + "author": "Medusa", + "license": "MIT", + "scripts": { + "prepare": "cross-env NODE_ENV=production yarn run build", + "test": "jest --passWithNoTests src", + "build": "tsc", + "watch": "tsc --watch" + }, + "devDependencies": { + "@types/stripe": "^8.0.417", + "cross-env": "^5.2.1", + "jest": "^25.5.4", + "medusa-interfaces": "^1.3.5", + "medusa-test-utils": "^1.1.37" + }, + "peerDependencies": { + "medusa-interfaces": "1.3.5" + }, + "dependencies": { + "body-parser": "^1.19.0", + "express": "^4.17.1", + "medusa-core-utils": "^1.1.38", + "stripe": "^11.10.0" + } +} diff --git a/packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.js b/packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.js new file mode 100644 index 0000000000000..7bd3cf247d650 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.js @@ -0,0 +1,284 @@ +import { carts } from "../../__mocks__/cart" +import StripeBase from "../stripe-base"; + +const fakeContainer = {} + +describe("StripeBase", () => { + describe("createPayment", () => { + let result + const stripeBase = new StripeBase( + fakeContainer, + { + api_key: "test" + } + ) + + beforeEach(async () => { + jest.clearAllMocks() + }) + + it("returns created stripe payment intent for cart with existing customer", async () => { + const cart = carts.frCart + const context = { + cart, + amount: cart.total, + currency_code: cart.region?.currency_code, + } + Object.assign(context, cart) + + result = await stripeBase.createPayment(context) + expect(result).toEqual({ + session_data: { + id: "pi_lebron", + customer: "cus_lebron", + description: undefined, + amount: 100, + }, + update_requests: { + customer_metadata: { + stripe_id: "cus_lebron" + } + } + }) + }) + + it("returns created stripe payment intent for cart with no customer", async () => { + const cart = carts.frCart + const context = { + cart, + amount: cart.total, + currency_code: cart.region?.currency_code, + } + Object.assign(context, cart) + + context.cart.context.payment_description = 'some description' + + result = await stripeBase.createPayment(context) + expect(result).toEqual({ + session_data: { + id: "pi_lebron", + customer: "cus_lebron", + description: 'some description', + amount: 100, + }, + update_requests: { + customer_metadata: { + stripe_id: "cus_lebron" + } + } + }) + }) + + it("returns created stripe payment intent for cart with no customer and the options default description", async () => { + const localStripeProviderService = new StripeBase( + fakeContainer, + { + api_key: "test", + payment_description: "test options description" + }) + + const cart = carts.frCart + const context = { + cart, + amount: cart.total, + currency_code: cart.region?.currency_code, + } + Object.assign(context, cart) + + context.cart.context.payment_description = null + + result = await localStripeProviderService.createPayment(context) + expect(result).toEqual({ + session_data: { + id: "pi_lebron", + customer: "cus_lebron", + description: "test options description", + amount: 100, + }, + update_requests: { + customer_metadata: { + stripe_id: "cus_lebron" + } + } + }) + }) + }) + + describe("retrievePayment", () => { + let result + beforeAll(async () => { + jest.clearAllMocks() + const stripeBase = new StripeBase( + fakeContainer, + { + api_key: "test", + } + ) + + result = await stripeBase.retrievePayment({ + payment_method: { + data: { + id: "pi_lebron", + }, + }, + }) + }) + + it("returns stripe payment intent", () => { + expect(result).toEqual({ + id: "pi_lebron", + customer: "cus_lebron", + }) + }) + }) + + describe("updatePayment", () => { + let result + beforeAll(async () => { + jest.clearAllMocks() + const stripeBase = new StripeBase( + fakeContainer, + { + api_key: "test", + } + ) + + result = await stripeBase.updatePayment( + { + id: "pi_lebron", + amount: 800, + }, + { + total: 1000, + } + ) + }) + + it("returns updated stripe payment intent", () => { + expect(result).toEqual({ + id: "pi_lebron", + customer: "cus_lebron", + amount: 1000, + }) + }) + }) + + describe("updatePaymentIntentCustomer", () => { + let result + beforeAll(async () => { + jest.clearAllMocks() + const stripeBase = new StripeBase( + fakeContainer, + { + api_key: "test", + } + ) + + result = await stripeBase.updatePaymentIntentCustomer( + "pi_lebron", + "cus_lebron_2" + ) + }) + + it("returns update stripe payment intent", () => { + expect(result).toEqual({ + id: "pi_lebron", + customer: "cus_lebron_2", + amount: 1000, + }) + }) + }) + + describe("capturePayment", () => { + let result + beforeAll(async () => { + jest.clearAllMocks() + const stripeBase = new StripeBase( + fakeContainer, + { + api_key: "test", + } + ) + + result = await stripeBase.capturePayment({ + data: { + id: "pi_lebron", + customer: "cus_lebron", + amount: 1000, + }, + }) + }) + + it("returns captured stripe payment intent", () => { + expect(result).toEqual({ + id: "pi_lebron", + customer: "cus_lebron", + amount: 1000, + status: "succeeded", + }) + }) + }) + + describe("refundPayment", () => { + let result + beforeAll(async () => { + jest.clearAllMocks() + const stripeBase = new StripeBase( + fakeContainer, + { + api_key: "test", + } + ) + + result = await stripeBase.refundPayment( + { + data: { + id: "re_123", + payment_intent: "pi_lebron", + amount: 1000, + status: "succeeded", + }, + }, + 1000 + ) + }) + + it("returns refunded stripe payment intent", () => { + expect(result).toEqual({ + id: "re_123", + payment_intent: "pi_lebron", + amount: 1000, + status: "succeeded", + }) + }) + }) + + describe("cancelPayment", () => { + let result + beforeAll(async () => { + jest.clearAllMocks() + const stripeBase = new StripeBase( + fakeContainer, + { + api_key: "test", + } + ) + + result = await stripeBase.cancelPayment({ + data: { + id: "pi_lebron", + customer: "cus_lebron", + status: "cancelled", + }, + }) + }) + + it("returns cancelled stripe payment intent", () => { + expect(result).toEqual({ + id: "pi_lebron", + customer: "cus_lebron", + status: "cancelled", + }) + }) + }) +}) diff --git a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts b/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts new file mode 100644 index 0000000000000..6a1ed574df5d4 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts @@ -0,0 +1,86 @@ +import Stripe from "stripe" +import { + AbstractPaymentProcessor, + PaymentProcessorContext, + PaymentProcessorError, + PaymentProcessorSessionResponse, + PaymentSessionStatus +} from "@medusajs/medusa" +import { PaymentIntentOptions, StripeOptions } from "../types" + +class StripeBase extends AbstractPaymentProcessor { + static identifier = "" + + protected readonly paymentIntentOptions + protected readonly options_: StripeOptions + private stripe_: Stripe + + constructor(_, options) { + super(_, options) + + this.options_ = options + } + + async init(): Promise { + this.stripe_ = new Stripe(this.options_.api_key, { + apiVersion: '2020-08-27', + }) + } + + getPaymentIntentOptions(): PaymentIntentOptions { + const options: PaymentIntentOptions = {} + + if (this?.paymentIntentOptions?.capture_method) { + options.capture_method = this.paymentIntentOptions.capture_method + } + + if (this?.paymentIntentOptions?.setup_future_usage) { + options.setup_future_usage = this.paymentIntentOptions.setup_future_usage + } + + if (this?.paymentIntentOptions?.payment_method_types) { + options.payment_method_types = + this.paymentIntentOptions.payment_method_types + } + + return options + } + + authorizePayment(context: PaymentProcessorContext): Promise { + return Promise.resolve(undefined); + } + + cancelPayment(paymentId: string): Promise { + return Promise.resolve(undefined); + } + + capturePayment(context: PaymentProcessorContext): Promise { + return Promise.resolve(undefined); + } + + deletePayment(paymentId: string): Promise { + return Promise.resolve(undefined); + } + + getPaymentStatus(paymentId: string): Promise { + return Promise.resolve(undefined); + } + + initiatePayment(context: PaymentProcessorContext): Promise { + return Promise.resolve(undefined); + } + + refundPayment(context: PaymentProcessorContext): Promise { + return Promise.resolve(undefined); + } + + retrievePayment(paymentId: string): Promise { + return Promise.resolve(undefined); + } + + updatePayment(context: PaymentProcessorContext): Promise { + return Promise.resolve(undefined); + } +} + +export default StripeBase diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts new file mode 100644 index 0000000000000..a12f9d52515f8 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts @@ -0,0 +1,18 @@ +import StripeBase from "../helpers/stripe-base" + +class BancontactProviderService extends StripeBase { + static identifier = "stripe-bancontact" + + constructor(_, options) { + super(_, options) + } + + get paymentIntentOptions() { + return { + payment_method_types: ["bancontact"], + capture_method: "automatic", + } + } +} + +export default BancontactProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts new file mode 100644 index 0000000000000..6e18a17fcc947 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts @@ -0,0 +1,18 @@ +import StripeBase from "../helpers/stripe-base" + +class BlikProviderService extends StripeBase { + static identifier = "stripe-blik" + + constructor(_, options) { + super(_, options) + } + + get paymentIntentOptions() { + return { + payment_method_types: ["blik"], + capture_method: "automatic", + } + } +} + +export default BlikProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts new file mode 100644 index 0000000000000..94b19415f03f3 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts @@ -0,0 +1,18 @@ +import StripeBase from "../helpers/stripe-base" + +class GiropayProviderService extends StripeBase { + static identifier = "stripe-giropay" + + constructor(_, options) { + super(_, options) + } + + get paymentIntentOptions() { + return { + payment_method_types: ["giropay"], + capture_method: "automatic", + } + } +} + +export default GiropayProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts new file mode 100644 index 0000000000000..6d20df143cd5f --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts @@ -0,0 +1,18 @@ +import StripeBase from "../helpers/stripe-base" + +class IdealProviderService extends StripeBase { + static identifier = "stripe-ideal" + + constructor(_, options) { + super(_, options) + } + + get paymentIntentOptions() { + return { + payment_method_types: ["ideal"], + capture_method: "automatic", + } + } +} + +export default IdealProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts new file mode 100644 index 0000000000000..ac2f47a23220d --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts @@ -0,0 +1,15 @@ +import StripeBase from "../helpers/stripe-base"; + +class StripeProviderService extends StripeBase { + static identifier = "stripe" + + constructor(_, options) { + super(_, options) + } + + get paymentIntentOptions() { + return {} + } +} + +export default StripeProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts new file mode 100644 index 0000000000000..236d8c38b017b --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts @@ -0,0 +1,18 @@ +import StripeBase from "../helpers/stripe-base" + +class Przelewy24ProviderService extends StripeBase { + static identifier = "stripe-przelewy24" + + constructor(_, options) { + super(_, options) + } + + get paymentIntentOptions() { + return { + payment_method_types: ["p24"], + capture_method: "automatic", + } + } +} + +export default Przelewy24ProviderService diff --git a/packages/medusa-payment-stripe-processor/src/types.ts b/packages/medusa-payment-stripe-processor/src/types.ts new file mode 100644 index 0000000000000..b92bb6c5047ef --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/types.ts @@ -0,0 +1,14 @@ +export interface StripeOptions { + api_key: string + webhook_secret: string + /** + * Use this flag to capture payment immediately (default is false) + */ + capture?: boolean +} + +export interface PaymentIntentOptions { + capture_method?: "automatic" | "manual" + setup_future_usage?: "on_session" | "off_session" + payment_method_types?: string[] +} \ No newline at end of file diff --git a/packages/medusa-payment-stripe-processor/tsconfig.json b/packages/medusa-payment-stripe-processor/tsconfig.json new file mode 100644 index 0000000000000..b73ee183580bb --- /dev/null +++ b/packages/medusa-payment-stripe-processor/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "lib": [ + "es5", + "es6", + "es2019" + ], + "target": "es5", + "outDir": "./dist", + "esModuleInterop": true, + "declaration": true, + "module": "commonjs", + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "sourceMap": true, + "noImplicitReturns": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "noImplicitThis": true, + "allowJs": true, + "skipLibCheck": true, + "downlevelIteration": true // to use ES5 specific tooling + }, + "include": ["./src/**/*", "index.d.ts"], + "exclude": [ + "./dist/**/*", + "./src/**/__tests__", + "./src/**/__mocks__", + "./src/**/__fixtures__", + "node_modules" + ] +} \ No newline at end of file diff --git a/packages/medusa-payment-stripe-processor/tsconfig.spec.json b/packages/medusa-payment-stripe-processor/tsconfig.spec.json new file mode 100644 index 0000000000000..a108b800dbb04 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/tsconfig.spec.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "./src/**/*", + "index.d.ts", + "./src/**/__tests__", + "./src/**/__mocks__" + ], + "exclude": ["node_modules"] +} From 8550734ffcb72faa61ac22b26ef26da6905a2c49 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Tue, 14 Feb 2023 14:39:42 +0100 Subject: [PATCH 02/36] continue to implement stripe base --- .../src/helpers/stripe-base.ts | 175 ++++++++++++++++-- .../src/types.ts | 8 + 2 files changed, 167 insertions(+), 16 deletions(-) diff --git a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts b/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts index 6a1ed574df5d4..912da04076408 100644 --- a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts +++ b/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts @@ -8,10 +8,9 @@ import { } from "@medusajs/medusa" import { PaymentIntentOptions, StripeOptions } from "../types" -class StripeBase extends AbstractPaymentProcessor { +abstract class StripeBase extends AbstractPaymentProcessor { static identifier = "" - protected readonly paymentIntentOptions protected readonly options_: StripeOptions private stripe_: Stripe @@ -23,10 +22,12 @@ class StripeBase extends AbstractPaymentProcessor { async init(): Promise { this.stripe_ = new Stripe(this.options_.api_key, { - apiVersion: '2020-08-27', + apiVersion: '2022-11-15', }) } + abstract get paymentIntentOptions(): PaymentIntentOptions + getPaymentIntentOptions(): PaymentIntentOptions { const options: PaymentIntentOptions = {} @@ -46,8 +47,79 @@ class StripeBase extends AbstractPaymentProcessor { return options } - authorizePayment(context: PaymentProcessorContext): Promise { - return Promise.resolve(undefined); + async initiatePayment( + context: PaymentProcessorContext + ): Promise { + const intentRequestData = this.getPaymentIntentOptions() + const { + email, + context: cart_context, + currency_code, + amount, + resource_id, + customer + } = context + + const description = ( + cart_context.payment_description ?? this.options_?.payment_description + ) as string + + const intentRequest: Stripe.PaymentIntentCreateParams = { + description, + amount: Math.round(amount), + currency: currency_code, + metadata: { resource_id }, + capture_method: this.options_.capture ? "automatic" : "manual", + ...intentRequestData, + } + + if (this.options_?.automatic_payment_methods) { + intentRequest.automatic_payment_methods = { enabled: true } + } + + if (customer?.metadata?.stripe_id) { + intentRequest.customer = customer.metadata.stripe_id as string + } else { + let stripeCustomer + try { + stripeCustomer = await this.stripe_.customers.create({ + email, + }) + } catch (e) { + return this.buildError( + "An error occurred in InitiatePayment during the creation of the stripe customer", + e + ) + } + + intentRequest.customer = stripeCustomer.id + } + + let session_data + try { + session_data = (await this.stripe_.paymentIntents.create( + intentRequest + )) as unknown as Record + } catch (e) { + return this.buildError( + "An error occurred in InitiatePayment during the creation of the stripe payment intent", + e + ) + } + + return { + session_data, + update_requests: customer?.metadata?.stripe_id ? undefined : { + customer_metadata: { + stripe_id: intentRequest.customer + } + } + } + } + + async authorizePayment(context: PaymentProcessorContext): Promise { + const id = context.paymentSessionData.id as string + await this.getPaymentStatus(id) } cancelPayment(paymentId: string): Promise { @@ -58,28 +130,99 @@ class StripeBase extends AbstractPaymentProcessor { return Promise.resolve(undefined); } - deletePayment(paymentId: string): Promise { - return Promise.resolve(undefined); - } + async deletePayment(paymentId: string): Promise { + let error - getPaymentStatus(paymentId: string): Promise { - return Promise.resolve(undefined); + await this.stripe_.paymentIntents.cancel(paymentId) + .catch((err) => { + if (err.statusCode === 400) { + return + } + + error = this.buildError( + "An error occurred in deletePayment during the cancellation of the payment", + err + ) + }) + + return error } - initiatePayment(context: PaymentProcessorContext): Promise { - return Promise.resolve(undefined); + async getPaymentStatus(paymentId: string): Promise { + const paymentIntent = await this.stripe_.paymentIntents.retrieve(paymentId) + + switch (paymentIntent.status) { + case "requires_payment_method": + case "requires_confirmation": + case "processing": + return PaymentSessionStatus.PENDING + case "requires_action": + return PaymentSessionStatus.REQUIRES_MORE + case "canceled": + return PaymentSessionStatus.CANCELED + case "requires_capture": + case "succeeded": + return PaymentSessionStatus.AUTHORIZED + default: + return PaymentSessionStatus.PENDING + } } refundPayment(context: PaymentProcessorContext): Promise { return Promise.resolve(undefined); } - retrievePayment(paymentId: string): Promise { - return Promise.resolve(undefined); + async retrievePayment(paymentId: string): Promise { + try { + const intent = await this.stripe_.paymentIntents.retrieve(paymentId) + return intent as unknown as Record + } catch (e) { + return this.buildError("An error occurred in retrievePayment", e) + } } - updatePayment(context: PaymentProcessorContext): Promise { - return Promise.resolve(undefined); + async updatePayment( + context: PaymentProcessorContext + ): Promise { + const { amount, customer, paymentSessionData } = context + const stripeId = customer?.metadata?.stripe_id + + if (stripeId !== paymentSessionData.customer) { + return await this.initiatePayment(context) + .catch(e => { + return this.buildError( + "An error occurred in updatePayment during the initiate of the new payment for the new customer", + e + ) + }) + } else { + if ( + amount && + paymentSessionData.amount === Math.round(amount) + ) { + return + } + + try { + const id = paymentSessionData.id as string + await this.stripe_.paymentIntents.update(id, { + amount: Math.round(amount), + }) + } catch (e) { + this.buildError( + "An error occurred in updatePayment during the update of the payment", + e + ) + } + } + } + + protected buildError(message: string, e: Stripe.StripeRawError): PaymentProcessorError { + return { + error: message, + code: e.code, + details: e.detail + } } } diff --git a/packages/medusa-payment-stripe-processor/src/types.ts b/packages/medusa-payment-stripe-processor/src/types.ts index b92bb6c5047ef..2850fdc9f6c1a 100644 --- a/packages/medusa-payment-stripe-processor/src/types.ts +++ b/packages/medusa-payment-stripe-processor/src/types.ts @@ -5,6 +5,14 @@ export interface StripeOptions { * Use this flag to capture payment immediately (default is false) */ capture?: boolean + /** + * set `automatic_payment_methods` to `{ enabled: true }` + */ + automatic_payment_methods?: boolean + /** + * Set a default description on the intent if the context does not provide one + */ + payment_description?: string } export interface PaymentIntentOptions { From 7bee57d05a7839b7fdc3a4e754aeed404354c9b2 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 15 Feb 2023 10:06:36 +0100 Subject: [PATCH 03/36] continue stripe impl --- .../src/helpers/stripe-base.ts | 133 +++++++++++++----- .../src/services/stripe-bancontact.ts | 3 +- .../src/services/stripe-blik.ts | 3 +- .../src/services/stripe-giropay.ts | 3 +- .../src/services/stripe-ideal.ts | 3 +- .../src/services/stripe-provider.ts | 3 +- .../src/services/stripe-przelewy24.ts | 3 +- yarn.lock | 39 ++++- 8 files changed, 145 insertions(+), 45 deletions(-) diff --git a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts b/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts index 912da04076408..e0bfd250e6d5b 100644 --- a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts +++ b/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts @@ -8,6 +8,15 @@ import { } from "@medusajs/medusa" import { PaymentIntentOptions, StripeOptions } from "../types" +const ERROR_CODES = { + PAYMENT_INTENT_UNEXPECTED_STATE: "payment_intent_unexpected_state" +} + +const INTENT_STATUS = { + SUCCEEDED: "succeeded", + CANCELED: "canceled", +} + abstract class StripeBase extends AbstractPaymentProcessor { static identifier = "" @@ -47,6 +56,26 @@ abstract class StripeBase extends AbstractPaymentProcessor { return options } + async getPaymentStatus(paymentId: string): Promise { + const paymentIntent = await this.stripe_.paymentIntents.retrieve(paymentId) + + switch (paymentIntent.status) { + case "requires_payment_method": + case "requires_confirmation": + case "processing": + return PaymentSessionStatus.PENDING + case "requires_action": + return PaymentSessionStatus.REQUIRES_MORE + case "canceled": + return PaymentSessionStatus.CANCELED + case "requires_capture": + case "succeeded": + return PaymentSessionStatus.AUTHORIZED + default: + return PaymentSessionStatus.PENDING + } + } + async initiatePayment( context: PaymentProcessorContext ): Promise { @@ -122,60 +151,73 @@ abstract class StripeBase extends AbstractPaymentProcessor { await this.getPaymentStatus(id) } - cancelPayment(paymentId: string): Promise { - return Promise.resolve(undefined); - } + async cancelPayment(paymentId: string): Promise { + try { + return await this.stripe_ + .paymentIntents + .cancel(paymentId) as unknown as PaymentProcessorSessionResponse["session_data"] + } catch (error) { + if (error.payment_intent.status === INTENT_STATUS.CANCELED) { + return error.payment_intent + } - capturePayment(context: PaymentProcessorContext): Promise { - return Promise.resolve(undefined); + return this.buildError( + "An error occurred in cancelPayment during the cancellation of the payment", + error + ) + } } - async deletePayment(paymentId: string): Promise { - let error - - await this.stripe_.paymentIntents.cancel(paymentId) - .catch((err) => { - if (err.statusCode === 400) { - return + async capturePayment( + context: PaymentProcessorContext + ): Promise { + const { id } = context.paymentSessionData + try { + const intent = await this.stripe_.paymentIntents.capture(id as string) + return intent as unknown as PaymentProcessorSessionResponse["session_data"] + } catch (error) { + if (error.code === ERROR_CODES.PAYMENT_INTENT_UNEXPECTED_STATE) { + if (error.payment_intent.status === INTENT_STATUS.SUCCEEDED) { + return error.payment_intent } + } - error = this.buildError( - "An error occurred in deletePayment during the cancellation of the payment", - err - ) - }) + return this.buildError( + "An error occurred in deletePayment during the capture of the payment", + error + ) + } + } - return error + async deletePayment( + paymentId: string + ): Promise { + return await this.cancelPayment(paymentId) } - async getPaymentStatus(paymentId: string): Promise { - const paymentIntent = await this.stripe_.paymentIntents.retrieve(paymentId) + async refundPayment(context: PaymentProcessorContext): Promise { + const { amount } = context + const { id } = context.paymentSessionData - switch (paymentIntent.status) { - case "requires_payment_method": - case "requires_confirmation": - case "processing": - return PaymentSessionStatus.PENDING - case "requires_action": - return PaymentSessionStatus.REQUIRES_MORE - case "canceled": - return PaymentSessionStatus.CANCELED - case "requires_capture": - case "succeeded": - return PaymentSessionStatus.AUTHORIZED - default: - return PaymentSessionStatus.PENDING + try { + await this.stripe_.refunds.create({ + amount: Math.round(amount), + payment_intent: id as string, + }) + } catch (e) { + return this.buildError( + "An error occurred in retrievePayment during the refundPayment", + e + ) } - } - refundPayment(context: PaymentProcessorContext): Promise { - return Promise.resolve(undefined); + return context.paymentSessionData } async retrievePayment(paymentId: string): Promise { try { const intent = await this.stripe_.paymentIntents.retrieve(paymentId) - return intent as unknown as Record + return intent as unknown as PaymentProcessorSessionResponse["session_data"] } catch (e) { return this.buildError("An error occurred in retrievePayment", e) } @@ -217,6 +259,21 @@ abstract class StripeBase extends AbstractPaymentProcessor { } } + /** + * Constructs Stripe Webhook event + * @param {object} data - the data of the webhook request: req.body + * @param {object} signature - the Stripe signature on the event, that + * ensures integrity of the webhook event + * @return {object} Stripe Webhook event + */ + constructWebhookEvent(data, signature) { + return this.stripe_.webhooks.constructEvent( + data, + signature, + this.options_.webhook_secret + ) + } + protected buildError(message: string, e: Stripe.StripeRawError): PaymentProcessorError { return { error: message, diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts index a12f9d52515f8..d39babbf22545 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts @@ -1,4 +1,5 @@ import StripeBase from "../helpers/stripe-base" +import { PaymentIntentOptions } from "../types"; class BancontactProviderService extends StripeBase { static identifier = "stripe-bancontact" @@ -7,7 +8,7 @@ class BancontactProviderService extends StripeBase { super(_, options) } - get paymentIntentOptions() { + get paymentIntentOptions(): PaymentIntentOptions { return { payment_method_types: ["bancontact"], capture_method: "automatic", diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts index 6e18a17fcc947..ece460b6b32e1 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts @@ -1,4 +1,5 @@ import StripeBase from "../helpers/stripe-base" +import { PaymentIntentOptions } from "../types"; class BlikProviderService extends StripeBase { static identifier = "stripe-blik" @@ -7,7 +8,7 @@ class BlikProviderService extends StripeBase { super(_, options) } - get paymentIntentOptions() { + get paymentIntentOptions(): PaymentIntentOptions { return { payment_method_types: ["blik"], capture_method: "automatic", diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts index 94b19415f03f3..123eb0fc62deb 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts @@ -1,4 +1,5 @@ import StripeBase from "../helpers/stripe-base" +import { PaymentIntentOptions } from "../types"; class GiropayProviderService extends StripeBase { static identifier = "stripe-giropay" @@ -7,7 +8,7 @@ class GiropayProviderService extends StripeBase { super(_, options) } - get paymentIntentOptions() { + get paymentIntentOptions(): PaymentIntentOptions { return { payment_method_types: ["giropay"], capture_method: "automatic", diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts index 6d20df143cd5f..e4c8408c25085 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts @@ -1,4 +1,5 @@ import StripeBase from "../helpers/stripe-base" +import { PaymentIntentOptions } from "../types"; class IdealProviderService extends StripeBase { static identifier = "stripe-ideal" @@ -7,7 +8,7 @@ class IdealProviderService extends StripeBase { super(_, options) } - get paymentIntentOptions() { + get paymentIntentOptions(): PaymentIntentOptions { return { payment_method_types: ["ideal"], capture_method: "automatic", diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts index ac2f47a23220d..7b9512253991d 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts @@ -1,4 +1,5 @@ import StripeBase from "../helpers/stripe-base"; +import { PaymentIntentOptions } from "../types"; class StripeProviderService extends StripeBase { static identifier = "stripe" @@ -7,7 +8,7 @@ class StripeProviderService extends StripeBase { super(_, options) } - get paymentIntentOptions() { + get paymentIntentOptions(): PaymentIntentOptions { return {} } } diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts index 236d8c38b017b..cec220c26f385 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts @@ -1,4 +1,5 @@ import StripeBase from "../helpers/stripe-base" +import { PaymentIntentOptions } from "../types"; class Przelewy24ProviderService extends StripeBase { static identifier = "stripe-przelewy24" @@ -7,7 +8,7 @@ class Przelewy24ProviderService extends StripeBase { super(_, options) } - get paymentIntentOptions() { + get paymentIntentOptions(): PaymentIntentOptions { return { payment_method_types: ["p24"], capture_method: "automatic", diff --git a/yarn.lock b/yarn.lock index 89011e611e14c..878433a3936a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9198,6 +9198,15 @@ __metadata: languageName: node linkType: hard +"@types/stripe@npm:^8.0.417": + version: 8.0.417 + resolution: "@types/stripe@npm:8.0.417" + dependencies: + stripe: "*" + checksum: 97e3a5ad6948a94366d6749328b721a3c9004ba68795e7675efaa74e4b4c51d57c1dfc785747f4221192dabd7a13fb41778e88e080bafd5d3938a50df7f4ef98 + languageName: node + linkType: hard + "@types/superagent@npm:*": version: 4.1.15 resolution: "@types/superagent@npm:4.1.15" @@ -25697,6 +25706,24 @@ __metadata: languageName: unknown linkType: soft +"medusa-payment-stripe-processor@workspace:packages/medusa-payment-stripe-processor": + version: 0.0.0-use.local + resolution: "medusa-payment-stripe-processor@workspace:packages/medusa-payment-stripe-processor" + dependencies: + "@types/stripe": ^8.0.417 + body-parser: ^1.19.0 + cross-env: ^5.2.1 + express: ^4.17.1 + jest: ^25.5.4 + medusa-core-utils: ^1.1.38 + medusa-interfaces: ^1.3.5 + medusa-test-utils: ^1.1.37 + stripe: ^11.10.0 + peerDependencies: + medusa-interfaces: 1.3.5 + languageName: unknown + linkType: soft + "medusa-payment-stripe@workspace:packages/medusa-payment-stripe": version: 0.0.0-use.local resolution: "medusa-payment-stripe@workspace:packages/medusa-payment-stripe" @@ -30321,7 +30348,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.10.0, qs@npm:^6.10.3, qs@npm:^6.5.1, qs@npm:^6.6.0, qs@npm:^6.9.4": +"qs@npm:^6.10.0, qs@npm:^6.10.3, qs@npm:^6.11.0, qs@npm:^6.5.1, qs@npm:^6.6.0, qs@npm:^6.9.4": version: 6.11.0 resolution: "qs@npm:6.11.0" dependencies: @@ -33886,6 +33913,16 @@ __metadata: languageName: node linkType: hard +"stripe@npm:*, stripe@npm:^11.10.0": + version: 11.10.0 + resolution: "stripe@npm:11.10.0" + dependencies: + "@types/node": ">=8.1.0" + qs: ^6.11.0 + checksum: e50b7f671f608557a6dec74ae817c13df73ded75f586e2c5069e6acf86d5e459753695c59454226e8ede3ab7df00915f6a5becda8e7153226ea2eacbd7fb87a2 + languageName: node + linkType: hard + "stripe@npm:^8.50.0": version: 8.222.0 resolution: "stripe@npm:8.222.0" From 93b630556e7587575957caa1cf09fc32017e701f Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 15 Feb 2023 10:53:54 +0100 Subject: [PATCH 04/36] update eslint config --- .eslintignore | 1 + .eslintrc.js | 5 +- .../package.json | 2 +- .../src/helpers/stripe-base.ts | 110 ++++++++++-------- .../src/index.ts | 1 + .../tsconfig.json | 10 +- .../tsconfig.spec.json | 7 +- 7 files changed, 77 insertions(+), 59 deletions(-) create mode 100644 packages/medusa-payment-stripe-processor/src/index.ts diff --git a/.eslintignore b/.eslintignore index 83458b34424af..b42392c6a7d26 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,6 +7,7 @@ jest* packages/* # List of packages to Lint !packages/medusa +!packages/medusa-payment-stripe-processor diff --git a/.eslintrc.js b/.eslintrc.js index 39e7d73efd48b..d65fa8b7c8c5f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -80,7 +80,10 @@ module.exports = { extends: ["plugin:@typescript-eslint/recommended"], parser: "@typescript-eslint/parser", parserOptions: { - project: "./packages/medusa/tsconfig.json", + project: [ + "./packages/medusa/tsconfig.json", + "./packages/medusa-payment-stripe-processor/tsconfig.json", + ] }, rules: { "valid-jsdoc": "off", diff --git a/packages/medusa-payment-stripe-processor/package.json b/packages/medusa-payment-stripe-processor/package.json index 5d489c467e91a..ddceff52d86eb 100644 --- a/packages/medusa-payment-stripe-processor/package.json +++ b/packages/medusa-payment-stripe-processor/package.json @@ -2,7 +2,7 @@ "name": "medusa-payment-stripe-processor", "version": "0.0.1", "description": "Stripe Payment provider for Meduas Commerce", - "main": "index.js", + "main": "dist/index.js", "keywords": [ "medusa-plugin", "medusa-plugin-payment" diff --git a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts b/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts index e0bfd250e6d5b..5139afe68e9ae 100644 --- a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts +++ b/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts @@ -4,12 +4,12 @@ import { PaymentProcessorContext, PaymentProcessorError, PaymentProcessorSessionResponse, - PaymentSessionStatus + PaymentSessionStatus, } from "@medusajs/medusa" import { PaymentIntentOptions, StripeOptions } from "../types" const ERROR_CODES = { - PAYMENT_INTENT_UNEXPECTED_STATE: "payment_intent_unexpected_state" + PAYMENT_INTENT_UNEXPECTED_STATE: "payment_intent_unexpected_state", } const INTENT_STATUS = { @@ -23,7 +23,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { protected readonly options_: StripeOptions private stripe_: Stripe - constructor(_, options) { + protected constructor(_, options) { super(_, options) this.options_ = options @@ -31,7 +31,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { async init(): Promise { this.stripe_ = new Stripe(this.options_.api_key, { - apiVersion: '2022-11-15', + apiVersion: "2022-11-15", }) } @@ -86,12 +86,11 @@ abstract class StripeBase extends AbstractPaymentProcessor { currency_code, amount, resource_id, - customer + customer, } = context - const description = ( - cart_context.payment_description ?? this.options_?.payment_description - ) as string + const description = (cart_context.payment_description ?? + this.options_?.payment_description) as string const intentRequest: Stripe.PaymentIntentCreateParams = { description, @@ -125,37 +124,45 @@ abstract class StripeBase extends AbstractPaymentProcessor { } let session_data - try { - session_data = (await this.stripe_.paymentIntents.create( - intentRequest - )) as unknown as Record - } catch (e) { - return this.buildError( - "An error occurred in InitiatePayment during the creation of the stripe payment intent", - e - ) - } + try { + session_data = (await this.stripe_.paymentIntents.create( + intentRequest + )) as unknown as Record + } catch (e) { + return this.buildError( + "An error occurred in InitiatePayment during the creation of the stripe payment intent", + e + ) + } return { session_data, - update_requests: customer?.metadata?.stripe_id ? undefined : { - customer_metadata: { - stripe_id: intentRequest.customer - } - } + update_requests: customer?.metadata?.stripe_id + ? undefined + : { + customer_metadata: { + stripe_id: intentRequest.customer, + }, + }, } } - async authorizePayment(context: PaymentProcessorContext): Promise { + async authorizePayment( + context: PaymentProcessorContext + ): Promise { const id = context.paymentSessionData.id as string await this.getPaymentStatus(id) } - async cancelPayment(paymentId: string): Promise { + async cancelPayment( + paymentId: string + ): Promise< + PaymentProcessorError | PaymentProcessorSessionResponse["session_data"] + > { try { - return await this.stripe_ - .paymentIntents - .cancel(paymentId) as unknown as PaymentProcessorSessionResponse["session_data"] + return (await this.stripe_.paymentIntents.cancel( + paymentId + )) as unknown as PaymentProcessorSessionResponse["session_data"] } catch (error) { if (error.payment_intent.status === INTENT_STATUS.CANCELED) { return error.payment_intent @@ -170,7 +177,9 @@ abstract class StripeBase extends AbstractPaymentProcessor { async capturePayment( context: PaymentProcessorContext - ): Promise { + ): Promise< + PaymentProcessorError | PaymentProcessorSessionResponse["session_data"] + > { const { id } = context.paymentSessionData try { const intent = await this.stripe_.paymentIntents.capture(id as string) @@ -191,11 +200,17 @@ abstract class StripeBase extends AbstractPaymentProcessor { async deletePayment( paymentId: string - ): Promise { + ): Promise< + PaymentProcessorError | PaymentProcessorSessionResponse["session_data"] + > { return await this.cancelPayment(paymentId) } - async refundPayment(context: PaymentProcessorContext): Promise { + async refundPayment( + context: PaymentProcessorContext + ): Promise< + PaymentProcessorError | PaymentProcessorSessionResponse["session_data"] + > { const { amount } = context const { id } = context.paymentSessionData @@ -214,7 +229,11 @@ abstract class StripeBase extends AbstractPaymentProcessor { return context.paymentSessionData } - async retrievePayment(paymentId: string): Promise { + async retrievePayment( + paymentId: string + ): Promise< + PaymentProcessorError | PaymentProcessorSessionResponse["session_data"] + > { try { const intent = await this.stripe_.paymentIntents.retrieve(paymentId) return intent as unknown as PaymentProcessorSessionResponse["session_data"] @@ -230,18 +249,14 @@ abstract class StripeBase extends AbstractPaymentProcessor { const stripeId = customer?.metadata?.stripe_id if (stripeId !== paymentSessionData.customer) { - return await this.initiatePayment(context) - .catch(e => { - return this.buildError( - "An error occurred in updatePayment during the initiate of the new payment for the new customer", - e - ) - }) + return await this.initiatePayment(context).catch((e) => { + return this.buildError( + "An error occurred in updatePayment during the initiate of the new payment for the new customer", + e + ) + }) } else { - if ( - amount && - paymentSessionData.amount === Math.round(amount) - ) { + if (amount && paymentSessionData.amount === Math.round(amount)) { return } @@ -273,12 +288,15 @@ abstract class StripeBase extends AbstractPaymentProcessor { this.options_.webhook_secret ) } - - protected buildError(message: string, e: Stripe.StripeRawError): PaymentProcessorError { + + protected buildError( + message: string, + e: Stripe.StripeRawError + ): PaymentProcessorError { return { error: message, code: e.code, - details: e.detail + details: e.detail, } } } diff --git a/packages/medusa-payment-stripe-processor/src/index.ts b/packages/medusa-payment-stripe-processor/src/index.ts new file mode 100644 index 0000000000000..625c0891b2c30 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/index.ts @@ -0,0 +1 @@ +// noop \ No newline at end of file diff --git a/packages/medusa-payment-stripe-processor/tsconfig.json b/packages/medusa-payment-stripe-processor/tsconfig.json index b73ee183580bb..babbc0f28482e 100644 --- a/packages/medusa-payment-stripe-processor/tsconfig.json +++ b/packages/medusa-payment-stripe-processor/tsconfig.json @@ -22,12 +22,12 @@ "skipLibCheck": true, "downlevelIteration": true // to use ES5 specific tooling }, - "include": ["./src/**/*", "index.d.ts"], + "include": ["src"], "exclude": [ - "./dist/**/*", - "./src/**/__tests__", - "./src/**/__mocks__", - "./src/**/__fixtures__", + "dist", + "src/**/__tests__", + "src/**/__mocks__", + "src/**/__fixtures__", "node_modules" ] } \ No newline at end of file diff --git a/packages/medusa-payment-stripe-processor/tsconfig.spec.json b/packages/medusa-payment-stripe-processor/tsconfig.spec.json index a108b800dbb04..9b6240919113c 100644 --- a/packages/medusa-payment-stripe-processor/tsconfig.spec.json +++ b/packages/medusa-payment-stripe-processor/tsconfig.spec.json @@ -1,10 +1,5 @@ { "extends": "./tsconfig.json", - "include": [ - "./src/**/*", - "index.d.ts", - "./src/**/__tests__", - "./src/**/__mocks__" - ], + "include": ["src"], "exclude": ["node_modules"] } From ef7b5c63b73ac713d05f0c47be0abb30736315cd Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 15 Feb 2023 11:47:38 +0100 Subject: [PATCH 05/36] Tests continuation --- .../.gitignore | 4 + .../jest.config.js | 3 +- .../package.json | 7 +- .../src/__fixtures__/data.ts | 30 +++ .../src/__mocks__/cart.ts | 216 ++++++++++++++++++ .../src/__mocks__/customer.ts | 39 ++++ .../src/__mocks__/eventbus.ts | 10 + .../src/__mocks__/stripe.ts | 37 +++ .../src/__mocks__/totals.js | 12 + .../src/helpers/__fixtures__/stripe-test.ts | 12 + .../src/helpers/__tests__/stripe-base.spec.ts | 30 +++ .../src/helpers/stripe-base.ts | 10 +- yarn.lock | 53 ++++- 13 files changed, 449 insertions(+), 14 deletions(-) create mode 100644 packages/medusa-payment-stripe-processor/.gitignore create mode 100644 packages/medusa-payment-stripe-processor/src/__fixtures__/data.ts create mode 100644 packages/medusa-payment-stripe-processor/src/__mocks__/cart.ts create mode 100644 packages/medusa-payment-stripe-processor/src/__mocks__/customer.ts create mode 100644 packages/medusa-payment-stripe-processor/src/__mocks__/eventbus.ts create mode 100644 packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts create mode 100644 packages/medusa-payment-stripe-processor/src/__mocks__/totals.js create mode 100644 packages/medusa-payment-stripe-processor/src/helpers/__fixtures__/stripe-test.ts create mode 100644 packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.spec.ts diff --git a/packages/medusa-payment-stripe-processor/.gitignore b/packages/medusa-payment-stripe-processor/.gitignore new file mode 100644 index 0000000000000..384d378f948ba --- /dev/null +++ b/packages/medusa-payment-stripe-processor/.gitignore @@ -0,0 +1,4 @@ +dist +node_modules +.DS_store +yarn.lock \ No newline at end of file diff --git a/packages/medusa-payment-stripe-processor/jest.config.js b/packages/medusa-payment-stripe-processor/jest.config.js index adffb81889622..7ed3e9a0975d1 100644 --- a/packages/medusa-payment-stripe-processor/jest.config.js +++ b/packages/medusa-payment-stripe-processor/jest.config.js @@ -11,7 +11,7 @@ module.exports = { // : [`default`].concat(useCoverage ? `jest-junit` : []), globals: { "ts-jest": { - tsConfig: "tsconfig.spec.json", + tsconfig: "tsconfig.spec.json", isolatedModules: false, }, }, @@ -20,5 +20,4 @@ module.exports = { }, testEnvironment: `node`, moduleFileExtensions: [`js`, `jsx`, `ts`, `tsx`, `json`], - setupFilesAfterEnv: ["/setupTests.js"], } diff --git a/packages/medusa-payment-stripe-processor/package.json b/packages/medusa-payment-stripe-processor/package.json index ddceff52d86eb..f4b739e59448e 100644 --- a/packages/medusa-payment-stripe-processor/package.json +++ b/packages/medusa-payment-stripe-processor/package.json @@ -27,14 +27,13 @@ "watch": "tsc --watch" }, "devDependencies": { + "@medusajs/medusa": "^1.7.7", "@types/stripe": "^8.0.417", "cross-env": "^5.2.1", - "jest": "^25.5.4", - "medusa-interfaces": "^1.3.5", - "medusa-test-utils": "^1.1.37" + "jest": "^25.5.4" }, "peerDependencies": { - "medusa-interfaces": "1.3.5" + "@medusajs/medusa": "^1.7.7" }, "dependencies": { "body-parser": "^1.19.0", diff --git a/packages/medusa-payment-stripe-processor/src/__fixtures__/data.ts b/packages/medusa-payment-stripe-processor/src/__fixtures__/data.ts new file mode 100644 index 0000000000000..9ab2e88a37ab1 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/__fixtures__/data.ts @@ -0,0 +1,30 @@ +export const PaymentIntentDataByStatus = { + REQUIRE_PAYMENT_METHOD: { + id: "requires_payment_method", + status: "requires_payment_method" + }, + REQUIRES_CONFIRMATION: { + id: "requires_confirmation", + status: "requires_confirmation" + }, + PROCESSING: { + id: "processing", + status: "processing" + }, + REQUIRES_ACTION: { + id: "requires_action", + status: "requires_action" + }, + CANCELED: { + id: "canceled", + status: "canceled" + }, + REQUIRES_CAPTURE: { + id: "requires_capture", + status: "requires_capture" + }, + SUCCEEDED: { + id: "succeeded", + status: "succeeded" + }, +} \ No newline at end of file diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/cart.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/cart.ts new file mode 100644 index 0000000000000..c301361bdaad7 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/__mocks__/cart.ts @@ -0,0 +1,216 @@ +import { IdMap } from "medusa-test-utils" + +export const carts = { + emptyCart: { + id: IdMap.getId("emptyCart"), + items: [], + region_id: IdMap.getId("testRegion"), + customer_id: "test-customer", + payment_sessions: [], + shipping_options: [ + { + id: IdMap.getId("freeShipping"), + profile_id: "default_profile", + data: { + some_data: "yes", + }, + }, + ], + }, + frCart: { + id: IdMap.getId("fr-cart"), + email: "lebron@james.com", + title: "test", + region_id: IdMap.getId("region-france"), + items: [ + { + id: IdMap.getId("line"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + + unit_price: 8, + variant: { + id: IdMap.getId("eur-8-us-10"), + }, + product: { + id: IdMap.getId("product"), + }, + // { + // unit_price: 10, + // variant: { + // id: IdMap.getId("eur-10-us-12"), + // }, + // product: { + // id: IdMap.getId("product"), + // }, + // quantity: 1, + // }, + quantity: 10, + }, + { + id: IdMap.getId("existingLine"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + unit_price: 10, + variant: { + id: IdMap.getId("eur-10-us-12"), + }, + product: { + id: IdMap.getId("product"), + }, + quantity: 1, + }, + ], + shipping_methods: [ + { + id: IdMap.getId("freeShipping"), + profile_id: "default_profile", + }, + ], + shipping_options: [ + { + id: IdMap.getId("freeShipping"), + profile_id: "default_profile", + }, + ], + payment_sessions: [ + { + provider_id: "stripe", + data: { + id: "pi_123456789", + customer: IdMap.getId("not-lebron"), + }, + }, + ], + payment_method: { + provider_id: "stripe", + data: { + id: "pi_123456789", + customer: IdMap.getId("not-lebron"), + }, + }, + region: { currency_code: "usd" }, + total: 100, + shipping_address: {}, + billing_address: {}, + discounts: [], + customer_id: IdMap.getId("lebron"), + context: {} + }, + frCartNoStripeCustomer: { + id: IdMap.getId("fr-cart-no-customer"), + title: "test", + region_id: IdMap.getId("region-france"), + items: [ + { + id: IdMap.getId("line"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + content: [ + { + unit_price: 8, + variant: { + id: IdMap.getId("eur-8-us-10"), + }, + product: { + id: IdMap.getId("product"), + }, + quantity: 1, + }, + { + unit_price: 10, + variant: { + id: IdMap.getId("eur-10-us-12"), + }, + product: { + id: IdMap.getId("product"), + }, + quantity: 1, + }, + ], + quantity: 10, + }, + { + id: IdMap.getId("existingLine"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + content: { + unit_price: 10, + variant: { + id: IdMap.getId("eur-10-us-12"), + }, + product: { + id: IdMap.getId("product"), + }, + quantity: 1, + }, + quantity: 10, + }, + ], + shipping_methods: [ + { + id: IdMap.getId("freeShipping"), + profile_id: "default_profile", + }, + ], + shipping_options: [ + { + id: IdMap.getId("freeShipping"), + profile_id: "default_profile", + }, + ], + payment_sessions: [ + { + provider_id: "stripe", + data: { + id: "pi_no", + customer: IdMap.getId("not-lebron"), + }, + }, + ], + payment_method: { + provider_id: "stripe", + data: { + id: "pi_no", + customer: IdMap.getId("not-lebron"), + }, + }, + shipping_address: {}, + billing_address: {}, + discounts: [], + customer_id: IdMap.getId("vvd"), + }, +} + +export const CartServiceMock = { + withTransaction: function () { + return this + }, + retrieve: jest.fn().mockImplementation((cartId) => { + if (cartId === IdMap.getId("fr-cart")) { + return Promise.resolve(carts.frCart) + } + if (cartId === IdMap.getId("fr-cart-no-customer")) { + return Promise.resolve(carts.frCartNoStripeCustomer) + } + if (cartId === IdMap.getId("emptyCart")) { + return Promise.resolve(carts.emptyCart) + } + return Promise.resolve(undefined) + }), + updatePaymentSession: jest + .fn() + .mockImplementation((cartId, stripe, paymentIntent) => { + return Promise.resolve() + }), +} + +const mock = jest.fn().mockImplementation(() => { + return CartServiceMock +}) + +export default mock diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/customer.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/customer.ts new file mode 100644 index 0000000000000..421f661e8806a --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/__mocks__/customer.ts @@ -0,0 +1,39 @@ +import { IdMap } from "medusa-test-utils" + +export const CustomerServiceMock = { + withTransaction: function () { + return this + }, + retrieve: jest.fn().mockImplementation((id) => { + if (id === IdMap.getId("lebron")) { + return Promise.resolve({ + _id: IdMap.getId("lebron"), + first_name: "LeBron", + last_name: "James", + email: "lebron@james.com", + password_hash: "1234", + metadata: { + stripe_id: "cus_123456789_new", + }, + }) + } + if (id === IdMap.getId("vvd")) { + return Promise.resolve({ + _id: IdMap.getId("vvd"), + first_name: "Virgil", + last_name: "Van Dijk", + email: "virg@vvd.com", + password_hash: "1234", + metadata: {}, + }) + } + return Promise.resolve(undefined) + }), + setMetadata: jest.fn().mockReturnValue(Promise.resolve()), +} + +const mock = jest.fn().mockImplementation(() => { + return CustomerServiceMock +}) + +export default mock diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/eventbus.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/eventbus.ts new file mode 100644 index 0000000000000..e9031d94284b5 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/__mocks__/eventbus.ts @@ -0,0 +1,10 @@ +export const EventBusServiceMock = { + emit: jest.fn(), + subscribe: jest.fn(), +} + +const mock = jest.fn().mockImplementation(() => { + return EventBusServiceMock +}) + +export default mock diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts new file mode 100644 index 0000000000000..7a1f6f1146824 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts @@ -0,0 +1,37 @@ +import { PaymentIntentDataByStatus } from "../__fixtures__/data"; + +function buildPaymentIntent(data) { + const paymentIntentData = {} + + return Object.assign(paymentIntentData, data) +} + +export const StripeMock = { + retrieve: jest.fn().mockImplementation(async (paymentId) => { + if (paymentId === PaymentIntentDataByStatus.REQUIRE_PAYMENT_METHOD) { + return buildPaymentIntent({ status: PaymentIntentDataByStatus.REQUIRE_PAYMENT_METHOD }) + } + if (paymentId === PaymentIntentDataByStatus.REQUIRES_CONFIRMATION) { + return buildPaymentIntent({ status: PaymentIntentDataByStatus.REQUIRES_CONFIRMATION }) + } + if (paymentId === PaymentIntentDataByStatus.PROCESSING) { + return buildPaymentIntent({ status: PaymentIntentDataByStatus.PROCESSING }) + } + if (paymentId === PaymentIntentDataByStatus.CANCELED) { + return buildPaymentIntent({ status: PaymentIntentDataByStatus.REQUIRES_ACTION }) + } + if (paymentId === PaymentIntentDataByStatus.CANCELED) { + return buildPaymentIntent({ status: PaymentIntentDataByStatus.CANCELED }) + } + if (paymentId === PaymentIntentDataByStatus.REQUIRES_CAPTURE) { + return buildPaymentIntent({ status: PaymentIntentDataByStatus.REQUIRES_CAPTURE }) + } + if (paymentId === PaymentIntentDataByStatus.SUCCEEDED) { + return buildPaymentIntent({ status: PaymentIntentDataByStatus.SUCCEEDED }) + } + }) +} + +const stripe = jest.fn(() => StripeMock) + +export default stripe diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/totals.js b/packages/medusa-payment-stripe-processor/src/__mocks__/totals.js new file mode 100644 index 0000000000000..5163d4ee662c6 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/__mocks__/totals.js @@ -0,0 +1,12 @@ +export const TotalsServiceMock = { + withTransaction: function () { + return this + }, + getTotal: jest.fn(), +} + +const mock = jest.fn().mockImplementation(() => { + return TotalsServiceMock +}) + +export default mock diff --git a/packages/medusa-payment-stripe-processor/src/helpers/__fixtures__/stripe-test.ts b/packages/medusa-payment-stripe-processor/src/helpers/__fixtures__/stripe-test.ts new file mode 100644 index 0000000000000..3452e78dd06ad --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/helpers/__fixtures__/stripe-test.ts @@ -0,0 +1,12 @@ +import StripeBase from "../stripe-base"; +import { PaymentIntentOptions } from "../../types"; + +export class StripeTest extends StripeBase { + constructor(_, options) { + super(_, options); + } + + get paymentIntentOptions(): PaymentIntentOptions { + return {} + } +} \ No newline at end of file diff --git a/packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.spec.ts new file mode 100644 index 0000000000000..937417ea940dd --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.spec.ts @@ -0,0 +1,30 @@ +import { StripeTest } from "../__fixtures__/stripe-test"; +import { PaymentIntentDataByStatus } from "../../__fixtures__/data"; +import { PaymentSessionStatus } from "@medusajs/medusa"; + +const container = {} + +const stripeTest = new StripeTest(container, { api_key: "test" }) + +describe("StripeTest", () => { + describe('getPaymentStatus', function () { + it("should return the correct status", async () => { + let status: PaymentSessionStatus + + status = await stripeTest.getPaymentStatus(PaymentIntentDataByStatus.REQUIRE_PAYMENT_METHOD.id) + expect(status).toBe(PaymentSessionStatus.PENDING) + + status = await stripeTest.getPaymentStatus(PaymentIntentDataByStatus.REQUIRES_CONFIRMATION.id) + expect(status).toBe(PaymentSessionStatus.PENDING) + + status = await stripeTest.getPaymentStatus(PaymentIntentDataByStatus.PROCESSING.id) + expect(status).toBe(PaymentSessionStatus.PENDING) + + status = await stripeTest.getPaymentStatus(PaymentIntentDataByStatus.REQUIRES_ACTION.id) + expect(status).toBe(PaymentSessionStatus.REQUIRES_MORE) + + status = await stripeTest.getPaymentStatus(PaymentIntentDataByStatus.CANCELED.id) + expect(status).toBe(PaymentSessionStatus.CANCELED) + }) + }); +}) diff --git a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts b/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts index 5139afe68e9ae..c892fed5506da 100644 --- a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts +++ b/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts @@ -8,11 +8,11 @@ import { } from "@medusajs/medusa" import { PaymentIntentOptions, StripeOptions } from "../types" -const ERROR_CODES = { +const ErrorCodes = { PAYMENT_INTENT_UNEXPECTED_STATE: "payment_intent_unexpected_state", } -const INTENT_STATUS = { +const ErrorIntentStatus = { SUCCEEDED: "succeeded", CANCELED: "canceled", } @@ -164,7 +164,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { paymentId )) as unknown as PaymentProcessorSessionResponse["session_data"] } catch (error) { - if (error.payment_intent.status === INTENT_STATUS.CANCELED) { + if (error.payment_intent.status === ErrorIntentStatus.CANCELED) { return error.payment_intent } @@ -185,8 +185,8 @@ abstract class StripeBase extends AbstractPaymentProcessor { const intent = await this.stripe_.paymentIntents.capture(id as string) return intent as unknown as PaymentProcessorSessionResponse["session_data"] } catch (error) { - if (error.code === ERROR_CODES.PAYMENT_INTENT_UNEXPECTED_STATE) { - if (error.payment_intent.status === INTENT_STATUS.SUCCEEDED) { + if (error.code === ErrorCodes.PAYMENT_INTENT_UNEXPECTED_STATE) { + if (error.payment_intent.status === ErrorIntentStatus.SUCCEEDED) { return error.payment_intent } } diff --git a/yarn.lock b/yarn.lock index 878433a3936a4..d1b769bfe1392 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5275,6 +5275,44 @@ __metadata: languageName: unknown linkType: soft +"@medusajs/medusa-cli@npm:^1.3.8": + version: 1.3.8 + resolution: "@medusajs/medusa-cli@npm:1.3.8" + dependencies: + "@babel/polyfill": ^7.8.7 + "@babel/runtime": ^7.9.6 + axios: ^0.21.4 + chalk: ^4.0.0 + configstore: 5.0.1 + core-js: ^3.6.5 + dotenv: ^8.2.0 + execa: ^5.1.1 + fs-exists-cached: ^1.0.0 + fs-extra: ^10.0.0 + hosted-git-info: ^4.0.2 + inquirer: ^8.0.0 + is-valid-path: ^0.1.1 + meant: ^1.0.3 + medusa-core-utils: ^1.1.39 + medusa-telemetry: 0.0.16 + netrc-parser: ^3.1.6 + open: ^8.0.6 + ora: ^5.4.1 + pg-god: ^1.0.12 + prompts: ^2.4.2 + regenerator-runtime: ^0.13.11 + resolve-cwd: ^3.0.0 + stack-trace: ^0.0.10 + ulid: ^2.3.0 + url: ^0.11.0 + winston: ^3.8.2 + yargs: ^15.3.1 + bin: + medusa: cli.js + checksum: 8d18ac9b20bbfbb8fdcfc23293169744ef77339f6a4c063e0838466b871a105109baccc60def36a75f03544bd653727e9feed113c7799105512cacdbf443e990 + languageName: node + linkType: hard + "@medusajs/medusa-js@^1.3.8, @medusajs/medusa-js@workspace:packages/medusa-js": version: 0.0.0-use.local resolution: "@medusajs/medusa-js@workspace:packages/medusa-js" @@ -25409,6 +25447,16 @@ __metadata: languageName: unknown linkType: soft +"medusa-core-utils@npm:^1.1.39": + version: 1.1.39 + resolution: "medusa-core-utils@npm:1.1.39" + dependencies: + joi: ^17.3.0 + joi-objectid: ^3.0.1 + checksum: 203885dbe3cbe0f1cc0218ae65a3e9267a3bbc5f1441e38bed980c19b4e5ec047692751b3cb00f988377715a5e764967dbd38da7fd80ea8de12cb05f70fdf0f8 + languageName: node + linkType: hard + "medusa-dev-cli@workspace:packages/medusa-dev-cli": version: 0.0.0-use.local resolution: "medusa-dev-cli@workspace:packages/medusa-dev-cli" @@ -25710,17 +25758,16 @@ __metadata: version: 0.0.0-use.local resolution: "medusa-payment-stripe-processor@workspace:packages/medusa-payment-stripe-processor" dependencies: + "@medusajs/medusa": ^1.7.7 "@types/stripe": ^8.0.417 body-parser: ^1.19.0 cross-env: ^5.2.1 express: ^4.17.1 jest: ^25.5.4 medusa-core-utils: ^1.1.38 - medusa-interfaces: ^1.3.5 - medusa-test-utils: ^1.1.37 stripe: ^11.10.0 peerDependencies: - medusa-interfaces: 1.3.5 + "@medusajs/medusa": ^1.7.7 languageName: unknown linkType: soft From 605ad0a8f8aabcaa6ab0b477475a4eecaa5f519d Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 15 Feb 2023 12:11:36 +0100 Subject: [PATCH 06/36] cleanup --- .../package.json | 2 +- .../__fixtures__/stripe-test.ts | 0 .../__tests__/stripe-base.js | 0 .../__tests__/stripe-base.spec.ts | 0 .../src/{helpers => core}/stripe-base.ts | 50 ++++++++++++------- .../src/services/stripe-bancontact.ts | 4 +- .../src/services/stripe-blik.ts | 4 +- .../src/services/stripe-giropay.ts | 4 +- .../src/services/stripe-ideal.ts | 4 +- .../src/services/stripe-provider.ts | 4 +- .../src/services/stripe-przelewy24.ts | 4 +- yarn.lock | 17 ------- 12 files changed, 44 insertions(+), 49 deletions(-) rename packages/medusa-payment-stripe-processor/src/{helpers => core}/__fixtures__/stripe-test.ts (100%) rename packages/medusa-payment-stripe-processor/src/{helpers => core}/__tests__/stripe-base.js (100%) rename packages/medusa-payment-stripe-processor/src/{helpers => core}/__tests__/stripe-base.spec.ts (100%) rename packages/medusa-payment-stripe-processor/src/{helpers => core}/stripe-base.ts (88%) diff --git a/packages/medusa-payment-stripe-processor/package.json b/packages/medusa-payment-stripe-processor/package.json index f4b739e59448e..70d7806ed00c8 100644 --- a/packages/medusa-payment-stripe-processor/package.json +++ b/packages/medusa-payment-stripe-processor/package.json @@ -1,5 +1,5 @@ { - "name": "medusa-payment-stripe-processor", + "name": "@medusajs/medusa-payment-stripe-processor", "version": "0.0.1", "description": "Stripe Payment provider for Meduas Commerce", "main": "dist/index.js", diff --git a/packages/medusa-payment-stripe-processor/src/helpers/__fixtures__/stripe-test.ts b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/stripe-test.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/helpers/__fixtures__/stripe-test.ts rename to packages/medusa-payment-stripe-processor/src/core/__fixtures__/stripe-test.ts diff --git a/packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.js b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.js similarity index 100% rename from packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.js rename to packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.js diff --git a/packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/helpers/__tests__/stripe-base.spec.ts rename to packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts diff --git a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts b/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts similarity index 88% rename from packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts rename to packages/medusa-payment-stripe-processor/src/core/stripe-base.ts index c892fed5506da..cf6e1875f5117 100644 --- a/packages/medusa-payment-stripe-processor/src/helpers/stripe-base.ts +++ b/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts @@ -56,8 +56,11 @@ abstract class StripeBase extends AbstractPaymentProcessor { return options } - async getPaymentStatus(paymentId: string): Promise { - const paymentIntent = await this.stripe_.paymentIntents.retrieve(paymentId) + async getPaymentStatus( + paymentSessionData: Record + ): Promise { + const id = paymentSessionData.id as string + const paymentIntent = await this.stripe_.paymentIntents.retrieve(id) switch (paymentIntent.status) { case "requires_payment_method": @@ -148,20 +151,28 @@ abstract class StripeBase extends AbstractPaymentProcessor { } async authorizePayment( - context: PaymentProcessorContext - ): Promise { - const id = context.paymentSessionData.id as string - await this.getPaymentStatus(id) + paymentSessionData: Record, + context: Record + ): Promise< + | PaymentProcessorError + | { + status: PaymentSessionStatus + data: PaymentProcessorSessionResponse["session_data"] + } + > { + const status = await this.getPaymentStatus(paymentSessionData) + return { data: paymentSessionData, status } } async cancelPayment( - paymentId: string + paymentSessionData: Record ): Promise< PaymentProcessorError | PaymentProcessorSessionResponse["session_data"] > { try { + const id = paymentSessionData.id as string return (await this.stripe_.paymentIntents.cancel( - paymentId + id )) as unknown as PaymentProcessorSessionResponse["session_data"] } catch (error) { if (error.payment_intent.status === ErrorIntentStatus.CANCELED) { @@ -180,9 +191,9 @@ abstract class StripeBase extends AbstractPaymentProcessor { ): Promise< PaymentProcessorError | PaymentProcessorSessionResponse["session_data"] > { - const { id } = context.paymentSessionData + const id = context.paymentSessionData.id as string try { - const intent = await this.stripe_.paymentIntents.capture(id as string) + const intent = await this.stripe_.paymentIntents.capture(id) return intent as unknown as PaymentProcessorSessionResponse["session_data"] } catch (error) { if (error.code === ErrorCodes.PAYMENT_INTENT_UNEXPECTED_STATE) { @@ -199,24 +210,24 @@ abstract class StripeBase extends AbstractPaymentProcessor { } async deletePayment( - paymentId: string + paymentSessionData: Record ): Promise< PaymentProcessorError | PaymentProcessorSessionResponse["session_data"] > { - return await this.cancelPayment(paymentId) + return await this.cancelPayment(paymentSessionData) } async refundPayment( - context: PaymentProcessorContext + paymentSessionData: Record, + refundAmount: number ): Promise< PaymentProcessorError | PaymentProcessorSessionResponse["session_data"] > { - const { amount } = context - const { id } = context.paymentSessionData + const id = paymentSessionData.id as string try { await this.stripe_.refunds.create({ - amount: Math.round(amount), + amount: Math.round(refundAmount), payment_intent: id as string, }) } catch (e) { @@ -226,16 +237,17 @@ abstract class StripeBase extends AbstractPaymentProcessor { ) } - return context.paymentSessionData + return paymentSessionData } async retrievePayment( - paymentId: string + paymentSessionData: Record ): Promise< PaymentProcessorError | PaymentProcessorSessionResponse["session_data"] > { try { - const intent = await this.stripe_.paymentIntents.retrieve(paymentId) + const id = paymentSessionData.id as string + const intent = await this.stripe_.paymentIntents.retrieve(id) return intent as unknown as PaymentProcessorSessionResponse["session_data"] } catch (e) { return this.buildError("An error occurred in retrievePayment", e) diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts index d39babbf22545..970e04d64ab2b 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts @@ -1,5 +1,5 @@ -import StripeBase from "../helpers/stripe-base" -import { PaymentIntentOptions } from "../types"; +import StripeBase from "../core/stripe-base" +import { PaymentIntentOptions } from "../types" class BancontactProviderService extends StripeBase { static identifier = "stripe-bancontact" diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts index ece460b6b32e1..895003e6fd356 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts @@ -1,5 +1,5 @@ -import StripeBase from "../helpers/stripe-base" -import { PaymentIntentOptions } from "../types"; +import StripeBase from "../core/stripe-base" +import { PaymentIntentOptions } from "../types" class BlikProviderService extends StripeBase { static identifier = "stripe-blik" diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts index 123eb0fc62deb..c486e5dbe2697 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts @@ -1,5 +1,5 @@ -import StripeBase from "../helpers/stripe-base" -import { PaymentIntentOptions } from "../types"; +import StripeBase from "../core/stripe-base" +import { PaymentIntentOptions } from "../types" class GiropayProviderService extends StripeBase { static identifier = "stripe-giropay" diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts index e4c8408c25085..336b9c698e45a 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts @@ -1,5 +1,5 @@ -import StripeBase from "../helpers/stripe-base" -import { PaymentIntentOptions } from "../types"; +import StripeBase from "../core/stripe-base" +import { PaymentIntentOptions } from "../types" class IdealProviderService extends StripeBase { static identifier = "stripe-ideal" diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts index 7b9512253991d..547f2dd72ee01 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts @@ -1,5 +1,5 @@ -import StripeBase from "../helpers/stripe-base"; -import { PaymentIntentOptions } from "../types"; +import StripeBase from "../core/stripe-base" +import { PaymentIntentOptions } from "../types" class StripeProviderService extends StripeBase { static identifier = "stripe" diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts b/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts index cec220c26f385..62daf61b1b457 100644 --- a/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts +++ b/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts @@ -1,5 +1,5 @@ -import StripeBase from "../helpers/stripe-base" -import { PaymentIntentOptions } from "../types"; +import StripeBase from "../core/stripe-base" +import { PaymentIntentOptions } from "../types" class Przelewy24ProviderService extends StripeBase { static identifier = "stripe-przelewy24" diff --git a/yarn.lock b/yarn.lock index d1b769bfe1392..fac4fe58a498a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25754,23 +25754,6 @@ __metadata: languageName: unknown linkType: soft -"medusa-payment-stripe-processor@workspace:packages/medusa-payment-stripe-processor": - version: 0.0.0-use.local - resolution: "medusa-payment-stripe-processor@workspace:packages/medusa-payment-stripe-processor" - dependencies: - "@medusajs/medusa": ^1.7.7 - "@types/stripe": ^8.0.417 - body-parser: ^1.19.0 - cross-env: ^5.2.1 - express: ^4.17.1 - jest: ^25.5.4 - medusa-core-utils: ^1.1.38 - stripe: ^11.10.0 - peerDependencies: - "@medusajs/medusa": ^1.7.7 - languageName: unknown - linkType: soft - "medusa-payment-stripe@workspace:packages/medusa-payment-stripe": version: 0.0.0-use.local resolution: "medusa-payment-stripe@workspace:packages/medusa-payment-stripe" From ee4587bbc35aacce2a6aea331224ac1487b446f3 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 15 Feb 2023 14:48:56 +0100 Subject: [PATCH 07/36] Initiate payment unit tests --- .../src/__mocks__/cart.ts | 216 ------------------ .../src/__mocks__/customer.ts | 39 ---- .../src/__mocks__/eventbus.ts | 10 - .../src/__mocks__/stripe.ts | 55 +++-- .../src/__mocks__/totals.js | 12 - .../src/core/__fixtures__/data.ts | 50 ++++ .../src/core/__tests__/stripe-base.spec.ts | 168 +++++++++++++- 7 files changed, 238 insertions(+), 312 deletions(-) delete mode 100644 packages/medusa-payment-stripe-processor/src/__mocks__/cart.ts delete mode 100644 packages/medusa-payment-stripe-processor/src/__mocks__/customer.ts delete mode 100644 packages/medusa-payment-stripe-processor/src/__mocks__/eventbus.ts delete mode 100644 packages/medusa-payment-stripe-processor/src/__mocks__/totals.js create mode 100644 packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/cart.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/cart.ts deleted file mode 100644 index c301361bdaad7..0000000000000 --- a/packages/medusa-payment-stripe-processor/src/__mocks__/cart.ts +++ /dev/null @@ -1,216 +0,0 @@ -import { IdMap } from "medusa-test-utils" - -export const carts = { - emptyCart: { - id: IdMap.getId("emptyCart"), - items: [], - region_id: IdMap.getId("testRegion"), - customer_id: "test-customer", - payment_sessions: [], - shipping_options: [ - { - id: IdMap.getId("freeShipping"), - profile_id: "default_profile", - data: { - some_data: "yes", - }, - }, - ], - }, - frCart: { - id: IdMap.getId("fr-cart"), - email: "lebron@james.com", - title: "test", - region_id: IdMap.getId("region-france"), - items: [ - { - id: IdMap.getId("line"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - - unit_price: 8, - variant: { - id: IdMap.getId("eur-8-us-10"), - }, - product: { - id: IdMap.getId("product"), - }, - // { - // unit_price: 10, - // variant: { - // id: IdMap.getId("eur-10-us-12"), - // }, - // product: { - // id: IdMap.getId("product"), - // }, - // quantity: 1, - // }, - quantity: 10, - }, - { - id: IdMap.getId("existingLine"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - unit_price: 10, - variant: { - id: IdMap.getId("eur-10-us-12"), - }, - product: { - id: IdMap.getId("product"), - }, - quantity: 1, - }, - ], - shipping_methods: [ - { - id: IdMap.getId("freeShipping"), - profile_id: "default_profile", - }, - ], - shipping_options: [ - { - id: IdMap.getId("freeShipping"), - profile_id: "default_profile", - }, - ], - payment_sessions: [ - { - provider_id: "stripe", - data: { - id: "pi_123456789", - customer: IdMap.getId("not-lebron"), - }, - }, - ], - payment_method: { - provider_id: "stripe", - data: { - id: "pi_123456789", - customer: IdMap.getId("not-lebron"), - }, - }, - region: { currency_code: "usd" }, - total: 100, - shipping_address: {}, - billing_address: {}, - discounts: [], - customer_id: IdMap.getId("lebron"), - context: {} - }, - frCartNoStripeCustomer: { - id: IdMap.getId("fr-cart-no-customer"), - title: "test", - region_id: IdMap.getId("region-france"), - items: [ - { - id: IdMap.getId("line"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - content: [ - { - unit_price: 8, - variant: { - id: IdMap.getId("eur-8-us-10"), - }, - product: { - id: IdMap.getId("product"), - }, - quantity: 1, - }, - { - unit_price: 10, - variant: { - id: IdMap.getId("eur-10-us-12"), - }, - product: { - id: IdMap.getId("product"), - }, - quantity: 1, - }, - ], - quantity: 10, - }, - { - id: IdMap.getId("existingLine"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - content: { - unit_price: 10, - variant: { - id: IdMap.getId("eur-10-us-12"), - }, - product: { - id: IdMap.getId("product"), - }, - quantity: 1, - }, - quantity: 10, - }, - ], - shipping_methods: [ - { - id: IdMap.getId("freeShipping"), - profile_id: "default_profile", - }, - ], - shipping_options: [ - { - id: IdMap.getId("freeShipping"), - profile_id: "default_profile", - }, - ], - payment_sessions: [ - { - provider_id: "stripe", - data: { - id: "pi_no", - customer: IdMap.getId("not-lebron"), - }, - }, - ], - payment_method: { - provider_id: "stripe", - data: { - id: "pi_no", - customer: IdMap.getId("not-lebron"), - }, - }, - shipping_address: {}, - billing_address: {}, - discounts: [], - customer_id: IdMap.getId("vvd"), - }, -} - -export const CartServiceMock = { - withTransaction: function () { - return this - }, - retrieve: jest.fn().mockImplementation((cartId) => { - if (cartId === IdMap.getId("fr-cart")) { - return Promise.resolve(carts.frCart) - } - if (cartId === IdMap.getId("fr-cart-no-customer")) { - return Promise.resolve(carts.frCartNoStripeCustomer) - } - if (cartId === IdMap.getId("emptyCart")) { - return Promise.resolve(carts.emptyCart) - } - return Promise.resolve(undefined) - }), - updatePaymentSession: jest - .fn() - .mockImplementation((cartId, stripe, paymentIntent) => { - return Promise.resolve() - }), -} - -const mock = jest.fn().mockImplementation(() => { - return CartServiceMock -}) - -export default mock diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/customer.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/customer.ts deleted file mode 100644 index 421f661e8806a..0000000000000 --- a/packages/medusa-payment-stripe-processor/src/__mocks__/customer.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { IdMap } from "medusa-test-utils" - -export const CustomerServiceMock = { - withTransaction: function () { - return this - }, - retrieve: jest.fn().mockImplementation((id) => { - if (id === IdMap.getId("lebron")) { - return Promise.resolve({ - _id: IdMap.getId("lebron"), - first_name: "LeBron", - last_name: "James", - email: "lebron@james.com", - password_hash: "1234", - metadata: { - stripe_id: "cus_123456789_new", - }, - }) - } - if (id === IdMap.getId("vvd")) { - return Promise.resolve({ - _id: IdMap.getId("vvd"), - first_name: "Virgil", - last_name: "Van Dijk", - email: "virg@vvd.com", - password_hash: "1234", - metadata: {}, - }) - } - return Promise.resolve(undefined) - }), - setMetadata: jest.fn().mockReturnValue(Promise.resolve()), -} - -const mock = jest.fn().mockImplementation(() => { - return CustomerServiceMock -}) - -export default mock diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/eventbus.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/eventbus.ts deleted file mode 100644 index e9031d94284b5..0000000000000 --- a/packages/medusa-payment-stripe-processor/src/__mocks__/eventbus.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const EventBusServiceMock = { - emit: jest.fn(), - subscribe: jest.fn(), -} - -const mock = jest.fn().mockImplementation(() => { - return EventBusServiceMock -}) - -export default mock diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts index 7a1f6f1146824..961da475a1685 100644 --- a/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts +++ b/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts @@ -1,4 +1,9 @@ -import { PaymentIntentDataByStatus } from "../__fixtures__/data"; +import { PaymentIntentDataByStatus } from "../__fixtures__/data" + +export const WRONG_CUSTOMER_EMAIL = "wrong@test.fr" +export const EXISTING_CUSTOMER_EMAIL = "right@test.fr" +export const NON_EXISTING_CUSTOMER_EMAIL = "right@test.fr" +export const STRIPE_ID = "test" function buildPaymentIntent(data) { const paymentIntentData = {} @@ -7,29 +12,31 @@ function buildPaymentIntent(data) { } export const StripeMock = { - retrieve: jest.fn().mockImplementation(async (paymentId) => { - if (paymentId === PaymentIntentDataByStatus.REQUIRE_PAYMENT_METHOD) { - return buildPaymentIntent({ status: PaymentIntentDataByStatus.REQUIRE_PAYMENT_METHOD }) - } - if (paymentId === PaymentIntentDataByStatus.REQUIRES_CONFIRMATION) { - return buildPaymentIntent({ status: PaymentIntentDataByStatus.REQUIRES_CONFIRMATION }) - } - if (paymentId === PaymentIntentDataByStatus.PROCESSING) { - return buildPaymentIntent({ status: PaymentIntentDataByStatus.PROCESSING }) - } - if (paymentId === PaymentIntentDataByStatus.CANCELED) { - return buildPaymentIntent({ status: PaymentIntentDataByStatus.REQUIRES_ACTION }) - } - if (paymentId === PaymentIntentDataByStatus.CANCELED) { - return buildPaymentIntent({ status: PaymentIntentDataByStatus.CANCELED }) - } - if (paymentId === PaymentIntentDataByStatus.REQUIRES_CAPTURE) { - return buildPaymentIntent({ status: PaymentIntentDataByStatus.REQUIRES_CAPTURE }) - } - if (paymentId === PaymentIntentDataByStatus.SUCCEEDED) { - return buildPaymentIntent({ status: PaymentIntentDataByStatus.SUCCEEDED }) - } - }) + paymentIntents: { + retrieve: jest.fn().mockImplementation(async (paymentId) => { + const data = Object.values(PaymentIntentDataByStatus).find(value => { + return value.id === paymentId + }) ?? {} + + return buildPaymentIntent(data) + }), + create: jest.fn().mockImplementation(async (data) => { + if (data.description === "fail") { + throw new Error("Error") + } + + return data + }) + }, + customers: { + create: jest.fn().mockImplementation(async data => { + if (data.email === EXISTING_CUSTOMER_EMAIL) { + return { id: STRIPE_ID, ...data } + } + + throw new Error("Error") + }) + }, } const stripe = jest.fn(() => StripeMock) diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/totals.js b/packages/medusa-payment-stripe-processor/src/__mocks__/totals.js deleted file mode 100644 index 5163d4ee662c6..0000000000000 --- a/packages/medusa-payment-stripe-processor/src/__mocks__/totals.js +++ /dev/null @@ -1,12 +0,0 @@ -export const TotalsServiceMock = { - withTransaction: function () { - return this - }, - getTotal: jest.fn(), -} - -const mock = jest.fn().mockImplementation(() => { - return TotalsServiceMock -}) - -export default mock diff --git a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts new file mode 100644 index 0000000000000..b7068c66d559c --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts @@ -0,0 +1,50 @@ +import { + EXISTING_CUSTOMER_EMAIL, + WRONG_CUSTOMER_EMAIL +} from "../../__mocks__/stripe"; + +export const initiatePaymentContextWithExistingCustomer = { + email: EXISTING_CUSTOMER_EMAIL, + currency_code: "usd", + amount: 1000, + resource_id: "test", + customer: {}, + context: {}, + paymentSessionData: {} +} + +export const initiatePaymentContextWithExistingCustomerStripeId = { + email: EXISTING_CUSTOMER_EMAIL, + currency_code: "usd", + amount: 1000, + resource_id: "test", + customer: { + metadata: { + stripe_id: "test" + } + }, + context: {}, + paymentSessionData: {} +} + +export const initiatePaymentContextWithWrongEmail = { + email: WRONG_CUSTOMER_EMAIL, + currency_code: "usd", + amount: 1000, + resource_id: "test", + customer: {}, + context: {}, + paymentSessionData: {} +} + +export const initiatePaymentContextWithFailIntentCreation = { + email: EXISTING_CUSTOMER_EMAIL, + currency_code: "usd", + amount: 1000, + resource_id: "test", + customer: {}, + context: { + description: "fail" + }, + paymentSessionData: {} +} diff --git a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts index 937417ea940dd..e65e390aec4a7 100644 --- a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts +++ b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts @@ -1,30 +1,176 @@ -import { StripeTest } from "../__fixtures__/stripe-test"; -import { PaymentIntentDataByStatus } from "../../__fixtures__/data"; -import { PaymentSessionStatus } from "@medusajs/medusa"; +import { StripeTest } from "../__fixtures__/stripe-test" +import { PaymentIntentDataByStatus } from "../../__fixtures__/data" +import { PaymentSessionStatus } from "@medusajs/medusa" +import { + initiatePaymentContextWithExistingCustomer, + initiatePaymentContextWithExistingCustomerStripeId, + initiatePaymentContextWithFailIntentCreation, + initiatePaymentContextWithWrongEmail +} from "../__fixtures__/data" +import { STRIPE_ID, StripeMock } from "../../__mocks__/stripe" const container = {} -const stripeTest = new StripeTest(container, { api_key: "test" }) - describe("StripeTest", () => { describe('getPaymentStatus', function () { + let stripeTest + + beforeAll(async () => { + const scopedContainer = { ...container } + stripeTest = new StripeTest(scopedContainer, { api_key: "test" }) + await stripeTest.init() + }) + it("should return the correct status", async () => { let status: PaymentSessionStatus - status = await stripeTest.getPaymentStatus(PaymentIntentDataByStatus.REQUIRE_PAYMENT_METHOD.id) + status = await stripeTest.getPaymentStatus({ + id: PaymentIntentDataByStatus.REQUIRE_PAYMENT_METHOD.id + }) expect(status).toBe(PaymentSessionStatus.PENDING) - status = await stripeTest.getPaymentStatus(PaymentIntentDataByStatus.REQUIRES_CONFIRMATION.id) + status = await stripeTest.getPaymentStatus({ + id: PaymentIntentDataByStatus.REQUIRES_CONFIRMATION.id + }) expect(status).toBe(PaymentSessionStatus.PENDING) - status = await stripeTest.getPaymentStatus(PaymentIntentDataByStatus.PROCESSING.id) + status = await stripeTest.getPaymentStatus({ + id: PaymentIntentDataByStatus.PROCESSING.id + }) expect(status).toBe(PaymentSessionStatus.PENDING) - status = await stripeTest.getPaymentStatus(PaymentIntentDataByStatus.REQUIRES_ACTION.id) + status = await stripeTest.getPaymentStatus({ + id: PaymentIntentDataByStatus.REQUIRES_ACTION.id + }) expect(status).toBe(PaymentSessionStatus.REQUIRES_MORE) - status = await stripeTest.getPaymentStatus(PaymentIntentDataByStatus.CANCELED.id) + status = await stripeTest.getPaymentStatus({ + id: PaymentIntentDataByStatus.CANCELED.id + }) expect(status).toBe(PaymentSessionStatus.CANCELED) + + status = await stripeTest.getPaymentStatus({ + id: PaymentIntentDataByStatus.REQUIRES_CAPTURE.id + }) + expect(status).toBe(PaymentSessionStatus.AUTHORIZED) + + status = await stripeTest.getPaymentStatus({ + id: PaymentIntentDataByStatus.SUCCEEDED.id + }) + expect(status).toBe(PaymentSessionStatus.AUTHORIZED) + + status = await stripeTest.getPaymentStatus({ + id: "unknown" + }) + expect(status).toBe(PaymentSessionStatus.PENDING) + }) + }) + + describe('initiatePayment', function () { + let stripeTest + + beforeAll(async () => { + const scopedContainer = { ...container } + stripeTest = new StripeTest(scopedContainer, { api_key: "test" }) + await stripeTest.init() + }) + + it("should succeed with an existing customer but no stripe id", async () => { + const result = await stripeTest.initiatePayment(initiatePaymentContextWithExistingCustomer) + + expect(StripeMock.customers.create).toHaveBeenCalled() + expect(StripeMock.customers.create).toHaveBeenCalledWith({ + email: initiatePaymentContextWithExistingCustomer.email + }) + + expect(StripeMock.paymentIntents.create).toHaveBeenCalled() + expect(StripeMock.paymentIntents.create).toHaveBeenCalledWith( + expect.objectContaining({ + description: undefined, + amount: initiatePaymentContextWithExistingCustomer.amount, + currency: initiatePaymentContextWithExistingCustomer.currency_code, + metadata: { resource_id: initiatePaymentContextWithExistingCustomer.resource_id }, + capture_method: "manual" + }) + ) + + expect(result).toEqual( + expect.objectContaining({ + session_data: expect.any(Object), + update_requests: { + customer_metadata: { + stripe_id: STRIPE_ID + } + } + }) + ) + }) + + it("should succeed with an existing customer with an existing stripe id", async () => { + const result = await stripeTest.initiatePayment(initiatePaymentContextWithExistingCustomerStripeId) + + expect(StripeMock.customers.create).not.toHaveBeenCalled() + + expect(StripeMock.paymentIntents.create).toHaveBeenCalled() + expect(StripeMock.paymentIntents.create).toHaveBeenCalledWith( + expect.objectContaining({ + description: undefined, + amount: initiatePaymentContextWithExistingCustomer.amount, + currency: initiatePaymentContextWithExistingCustomer.currency_code, + metadata: { resource_id: initiatePaymentContextWithExistingCustomer.resource_id }, + capture_method: "manual" + }) + ) + + expect(result).toEqual( + expect.objectContaining({ + session_data: expect.any(Object), + update_requests: undefined + }) + ) + }) + + it("should fail on customer creation", async () => { + const result = await stripeTest.initiatePayment(initiatePaymentContextWithWrongEmail) + + expect(StripeMock.customers.create).toHaveBeenCalled() + expect(StripeMock.customers.create).toHaveBeenCalledWith({ + email: initiatePaymentContextWithWrongEmail.email + }) + + expect(StripeMock.paymentIntents.create).not.toHaveBeenCalled() + + expect(result).toEqual({ + error: "An error occurred in InitiatePayment during the creation of the stripe customer", + code: undefined, + detail: undefined + }) + }) + + it("should fail on payment intents creation", async () => { + const result = await stripeTest.initiatePayment(initiatePaymentContextWithFailIntentCreation) + + expect(StripeMock.customers.create).toHaveBeenCalled() + expect(StripeMock.customers.create).toHaveBeenCalledWith({ + email: initiatePaymentContextWithFailIntentCreation.email + }) + + expect(StripeMock.paymentIntents.create).toHaveBeenCalled() + expect(StripeMock.paymentIntents.create).toHaveBeenCalledWith( + expect.objectContaining({ + description: initiatePaymentContextWithFailIntentCreation.context.description, + amount: initiatePaymentContextWithExistingCustomer.amount, + currency: initiatePaymentContextWithExistingCustomer.currency_code, + metadata: { resource_id: initiatePaymentContextWithExistingCustomer.resource_id }, + capture_method: "manual" + }) + ) + + expect(result).toEqual({ + error: "An error occurred in InitiatePayment during the creation of the stripe payment intent", + code: undefined, + detail: undefined + }) }) - }); + }) }) From 1351769a3a08be27c67376afd4bdeaae11ae7fc4 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 15 Feb 2023 15:09:39 +0100 Subject: [PATCH 08/36] unit test authorize and cancel payment --- .../src/__mocks__/stripe.ts | 29 +++++++- .../src/core/__fixtures__/data.ts | 25 +++++++ .../src/core/__tests__/stripe-base.spec.ts | 67 ++++++++++++++++++- .../src/core/stripe-base.ts | 18 ++--- .../src/types.ts | 11 ++- 5 files changed, 135 insertions(+), 15 deletions(-) diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts index 961da475a1685..a7963f71425d9 100644 --- a/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts +++ b/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts @@ -1,9 +1,12 @@ import { PaymentIntentDataByStatus } from "../__fixtures__/data" +import Stripe from "stripe"; +import { ErrorCodes, ErrorIntentStatus } from "../types"; export const WRONG_CUSTOMER_EMAIL = "wrong@test.fr" export const EXISTING_CUSTOMER_EMAIL = "right@test.fr" -export const NON_EXISTING_CUSTOMER_EMAIL = "right@test.fr" export const STRIPE_ID = "test" +export const PARTIALLY_FAIL_INTENT_ID = "partially_unknown" +export const FAIL_INTENT_ID = "unknown" function buildPaymentIntent(data) { const paymentIntentData = {} @@ -14,6 +17,10 @@ function buildPaymentIntent(data) { export const StripeMock = { paymentIntents: { retrieve: jest.fn().mockImplementation(async (paymentId) => { + if (paymentId === FAIL_INTENT_ID) { + throw new Error("Error") + } + const data = Object.values(PaymentIntentDataByStatus).find(value => { return value.id === paymentId }) ?? {} @@ -26,10 +33,28 @@ export const StripeMock = { } return data + }), + cancel: jest.fn().mockImplementation(async (paymentId) => { + if (paymentId === FAIL_INTENT_ID) { + throw new Error("Error") + } + + if (paymentId === PARTIALLY_FAIL_INTENT_ID) { + throw new Stripe.errors.StripeError({ + code: ErrorCodes.PAYMENT_INTENT_UNEXPECTED_STATE, + payment_intent: { + id: paymentId, + status: ErrorIntentStatus.CANCELED + } as unknown as Stripe.PaymentIntent, + type: "invalid_request_error" + }) + } + + return { id: paymentId } }) }, customers: { - create: jest.fn().mockImplementation(async data => { + create: jest.fn().mockImplementation(async (data) => { if (data.email === EXISTING_CUSTOMER_EMAIL) { return { id: STRIPE_ID, ...data } } diff --git a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts index b7068c66d559c..badc1f4437f52 100644 --- a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts +++ b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts @@ -1,7 +1,12 @@ import { EXISTING_CUSTOMER_EMAIL, + FAIL_INTENT_ID, + PARTIALLY_FAIL_INTENT_ID, WRONG_CUSTOMER_EMAIL } from "../../__mocks__/stripe"; +import { PaymentIntentDataByStatus } from "../../__fixtures__/data"; + +// INITIATE PAYMENT DATA export const initiatePaymentContextWithExistingCustomer = { email: EXISTING_CUSTOMER_EMAIL, @@ -48,3 +53,23 @@ export const initiatePaymentContextWithFailIntentCreation = { }, paymentSessionData: {} } + +// AUTHORIZE PAYMENT DATA + +export const authorizePaymentSuccessData = { + id: PaymentIntentDataByStatus.SUCCEEDED.id +} + +// CANCEL PAYMENT DATA + +export const cancelPaymentSuccessData = { + id: PaymentIntentDataByStatus.SUCCEEDED.id +} + +export const cancelPaymentFailData = { + id: FAIL_INTENT_ID +} + +export const cancelPaymentPartiallyFailData = { + id: PARTIALLY_FAIL_INTENT_ID +} diff --git a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts index e65e390aec4a7..82f7e83b065bd 100644 --- a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts +++ b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts @@ -2,12 +2,21 @@ import { StripeTest } from "../__fixtures__/stripe-test" import { PaymentIntentDataByStatus } from "../../__fixtures__/data" import { PaymentSessionStatus } from "@medusajs/medusa" import { + authorizePaymentSuccessData, + cancelPaymentFailData, + cancelPaymentPartiallyFailData, + cancelPaymentSuccessData, initiatePaymentContextWithExistingCustomer, initiatePaymentContextWithExistingCustomerStripeId, initiatePaymentContextWithFailIntentCreation, initiatePaymentContextWithWrongEmail } from "../__fixtures__/data" -import { STRIPE_ID, StripeMock } from "../../__mocks__/stripe" +import { + PARTIALLY_FAIL_INTENT_ID, + STRIPE_ID, + StripeMock +} from "../../__mocks__/stripe" +import { ErrorIntentStatus } from "../../types"; const container = {} @@ -173,4 +182,60 @@ describe("StripeTest", () => { }) }) }) + + describe('authorizePayment', function () { + let stripeTest + + beforeAll(async () => { + const scopedContainer = { ...container } + stripeTest = new StripeTest(scopedContainer, { api_key: "test" }) + await stripeTest.init() + }) + + it("should succeed", async () => { + const result = await stripeTest.authorizePayment(authorizePaymentSuccessData) + + expect(result).toEqual({ + data: authorizePaymentSuccessData, + status: PaymentSessionStatus.AUTHORIZED + }) + }) + }) + + describe('cancelPayment', function () { + let stripeTest + + beforeAll(async () => { + const scopedContainer = { ...container } + stripeTest = new StripeTest(scopedContainer, { api_key: "test" }) + await stripeTest.init() + }) + + it("should succeed", async () => { + const result = await stripeTest.cancelPayment(cancelPaymentSuccessData) + + expect(result).toEqual({ + id: PaymentIntentDataByStatus.SUCCEEDED.id + }) + }) + + it("should fail on intent cancellation but still return the intent", async () => { + const result = await stripeTest.cancelPayment(cancelPaymentPartiallyFailData) + + expect(result).toEqual({ + id: PARTIALLY_FAIL_INTENT_ID, + status: ErrorIntentStatus.CANCELED + }) + }) + + it("should fail on intent cancellation", async () => { + const result = await stripeTest.cancelPayment(cancelPaymentFailData) + + expect(result).toEqual({ + error: "An error occurred in cancelPayment during the cancellation of the payment", + code: undefined, + detail: undefined + }) + }) + }) }) diff --git a/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts b/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts index cf6e1875f5117..0deb70e508350 100644 --- a/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts +++ b/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts @@ -6,16 +6,12 @@ import { PaymentProcessorSessionResponse, PaymentSessionStatus, } from "@medusajs/medusa" -import { PaymentIntentOptions, StripeOptions } from "../types" - -const ErrorCodes = { - PAYMENT_INTENT_UNEXPECTED_STATE: "payment_intent_unexpected_state", -} - -const ErrorIntentStatus = { - SUCCEEDED: "succeeded", - CANCELED: "canceled", -} +import { + ErrorCodes, + ErrorIntentStatus, + PaymentIntentOptions, + StripeOptions, +} from "../types" abstract class StripeBase extends AbstractPaymentProcessor { static identifier = "" @@ -175,7 +171,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { id )) as unknown as PaymentProcessorSessionResponse["session_data"] } catch (error) { - if (error.payment_intent.status === ErrorIntentStatus.CANCELED) { + if (error.payment_intent?.status === ErrorIntentStatus.CANCELED) { return error.payment_intent } diff --git a/packages/medusa-payment-stripe-processor/src/types.ts b/packages/medusa-payment-stripe-processor/src/types.ts index 2850fdc9f6c1a..3b73d513605f8 100644 --- a/packages/medusa-payment-stripe-processor/src/types.ts +++ b/packages/medusa-payment-stripe-processor/src/types.ts @@ -19,4 +19,13 @@ export interface PaymentIntentOptions { capture_method?: "automatic" | "manual" setup_future_usage?: "on_session" | "off_session" payment_method_types?: string[] -} \ No newline at end of file +} + +export const ErrorCodes = { + PAYMENT_INTENT_UNEXPECTED_STATE: "payment_intent_unexpected_state", +} + +export const ErrorIntentStatus = { + SUCCEEDED: "succeeded", + CANCELED: "canceled", +} From d23dfa087c9e6ed3be4cfcb83a1cc04d66d1d963 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 15 Feb 2023 15:16:22 +0100 Subject: [PATCH 09/36] unit test capture payment --- .../src/__mocks__/stripe.ts | 18 +++++++++ .../src/core/__fixtures__/data.ts | 20 ++++++++++ .../src/core/__tests__/stripe-base.spec.ts | 40 +++++++++++++++++++ .../src/core/stripe-base.ts | 2 +- 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts index a7963f71425d9..f113f9000fda3 100644 --- a/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts +++ b/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts @@ -50,6 +50,24 @@ export const StripeMock = { }) } + return { id: paymentId } + }), + capture: jest.fn().mockImplementation(async (paymentId) => { + if (paymentId === FAIL_INTENT_ID) { + throw new Error("Error") + } + + if (paymentId === PARTIALLY_FAIL_INTENT_ID) { + throw new Stripe.errors.StripeError({ + code: ErrorCodes.PAYMENT_INTENT_UNEXPECTED_STATE, + payment_intent: { + id: paymentId, + status: ErrorIntentStatus.SUCCEEDED + } as unknown as Stripe.PaymentIntent, + type: "invalid_request_error" + }) + } + return { id: paymentId } }) }, diff --git a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts index badc1f4437f52..7a9f7d5a1f5b4 100644 --- a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts +++ b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts @@ -73,3 +73,23 @@ export const cancelPaymentFailData = { export const cancelPaymentPartiallyFailData = { id: PARTIALLY_FAIL_INTENT_ID } + +// CAPTURE PAYMENT DATA + +export const capturePaymentContextSuccessData = { + paymentSessionData: { + id: PaymentIntentDataByStatus.SUCCEEDED.id + } +} + +export const capturePaymentContextFailData = { + paymentSessionData: { + id: FAIL_INTENT_ID + } +} + +export const capturePaymentContextPartiallyFailData = { + paymentSessionData: { + id: PARTIALLY_FAIL_INTENT_ID + } +} diff --git a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts index 82f7e83b065bd..3e46be6d13a26 100644 --- a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts +++ b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts @@ -6,6 +6,9 @@ import { cancelPaymentFailData, cancelPaymentPartiallyFailData, cancelPaymentSuccessData, + capturePaymentContextFailData, + capturePaymentContextPartiallyFailData, + capturePaymentContextSuccessData, initiatePaymentContextWithExistingCustomer, initiatePaymentContextWithExistingCustomerStripeId, initiatePaymentContextWithFailIntentCreation, @@ -238,4 +241,41 @@ describe("StripeTest", () => { }) }) }) + + describe('capturePayment', function () { + let stripeTest + + beforeAll(async () => { + const scopedContainer = { ...container } + stripeTest = new StripeTest(scopedContainer, { api_key: "test" }) + await stripeTest.init() + }) + + it("should succeed", async () => { + const result = await stripeTest.capturePayment(capturePaymentContextSuccessData) + + expect(result).toEqual({ + id: PaymentIntentDataByStatus.SUCCEEDED.id + }) + }) + + it("should fail on intent capture but still return the intent", async () => { + const result = await stripeTest.capturePayment(capturePaymentContextPartiallyFailData) + + expect(result).toEqual({ + id: PARTIALLY_FAIL_INTENT_ID, + status: ErrorIntentStatus.SUCCEEDED + }) + }) + + it("should fail on intent capture", async () => { + const result = await stripeTest.capturePayment(capturePaymentContextFailData) + + expect(result).toEqual({ + error: "An error occurred in deletePayment during the capture of the payment", + code: undefined, + detail: undefined + }) + }) + }) }) diff --git a/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts b/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts index 0deb70e508350..44c2c20fb3647 100644 --- a/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts +++ b/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts @@ -193,7 +193,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { return intent as unknown as PaymentProcessorSessionResponse["session_data"] } catch (error) { if (error.code === ErrorCodes.PAYMENT_INTENT_UNEXPECTED_STATE) { - if (error.payment_intent.status === ErrorIntentStatus.SUCCEEDED) { + if (error.payment_intent?.status === ErrorIntentStatus.SUCCEEDED) { return error.payment_intent } } From efd246ff8c50e8737d1d79547c75df15cdb831c9 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 15 Feb 2023 15:18:05 +0100 Subject: [PATCH 10/36] unit test delete payment --- .../src/core/__fixtures__/data.ts | 14 +++++++ .../src/core/__tests__/stripe-base.spec.ts | 40 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts index 7a9f7d5a1f5b4..464ac97615519 100644 --- a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts +++ b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts @@ -93,3 +93,17 @@ export const capturePaymentContextPartiallyFailData = { id: PARTIALLY_FAIL_INTENT_ID } } + +// DELETE PAYMENT DATA + +export const deletePaymentSuccessData = { + id: PaymentIntentDataByStatus.SUCCEEDED.id +} + +export const deletePaymentFailData = { + id: FAIL_INTENT_ID +} + +export const deletePaymentPartiallyFailData = { + id: PARTIALLY_FAIL_INTENT_ID +} \ No newline at end of file diff --git a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts index 3e46be6d13a26..9b3e95ba0b4f0 100644 --- a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts +++ b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts @@ -9,6 +9,9 @@ import { capturePaymentContextFailData, capturePaymentContextPartiallyFailData, capturePaymentContextSuccessData, + deletePaymentFailData, + deletePaymentPartiallyFailData, + deletePaymentSuccessData, initiatePaymentContextWithExistingCustomer, initiatePaymentContextWithExistingCustomerStripeId, initiatePaymentContextWithFailIntentCreation, @@ -278,4 +281,41 @@ describe("StripeTest", () => { }) }) }) + + describe('deletePayment', function () { + let stripeTest + + beforeAll(async () => { + const scopedContainer = { ...container } + stripeTest = new StripeTest(scopedContainer, { api_key: "test" }) + await stripeTest.init() + }) + + it("should succeed", async () => { + const result = await stripeTest.cancelPayment(deletePaymentSuccessData) + + expect(result).toEqual({ + id: PaymentIntentDataByStatus.SUCCEEDED.id + }) + }) + + it("should fail on intent cancellation but still return the intent", async () => { + const result = await stripeTest.cancelPayment(deletePaymentPartiallyFailData) + + expect(result).toEqual({ + id: PARTIALLY_FAIL_INTENT_ID, + status: ErrorIntentStatus.CANCELED + }) + }) + + it("should fail on intent cancellation", async () => { + const result = await stripeTest.cancelPayment(deletePaymentFailData) + + expect(result).toEqual({ + error: "An error occurred in cancelPayment during the cancellation of the payment", + code: undefined, + detail: undefined + }) + }) + }) }) From 3fe56b38917ca7856656a010eec7bbc4f065146d Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 15 Feb 2023 15:34:05 +0100 Subject: [PATCH 11/36] miscelaneous --- packages/medusa-payment-paypal/package.json | 2 +- packages/medusa-payment-stripe-processor/package.json | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/medusa-payment-paypal/package.json b/packages/medusa-payment-paypal/package.json index 32f908b8411be..2bb9ec35bc687 100644 --- a/packages/medusa-payment-paypal/package.json +++ b/packages/medusa-payment-paypal/package.json @@ -1,7 +1,7 @@ { "name": "medusa-payment-paypal", "version": "1.2.10", - "description": "Paypal Payment provider for Meduas Commerce", + "description": "Paypal Payment provider for Medusa Commerce", "main": "index.js", "repository": { "type": "git", diff --git a/packages/medusa-payment-stripe-processor/package.json b/packages/medusa-payment-stripe-processor/package.json index 70d7806ed00c8..d29cbf831bb66 100644 --- a/packages/medusa-payment-stripe-processor/package.json +++ b/packages/medusa-payment-stripe-processor/package.json @@ -1,7 +1,7 @@ { - "name": "@medusajs/medusa-payment-stripe-processor", + "name": "medusa-payment-stripe-processor", "version": "0.0.1", - "description": "Stripe Payment provider for Meduas Commerce", + "description": "Stripe Payment provider for Medusa Commerce", "main": "dist/index.js", "keywords": [ "medusa-plugin", @@ -40,5 +40,6 @@ "express": "^4.17.1", "medusa-core-utils": "^1.1.38", "stripe": "^11.10.0" - } + }, + "gitHead": "cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e" } From 64878bc2029d0b2c50ba25e4bf7c9879ddd351bd Mon Sep 17 00:00:00 2001 From: adrien2p Date: Mon, 20 Feb 2023 12:48:34 +0100 Subject: [PATCH 12/36] finalise stripe base unit test --- .../src/__mocks__/stripe.ts | 26 +- .../src/core/__fixtures__/data.ts | 109 ++++++- .../src/core/__tests__/stripe-base.js | 284 ------------------ .../src/core/__tests__/stripe-base.spec.ts | 218 +++++++++++++- .../src/core/stripe-base.ts | 27 +- yarn.lock | 67 ++--- 6 files changed, 374 insertions(+), 357 deletions(-) delete mode 100644 packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.js diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts b/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts index f113f9000fda3..9b99382ca363c 100644 --- a/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts +++ b/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts @@ -8,12 +8,6 @@ export const STRIPE_ID = "test" export const PARTIALLY_FAIL_INTENT_ID = "partially_unknown" export const FAIL_INTENT_ID = "unknown" -function buildPaymentIntent(data) { - const paymentIntentData = {} - - return Object.assign(paymentIntentData, data) -} - export const StripeMock = { paymentIntents: { retrieve: jest.fn().mockImplementation(async (paymentId) => { @@ -21,11 +15,20 @@ export const StripeMock = { throw new Error("Error") } + return Object.values(PaymentIntentDataByStatus).find(value => { + return value.id === paymentId + }) ?? {} + }), + update: jest.fn().mockImplementation(async (paymentId, updateData) => { + if (paymentId === FAIL_INTENT_ID) { + throw new Error("Error") + } + const data = Object.values(PaymentIntentDataByStatus).find(value => { return value.id === paymentId }) ?? {} - return buildPaymentIntent(data) + return { ...data, ...updateData } }), create: jest.fn().mockImplementation(async (data) => { if (data.description === "fail") { @@ -71,6 +74,15 @@ export const StripeMock = { return { id: paymentId } }) }, + refunds: { + create: jest.fn().mockImplementation(async ({ payment_intent: paymentId }) => { + if (paymentId === FAIL_INTENT_ID) { + throw new Error("Error") + } + + return { id: paymentId } + }) + }, customers: { create: jest.fn().mockImplementation(async (data) => { if (data.email === EXISTING_CUSTOMER_EMAIL) { diff --git a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts index 464ac97615519..6d22d871f2019 100644 --- a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts +++ b/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts @@ -49,7 +49,7 @@ export const initiatePaymentContextWithFailIntentCreation = { resource_id: "test", customer: {}, context: { - description: "fail" + payment_description: "fail" }, paymentSessionData: {} } @@ -106,4 +106,109 @@ export const deletePaymentFailData = { export const deletePaymentPartiallyFailData = { id: PARTIALLY_FAIL_INTENT_ID -} \ No newline at end of file +} + +// REFUND PAYMENT DATA + +export const refundPaymentSuccessData = { + id: PaymentIntentDataByStatus.SUCCEEDED.id +} + +export const refundPaymentFailData = { + id: FAIL_INTENT_ID +} + +// RETRIEVE PAYMENT DATA + +export const retrievePaymentSuccessData = { + id: PaymentIntentDataByStatus.SUCCEEDED.id +} + +export const retrievePaymentFailData = { + id: FAIL_INTENT_ID +} + +// UPDATE PAYMENT DATA + +export const updatePaymentContextWithExistingCustomer = { + email: EXISTING_CUSTOMER_EMAIL, + currency_code: "usd", + amount: 1000, + resource_id: "test", + customer: {}, + context: {}, + paymentSessionData: { + customer: "test", + amount: 1000, + } +} + +export const updatePaymentContextWithExistingCustomerStripeId = { + email: EXISTING_CUSTOMER_EMAIL, + currency_code: "usd", + amount: 1000, + resource_id: "test", + customer: { + metadata: { + stripe_id: "test" + } + }, + context: {}, + paymentSessionData: { + customer: "test", + amount: 1000, + } +} + +export const updatePaymentContextWithWrongEmail = { + email: WRONG_CUSTOMER_EMAIL, + currency_code: "usd", + amount: 1000, + resource_id: "test", + customer: {}, + context: {}, + paymentSessionData: { + customer: "test", + amount: 1000, + } +} + +export const updatePaymentContextWithDifferentAmount = { + email: WRONG_CUSTOMER_EMAIL, + currency_code: "usd", + amount: 2000, + resource_id: "test", + customer: { + metadata: { + stripe_id: "test" + } + }, + context: {}, + paymentSessionData: { + id: PaymentIntentDataByStatus.SUCCEEDED.id, + customer: "test", + amount: 1000, + } +} + +export const updatePaymentContextFailWithDifferentAmount = { + email: WRONG_CUSTOMER_EMAIL, + currency_code: "usd", + amount: 2000, + resource_id: "test", + customer: { + metadata: { + stripe_id: "test" + } + }, + context: { + metadata: { + stripe_id: "test" + } + }, + paymentSessionData: { + id: FAIL_INTENT_ID, + customer: "test", + amount: 1000, + } +} diff --git a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.js b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.js deleted file mode 100644 index 7bd3cf247d650..0000000000000 --- a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.js +++ /dev/null @@ -1,284 +0,0 @@ -import { carts } from "../../__mocks__/cart" -import StripeBase from "../stripe-base"; - -const fakeContainer = {} - -describe("StripeBase", () => { - describe("createPayment", () => { - let result - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test" - } - ) - - beforeEach(async () => { - jest.clearAllMocks() - }) - - it("returns created stripe payment intent for cart with existing customer", async () => { - const cart = carts.frCart - const context = { - cart, - amount: cart.total, - currency_code: cart.region?.currency_code, - } - Object.assign(context, cart) - - result = await stripeBase.createPayment(context) - expect(result).toEqual({ - session_data: { - id: "pi_lebron", - customer: "cus_lebron", - description: undefined, - amount: 100, - }, - update_requests: { - customer_metadata: { - stripe_id: "cus_lebron" - } - } - }) - }) - - it("returns created stripe payment intent for cart with no customer", async () => { - const cart = carts.frCart - const context = { - cart, - amount: cart.total, - currency_code: cart.region?.currency_code, - } - Object.assign(context, cart) - - context.cart.context.payment_description = 'some description' - - result = await stripeBase.createPayment(context) - expect(result).toEqual({ - session_data: { - id: "pi_lebron", - customer: "cus_lebron", - description: 'some description', - amount: 100, - }, - update_requests: { - customer_metadata: { - stripe_id: "cus_lebron" - } - } - }) - }) - - it("returns created stripe payment intent for cart with no customer and the options default description", async () => { - const localStripeProviderService = new StripeBase( - fakeContainer, - { - api_key: "test", - payment_description: "test options description" - }) - - const cart = carts.frCart - const context = { - cart, - amount: cart.total, - currency_code: cart.region?.currency_code, - } - Object.assign(context, cart) - - context.cart.context.payment_description = null - - result = await localStripeProviderService.createPayment(context) - expect(result).toEqual({ - session_data: { - id: "pi_lebron", - customer: "cus_lebron", - description: "test options description", - amount: 100, - }, - update_requests: { - customer_metadata: { - stripe_id: "cus_lebron" - } - } - }) - }) - }) - - describe("retrievePayment", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.retrievePayment({ - payment_method: { - data: { - id: "pi_lebron", - }, - }, - }) - }) - - it("returns stripe payment intent", () => { - expect(result).toEqual({ - id: "pi_lebron", - customer: "cus_lebron", - }) - }) - }) - - describe("updatePayment", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.updatePayment( - { - id: "pi_lebron", - amount: 800, - }, - { - total: 1000, - } - ) - }) - - it("returns updated stripe payment intent", () => { - expect(result).toEqual({ - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000, - }) - }) - }) - - describe("updatePaymentIntentCustomer", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.updatePaymentIntentCustomer( - "pi_lebron", - "cus_lebron_2" - ) - }) - - it("returns update stripe payment intent", () => { - expect(result).toEqual({ - id: "pi_lebron", - customer: "cus_lebron_2", - amount: 1000, - }) - }) - }) - - describe("capturePayment", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.capturePayment({ - data: { - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000, - }, - }) - }) - - it("returns captured stripe payment intent", () => { - expect(result).toEqual({ - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000, - status: "succeeded", - }) - }) - }) - - describe("refundPayment", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.refundPayment( - { - data: { - id: "re_123", - payment_intent: "pi_lebron", - amount: 1000, - status: "succeeded", - }, - }, - 1000 - ) - }) - - it("returns refunded stripe payment intent", () => { - expect(result).toEqual({ - id: "re_123", - payment_intent: "pi_lebron", - amount: 1000, - status: "succeeded", - }) - }) - }) - - describe("cancelPayment", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.cancelPayment({ - data: { - id: "pi_lebron", - customer: "cus_lebron", - status: "cancelled", - }, - }) - }) - - it("returns cancelled stripe payment intent", () => { - expect(result).toEqual({ - id: "pi_lebron", - customer: "cus_lebron", - status: "cancelled", - }) - }) - }) -}) diff --git a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts index 9b3e95ba0b4f0..e04f2c3a5b633 100644 --- a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts +++ b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts @@ -1,3 +1,4 @@ +import { EOL } from "os" import { StripeTest } from "../__fixtures__/stripe-test" import { PaymentIntentDataByStatus } from "../../__fixtures__/data" import { PaymentSessionStatus } from "@medusajs/medusa" @@ -15,7 +16,16 @@ import { initiatePaymentContextWithExistingCustomer, initiatePaymentContextWithExistingCustomerStripeId, initiatePaymentContextWithFailIntentCreation, - initiatePaymentContextWithWrongEmail + initiatePaymentContextWithWrongEmail, + refundPaymentFailData, + refundPaymentSuccessData, + retrievePaymentFailData, + retrievePaymentSuccessData, + updatePaymentContextFailWithDifferentAmount, + updatePaymentContextWithDifferentAmount, + updatePaymentContextWithExistingCustomer, + updatePaymentContextWithExistingCustomerStripeId, + updatePaymentContextWithWrongEmail, } from "../__fixtures__/data" import { PARTIALLY_FAIL_INTENT_ID, @@ -36,6 +46,10 @@ describe("StripeTest", () => { await stripeTest.init() }) + beforeEach(() => { + jest.clearAllMocks() + }) + it("should return the correct status", async () => { let status: PaymentSessionStatus @@ -75,7 +89,7 @@ describe("StripeTest", () => { expect(status).toBe(PaymentSessionStatus.AUTHORIZED) status = await stripeTest.getPaymentStatus({ - id: "unknown" + id: "unknown-id" }) expect(status).toBe(PaymentSessionStatus.PENDING) }) @@ -90,6 +104,10 @@ describe("StripeTest", () => { await stripeTest.init() }) + beforeEach(() => { + jest.clearAllMocks() + }) + it("should succeed with an existing customer but no stripe id", async () => { const result = await stripeTest.initiatePayment(initiatePaymentContextWithExistingCustomer) @@ -173,10 +191,10 @@ describe("StripeTest", () => { expect(StripeMock.paymentIntents.create).toHaveBeenCalled() expect(StripeMock.paymentIntents.create).toHaveBeenCalledWith( expect.objectContaining({ - description: initiatePaymentContextWithFailIntentCreation.context.description, - amount: initiatePaymentContextWithExistingCustomer.amount, - currency: initiatePaymentContextWithExistingCustomer.currency_code, - metadata: { resource_id: initiatePaymentContextWithExistingCustomer.resource_id }, + description: initiatePaymentContextWithFailIntentCreation.context.payment_description, + amount: initiatePaymentContextWithFailIntentCreation.amount, + currency: initiatePaymentContextWithFailIntentCreation.currency_code, + metadata: { resource_id: initiatePaymentContextWithFailIntentCreation.resource_id }, capture_method: "manual" }) ) @@ -198,6 +216,10 @@ describe("StripeTest", () => { await stripeTest.init() }) + beforeEach(() => { + jest.clearAllMocks() + }) + it("should succeed", async () => { const result = await stripeTest.authorizePayment(authorizePaymentSuccessData) @@ -217,6 +239,10 @@ describe("StripeTest", () => { await stripeTest.init() }) + beforeEach(() => { + jest.clearAllMocks() + }) + it("should succeed", async () => { const result = await stripeTest.cancelPayment(cancelPaymentSuccessData) @@ -254,6 +280,10 @@ describe("StripeTest", () => { await stripeTest.init() }) + beforeEach(() => { + jest.clearAllMocks() + }) + it("should succeed", async () => { const result = await stripeTest.capturePayment(capturePaymentContextSuccessData) @@ -291,6 +321,10 @@ describe("StripeTest", () => { await stripeTest.init() }) + beforeEach(() => { + jest.clearAllMocks() + }) + it("should succeed", async () => { const result = await stripeTest.cancelPayment(deletePaymentSuccessData) @@ -318,4 +352,176 @@ describe("StripeTest", () => { }) }) }) + + describe('refundPayment', function () { + let stripeTest + const refundAmount = 500 + + beforeAll(async () => { + const scopedContainer = { ...container } + stripeTest = new StripeTest(scopedContainer, { api_key: "test" }) + await stripeTest.init() + }) + + beforeEach(() => { + jest.clearAllMocks() + }) + + it("should succeed", async () => { + const result = await stripeTest.refundPayment(refundPaymentSuccessData, refundAmount) + + expect(result).toEqual({ + id: PaymentIntentDataByStatus.SUCCEEDED.id + }) + }) + + it("should fail on refund creation", async () => { + const result = await stripeTest.refundPayment(refundPaymentFailData, refundAmount) + + expect(result).toEqual({ + error: "An error occurred in refundPayment during the refundPayment", + code: undefined, + detail: undefined + }) + }) + }) + + describe('retrievePayment', function () { + let stripeTest + + beforeAll(async () => { + const scopedContainer = { ...container } + stripeTest = new StripeTest(scopedContainer, { api_key: "test" }) + await stripeTest.init() + }) + + beforeEach(() => { + jest.clearAllMocks() + }) + + it("should succeed", async () => { + const result = await stripeTest.retrievePayment(retrievePaymentSuccessData) + + expect(result).toEqual({ + id: PaymentIntentDataByStatus.SUCCEEDED.id, + status: PaymentIntentDataByStatus.SUCCEEDED.status + }) + }) + + it("should fail on refund creation", async () => { + const result = await stripeTest.retrievePayment(retrievePaymentFailData) + + expect(result).toEqual({ + error: "An error occurred in retrievePayment", + code: undefined, + detail: undefined + }) + }) + }) + + describe('updatePayment', function () { + let stripeTest + + beforeAll(async () => { + const scopedContainer = { ...container } + stripeTest = new StripeTest(scopedContainer, { api_key: "test" }) + await stripeTest.init() + }) + + beforeEach(() => { + jest.clearAllMocks() + }) + + it("should succeed to initiate a payment with an existing customer but no stripe id", async () => { + const result = await stripeTest.updatePayment(updatePaymentContextWithExistingCustomer) + + expect(StripeMock.customers.create).toHaveBeenCalled() + expect(StripeMock.customers.create).toHaveBeenCalledWith({ + email: updatePaymentContextWithExistingCustomer.email + }) + + expect(StripeMock.paymentIntents.create).toHaveBeenCalled() + expect(StripeMock.paymentIntents.create).toHaveBeenCalledWith( + expect.objectContaining({ + description: undefined, + amount: updatePaymentContextWithExistingCustomer.amount, + currency: updatePaymentContextWithExistingCustomer.currency_code, + metadata: { resource_id: updatePaymentContextWithExistingCustomer.resource_id }, + capture_method: "manual" + }) + ) + + expect(result).toEqual( + expect.objectContaining({ + session_data: expect.any(Object), + update_requests: { + customer_metadata: { + stripe_id: STRIPE_ID + } + } + }) + ) + }) + + it("should fail to initiate a payment with an existing customer but no stripe id", async () => { + const result = await stripeTest.updatePayment(updatePaymentContextWithWrongEmail) + + expect(StripeMock.customers.create).toHaveBeenCalled() + expect(StripeMock.customers.create).toHaveBeenCalledWith({ + email: updatePaymentContextWithWrongEmail.email + }) + + expect(StripeMock.paymentIntents.create).not.toHaveBeenCalled() + + expect(result).toEqual({ + error: "An error occurred in updatePayment during the initiate of the new payment for the new customer", + code: undefined, + detail: "An error occurred in InitiatePayment during the creation of the stripe customer" + EOL + }) + }) + + it("should succeed but no update occurs when the amount did not changed", async () => { + const result = await stripeTest.updatePayment(updatePaymentContextWithExistingCustomerStripeId) + + expect(StripeMock.paymentIntents.update).not.toHaveBeenCalled() + + expect(result).not.toBeDefined() + }) + + it("should succeed to update the intent with the new amount", async () => { + const result = await stripeTest.updatePayment(updatePaymentContextWithDifferentAmount) + + expect(StripeMock.paymentIntents.update).toHaveBeenCalled() + expect(StripeMock.paymentIntents.update).toHaveBeenCalledWith( + updatePaymentContextWithDifferentAmount.paymentSessionData.id , + { + amount: updatePaymentContextWithDifferentAmount.amount + } + ) + + expect(result).toEqual({ + session_data: expect.objectContaining({ + amount: updatePaymentContextWithDifferentAmount.amount, + }) + }) + }) + + it("should fail to update the intent with the new amount", async () => { + const result = await stripeTest.updatePayment(updatePaymentContextFailWithDifferentAmount) + + expect(StripeMock.paymentIntents.update).toHaveBeenCalled() + expect(StripeMock.paymentIntents.update).toHaveBeenCalledWith( + updatePaymentContextFailWithDifferentAmount.paymentSessionData.id , + { + amount: updatePaymentContextFailWithDifferentAmount.amount + } + ) + + expect(result).toEqual({ + error: "An error occurred in updatePayment during the update of the payment", + code: undefined, + detail: undefined, + }) + }) + }) }) diff --git a/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts b/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts index 44c2c20fb3647..4032f53830c5f 100644 --- a/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts +++ b/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts @@ -1,6 +1,8 @@ import Stripe from "stripe" +import { EOL } from "os" import { AbstractPaymentProcessor, + isPaymentProcessorError, PaymentProcessorContext, PaymentProcessorError, PaymentProcessorSessionResponse, @@ -228,7 +230,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { }) } catch (e) { return this.buildError( - "An error occurred in retrievePayment during the refundPayment", + "An error occurred in refundPayment during the refundPayment", e ) } @@ -257,12 +259,15 @@ abstract class StripeBase extends AbstractPaymentProcessor { const stripeId = customer?.metadata?.stripe_id if (stripeId !== paymentSessionData.customer) { - return await this.initiatePayment(context).catch((e) => { + const result = await this.initiatePayment(context) + if (isPaymentProcessorError(result)) { return this.buildError( "An error occurred in updatePayment during the initiate of the new payment for the new customer", - e + result ) - }) + } + + return result } else { if (amount && paymentSessionData.amount === Math.round(amount)) { return @@ -270,11 +275,13 @@ abstract class StripeBase extends AbstractPaymentProcessor { try { const id = paymentSessionData.id as string - await this.stripe_.paymentIntents.update(id, { + const sessionData = (await this.stripe_.paymentIntents.update(id, { amount: Math.round(amount), - }) + })) as unknown as PaymentProcessorSessionResponse["session_data"] + + return { session_data: sessionData } } catch (e) { - this.buildError( + return this.buildError( "An error occurred in updatePayment during the update of the payment", e ) @@ -299,12 +306,14 @@ abstract class StripeBase extends AbstractPaymentProcessor { protected buildError( message: string, - e: Stripe.StripeRawError + e: Stripe.StripeRawError | PaymentProcessorError ): PaymentProcessorError { return { error: message, code: e.code, - details: e.detail, + detail: isPaymentProcessorError(e) + ? `${e.error}${EOL}${e.detail ?? ""}` + : e.detail, } } } diff --git a/yarn.lock b/yarn.lock index fac4fe58a498a..aa8daa87b2188 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5275,44 +5275,6 @@ __metadata: languageName: unknown linkType: soft -"@medusajs/medusa-cli@npm:^1.3.8": - version: 1.3.8 - resolution: "@medusajs/medusa-cli@npm:1.3.8" - dependencies: - "@babel/polyfill": ^7.8.7 - "@babel/runtime": ^7.9.6 - axios: ^0.21.4 - chalk: ^4.0.0 - configstore: 5.0.1 - core-js: ^3.6.5 - dotenv: ^8.2.0 - execa: ^5.1.1 - fs-exists-cached: ^1.0.0 - fs-extra: ^10.0.0 - hosted-git-info: ^4.0.2 - inquirer: ^8.0.0 - is-valid-path: ^0.1.1 - meant: ^1.0.3 - medusa-core-utils: ^1.1.39 - medusa-telemetry: 0.0.16 - netrc-parser: ^3.1.6 - open: ^8.0.6 - ora: ^5.4.1 - pg-god: ^1.0.12 - prompts: ^2.4.2 - regenerator-runtime: ^0.13.11 - resolve-cwd: ^3.0.0 - stack-trace: ^0.0.10 - ulid: ^2.3.0 - url: ^0.11.0 - winston: ^3.8.2 - yargs: ^15.3.1 - bin: - medusa: cli.js - checksum: 8d18ac9b20bbfbb8fdcfc23293169744ef77339f6a4c063e0838466b871a105109baccc60def36a75f03544bd653727e9feed113c7799105512cacdbf443e990 - languageName: node - linkType: hard - "@medusajs/medusa-js@^1.3.8, @medusajs/medusa-js@workspace:packages/medusa-js": version: 0.0.0-use.local resolution: "@medusajs/medusa-js@workspace:packages/medusa-js" @@ -25432,7 +25394,7 @@ __metadata: languageName: node linkType: hard -"medusa-core-utils@^1.1.31, medusa-core-utils@^1.1.39, medusa-core-utils@workspace:packages/medusa-core-utils": +"medusa-core-utils@^1.1.31, medusa-core-utils@^1.1.38, medusa-core-utils@^1.1.39, medusa-core-utils@workspace:packages/medusa-core-utils": version: 0.0.0-use.local resolution: "medusa-core-utils@workspace:packages/medusa-core-utils" dependencies: @@ -25447,16 +25409,6 @@ __metadata: languageName: unknown linkType: soft -"medusa-core-utils@npm:^1.1.39": - version: 1.1.39 - resolution: "medusa-core-utils@npm:1.1.39" - dependencies: - joi: ^17.3.0 - joi-objectid: ^3.0.1 - checksum: 203885dbe3cbe0f1cc0218ae65a3e9267a3bbc5f1441e38bed980c19b4e5ec047692751b3cb00f988377715a5e764967dbd38da7fd80ea8de12cb05f70fdf0f8 - languageName: node - linkType: hard - "medusa-dev-cli@workspace:packages/medusa-dev-cli": version: 0.0.0-use.local resolution: "medusa-dev-cli@workspace:packages/medusa-dev-cli" @@ -25754,6 +25706,23 @@ __metadata: languageName: unknown linkType: soft +"medusa-payment-stripe-processor@workspace:packages/medusa-payment-stripe-processor": + version: 0.0.0-use.local + resolution: "medusa-payment-stripe-processor@workspace:packages/medusa-payment-stripe-processor" + dependencies: + "@medusajs/medusa": ^1.7.7 + "@types/stripe": ^8.0.417 + body-parser: ^1.19.0 + cross-env: ^5.2.1 + express: ^4.17.1 + jest: ^25.5.4 + medusa-core-utils: ^1.1.38 + stripe: ^11.10.0 + peerDependencies: + "@medusajs/medusa": ^1.7.7 + languageName: unknown + linkType: soft + "medusa-payment-stripe@workspace:packages/medusa-payment-stripe": version: 0.0.0-use.local resolution: "medusa-payment-stripe@workspace:packages/medusa-payment-stripe" From 7a8dc0c6b84358354e994e55f516a22bf1ba7be2 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Mon, 20 Feb 2023 12:52:19 +0100 Subject: [PATCH 13/36] cleanup jest config --- .../medusa-payment-stripe-processor/jest.config.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/medusa-payment-stripe-processor/jest.config.js b/packages/medusa-payment-stripe-processor/jest.config.js index 7ed3e9a0975d1..e564d67c7053e 100644 --- a/packages/medusa-payment-stripe-processor/jest.config.js +++ b/packages/medusa-payment-stripe-processor/jest.config.js @@ -1,14 +1,4 @@ module.exports = { - //moduleNameMapper: { - // "^highlight.js$": `/node_modules/highlight.js/lib/index.js`, - //}, - //snapshotSerializers: [`jest-serializer-path`], - // collectCoverageFrom: coverageDirs, - //reporters: process.env.CI - // ? [[`jest-silent-reporter`, { useDots: true }]].concat( - // useCoverage ? `jest-junit` : [] - // ) - // : [`default`].concat(useCoverage ? `jest-junit` : []), globals: { "ts-jest": { tsconfig: "tsconfig.spec.json", From e80c444131ad75bf73cc899ec44f2c80dd4c82b6 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Mon, 20 Feb 2023 14:57:24 +0100 Subject: [PATCH 14/36] stripe webhook --- .../src/api/hooks/index.ts | 18 ++ .../src/api/hooks/stripe.ts | 165 ++++++++++++++++++ .../src/api/index.ts | 10 ++ .../src/api/utils/utils.ts | 44 +++++ .../medusa/src/strategies/cart-completion.ts | 9 +- 5 files changed, 243 insertions(+), 3 deletions(-) create mode 100644 packages/medusa-payment-stripe-processor/src/api/hooks/index.ts create mode 100644 packages/medusa-payment-stripe-processor/src/api/hooks/stripe.ts create mode 100644 packages/medusa-payment-stripe-processor/src/api/index.ts create mode 100644 packages/medusa-payment-stripe-processor/src/api/utils/utils.ts diff --git a/packages/medusa-payment-stripe-processor/src/api/hooks/index.ts b/packages/medusa-payment-stripe-processor/src/api/hooks/index.ts new file mode 100644 index 0000000000000..f938080bdbe7e --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/api/hooks/index.ts @@ -0,0 +1,18 @@ +import stripeHooks from "./stripe" +import { Router } from "express" +import bodyParser from "body-parser" +import middlewares from "@medusajs/medusa/dist/api/middlewares" + +const route = Router() + +export default (app) => { + app.use("/stripe", route) + + route.post( + "/hooks", + // stripe constructEvent fails without body-parser + bodyParser.raw({ type: "application/json" }), + middlewares.wrap(stripeHooks) + ) + return app +} diff --git a/packages/medusa-payment-stripe-processor/src/api/hooks/stripe.ts b/packages/medusa-payment-stripe-processor/src/api/hooks/stripe.ts new file mode 100644 index 0000000000000..7abb1087405d7 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/api/hooks/stripe.ts @@ -0,0 +1,165 @@ +import { Request, Response } from "express" +import { + buildHandleCartPaymentErrorMessage, + constructWebhook, + isPaymentCollection, +} from "../utils/utils" +import { + AbstractCartCompletionStrategy, + CartService, + IdempotencyKeyService, +} from "@medusajs/medusa" +import { MedusaError } from "medusa-core-utils" + +export const RETRY_STATUS_CODE = 409 + +export default async (req: Request, res: Response) => { + let event + try { + event = constructWebhook({ + signature: req.headers["stripe-signature"], + body: req.body, + container: req.scope, + }) + } catch (err) { + res.status(400).send(`Webhook Error: ${err.message}`) + return + } + + const paymentIntent = event.data.object + const cartId = paymentIntent.metadata.cart_id // Backward compatibility + const resourceId = paymentIntent.metadata.resource_id + + if (isPaymentCollection(resourceId)) { + await handlePaymentCollection(event, req, res, resourceId, paymentIntent.id) + } else { + await handleCartPayments(event, req, res, cartId ?? resourceId) + } +} + +async function handleCartPayments(event, req, res, cartId) { + const manager = req.scope.resolve("manager") + const orderService = req.scope.resolve("orderService") + const logger = req.scope.resolve("logger") + + const order = await orderService + .retrieveByCartId(cartId) + .catch(() => undefined) + + // handle payment intent events + switch (event.type) { + case "payment_intent.succeeded": + if (order) { + // If order is created but not captured, we attempt to do so + if (order.payment_status !== "captured") { + await manager.transaction(async (manager) => { + await orderService.withTransaction(manager).capturePayment(order.id) + }) + } else { + // Otherwise, respond with 200 preventing Stripe from retrying + return res.sendStatus(200) + } + } else { + // If order is not created, we respond with 404 to trigger Stripe retry mechanism + return res.sendStatus(404) + } + break + case "payment_intent.amount_capturable_updated": + try { + await manager.transaction(async (manager) => { + await paymentIntentAmountCapturableEventHandler({ + order, + cartId, + container: req.scope, + transactionManager: manager, + }) + }) + } catch (err) { + const message = buildHandleCartPaymentErrorMessage(event, err) + logger.warn(message) + return res.sendStatus(RETRY_STATUS_CODE) + } + break + default: + res.sendStatus(204) + return + } + + res.sendStatus(200) +} + +async function handlePaymentCollection(event, req, res, id, paymentIntentId) { + const manager = req.scope.resolve("manager") + const paymentCollectionService = req.scope.resolve("paymentCollectionService") + + const paycol = await paymentCollectionService + .retrieve(id, { relations: ["payments"] }) + .catch(() => undefined) + + if (paycol?.payments?.length) { + if (event.type === "payment_intent.succeeded") { + const payment = paycol.payments.find( + (pay) => pay.data.id === paymentIntentId + ) + if (payment && !payment.captured_at) { + await manager.transaction(async (manager) => { + await paymentCollectionService + .withTransaction(manager) + .capture(payment.id) + }) + } + + res.sendStatus(200) + return + } + } + res.sendStatus(204) +} + +async function paymentIntentAmountCapturableEventHandler({ + order, + cartId, + container, + transactionManager, +}) { + if (!order) { + const completionStrat: AbstractCartCompletionStrategy = container.resolve( + "cartCompletionStrategy" + ) + const cartService: CartService = container.resolve("cartService") + const idempotencyKeyService: IdempotencyKeyService = container.resolve( + "idempotencyKeyService" + ) + + let idempotencyKey + try { + idempotencyKey = await idempotencyKeyService + .withTransaction(transactionManager) + .initializeRequest("", "post", { cart_id: cartId }, "/stripe/hooks") + } catch (error) { + throw new MedusaError( + MedusaError.Types.UNEXPECTED_STATE, + "Failed to create idempotency key", + "409" + ) + } + + const cart = await cartService + .withTransaction(transactionManager) + .retrieve(cartId, { select: ["context"] }) + + const { response_code, response_body } = await completionStrat.complete( + cartId, + idempotencyKey, + { ip: cart.context?.ip as string } + ) + + if (response_code !== 200) { + throw new MedusaError( + MedusaError.Types.UNEXPECTED_STATE, + response_body["message"], + response_body["code"].toString() + ) + } + } +} diff --git a/packages/medusa-payment-stripe-processor/src/api/index.ts b/packages/medusa-payment-stripe-processor/src/api/index.ts new file mode 100644 index 0000000000000..d704d468d5fdd --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/api/index.ts @@ -0,0 +1,10 @@ +import { Router } from "express" +import hooks from "./hooks" + +export default (container) => { + const app = Router() + + hooks(app) + + return app +} diff --git a/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts b/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts new file mode 100644 index 0000000000000..49264eeb53688 --- /dev/null +++ b/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts @@ -0,0 +1,44 @@ +import { AwilixContainer } from "awilix" +import Stripe from "stripe" +import { PostgresError } from "@medusajs/medusa" +import { RETRY_STATUS_CODE } from "../hooks/stripe" + +const PAYMENT_PROVIDER_KEY = "pp_stripe" + +export function constructWebhook({ + signature, + body, + container, +}: { + signature: string | string[] | undefined + body: any + container: AwilixContainer +}): Stripe.Event { + const stripeProviderService = container.resolve(PAYMENT_PROVIDER_KEY) + return stripeProviderService.constructWebhookEvent(body, signature) +} + +export function isPaymentCollection(id) { + return id && id.startsWith("paycol") +} + +export function buildHandleCartPaymentErrorMessage( + event: string, + err: Stripe.errors.StripeError +): string { + let message = `Stripe webhook ${event} handling failed\n${ + err?.detail ?? err?.message + }` + if (err?.code === PostgresError.SERIALIZATION_FAILURE) { + message = `Stripe webhook ${event} handle failed. This can happen when this webhook is triggered during a cart completion and can be ignored. This event should be retried automatically.\n${ + err?.detail ?? err?.message + }` + } + if (err?.code === RETRY_STATUS_CODE.toString()) { + message = `Stripe webhook ${event} handle failed.\n${ + err?.detail ?? err?.message + }` + } + + return message +} diff --git a/packages/medusa/src/strategies/cart-completion.ts b/packages/medusa/src/strategies/cart-completion.ts index fd9173c282b5f..e1d592ac9e1d8 100644 --- a/packages/medusa/src/strategies/cart-completion.ts +++ b/packages/medusa/src/strategies/cart-completion.ts @@ -264,16 +264,19 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy { const cartServiceTx = this.cartService_.withTransaction(manager) const cart = await cartServiceTx.retrieveWithTotals(id, { - relations: ["region", "payment", "payment_sessions", "items.variant.product",], + relations: [ + "region", + "payment", + "payment_sessions", + "items.variant.product", + ], }) let allowBackorder = false - let swapId: string if (cart.type === "swap") { const swap = await swapServiceTx.retrieveByCartId(id) allowBackorder = swap.allow_backorder - swapId = swap.id } if (!allowBackorder) { From 5307b8adfdb70579d4aa5e9778cb8678729eb6d6 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Mon, 20 Feb 2023 15:10:12 +0100 Subject: [PATCH 15/36] fix type issues --- packages/medusa-payment-stripe-processor/src/api/utils/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts b/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts index 49264eeb53688..f886397e6bb36 100644 --- a/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts +++ b/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts @@ -24,7 +24,7 @@ export function isPaymentCollection(id) { export function buildHandleCartPaymentErrorMessage( event: string, - err: Stripe.errors.StripeError + err: Stripe.StripeRawError ): string { let message = `Stripe webhook ${event} handling failed\n${ err?.detail ?? err?.message From dd7d603b059b4cb8becdaca3a35431ed00e35f8e Mon Sep 17 00:00:00 2001 From: adrien2p Date: Tue, 21 Feb 2023 10:40:23 +0100 Subject: [PATCH 16/36] WIP --- packages/medusa/src/loaders/plugins.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/medusa/src/loaders/plugins.ts b/packages/medusa/src/loaders/plugins.ts index c178189901936..f3686ae30f40c 100644 --- a/packages/medusa/src/loaders/plugins.ts +++ b/packages/medusa/src/loaders/plugins.ts @@ -627,8 +627,17 @@ function resolvePlugin(pluginName: string): { ) // warnOnIncompatiblePeerDependency(packageJSON.name, packageJSON) + const resolvedPathToDist = path.dirname( + requireSource.resolve(`${pluginName}/dist`) + ) + const computedResolvedPath = + resolvedPath + (process.env.DEV_MODE ? "/src" : "") + + // Allow a plugin to choose to output the build to dist, only if not in dev mode + const isDistExist = !process.env.DEV_MODE && existsSync(resolvedPathToDist) + return { - resolve: resolvedPath + (process.env.DEV_MODE ? "/src" : ""), + resolve: isDistExist ? resolvedPathToDist : computedResolvedPath, id: createPluginId(packageJSON.name), name: packageJSON.name, options: {}, From 91fbea6465a43067a40ae3693523d91c5934a257 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 22 Feb 2023 15:58:34 +0100 Subject: [PATCH 17/36] Continue testing --- .../src/api/hooks/stripe.ts | 4 +-- .../src/core/stripe-base.ts | 24 +++++++++------ .../src/interfaces/payment-processor.ts | 7 ----- packages/medusa/src/loaders/defaults.ts | 9 ++---- .../medusa/src/loaders/helpers/plugins.ts | 20 +++++++++---- packages/medusa/src/loaders/plugins.ts | 30 ++++++++----------- .../medusa/src/services/payment-provider.ts | 23 +++++++------- 7 files changed, 58 insertions(+), 59 deletions(-) diff --git a/packages/medusa-payment-stripe-processor/src/api/hooks/stripe.ts b/packages/medusa-payment-stripe-processor/src/api/hooks/stripe.ts index 7abb1087405d7..84571144bd835 100644 --- a/packages/medusa-payment-stripe-processor/src/api/hooks/stripe.ts +++ b/packages/medusa-payment-stripe-processor/src/api/hooks/stripe.ts @@ -11,8 +11,6 @@ import { } from "@medusajs/medusa" import { MedusaError } from "medusa-core-utils" -export const RETRY_STATUS_CODE = 409 - export default async (req: Request, res: Response) => { let event try { @@ -77,7 +75,7 @@ async function handleCartPayments(event, req, res, cartId) { } catch (err) { const message = buildHandleCartPaymentErrorMessage(event, err) logger.warn(message) - return res.sendStatus(RETRY_STATUS_CODE) + return res.sendStatus(409) } break default: diff --git a/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts b/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts index 4032f53830c5f..017845d657d0e 100644 --- a/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts +++ b/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts @@ -16,21 +16,25 @@ import { } from "../types" abstract class StripeBase extends AbstractPaymentProcessor { - static identifier = "" + static identifier = "stripe" protected readonly options_: StripeOptions - private stripe_: Stripe + protected stripe_: Stripe protected constructor(_, options) { super(_, options) this.options_ = options + + this.init() } - async init(): Promise { - this.stripe_ = new Stripe(this.options_.api_key, { - apiVersion: "2022-11-15", - }) + init(): void { + this.stripe_ = + this.stripe_ || + new Stripe(this.options_.api_key, { + apiVersion: "2022-11-15", + }) } abstract get paymentIntentOptions(): PaymentIntentOptions @@ -306,14 +310,16 @@ abstract class StripeBase extends AbstractPaymentProcessor { protected buildError( message: string, - e: Stripe.StripeRawError | PaymentProcessorError + e: Stripe.StripeRawError | PaymentProcessorError | Error ): PaymentProcessorError { return { error: message, - code: e.code, + code: "code" in e ? e.code : "", detail: isPaymentProcessorError(e) ? `${e.error}${EOL}${e.detail ?? ""}` - : e.detail, + : "detail" in e + ? e.detail + : e.message ?? "", } } } diff --git a/packages/medusa/src/interfaces/payment-processor.ts b/packages/medusa/src/interfaces/payment-processor.ts index 7d69c16f74496..96982d44deee5 100644 --- a/packages/medusa/src/interfaces/payment-processor.ts +++ b/packages/medusa/src/interfaces/payment-processor.ts @@ -33,11 +33,6 @@ export interface PaymentProcessor { */ getIdentifier(): string - /** - * Used to initialise anything like an SDK or similar - */ - init(): Promise - /** * Initiate a payment session with the external provider */ @@ -147,8 +142,6 @@ export abstract class AbstractPaymentProcessor implements PaymentProcessor { return ctr.identifier } - abstract init(): Promise - abstract capturePayment( paymentSessionData: Record ): Promise< diff --git a/packages/medusa/src/loaders/defaults.ts b/packages/medusa/src/loaders/defaults.ts index 805ebc291d6fe..31ae411a1adc7 100644 --- a/packages/medusa/src/loaders/defaults.ts +++ b/packages/medusa/src/loaders/defaults.ts @@ -205,12 +205,9 @@ async function registerPaymentProcessor({ ).filter((provider) => provider instanceof AbstractPaymentProcessor) const payIds: string[] = [] - await Promise.all( - payProviders.map((paymentProvider) => { - payIds.push(paymentProvider.getIdentifier()) - return paymentProvider.init() - }) - ) + payProviders.map((paymentProvider) => { + payIds.push(paymentProvider.getIdentifier()) + }) const pProviderService = container.resolve( "paymentProviderService" diff --git a/packages/medusa/src/loaders/helpers/plugins.ts b/packages/medusa/src/loaders/helpers/plugins.ts index 539b1d412faf2..69a57bf09e45c 100644 --- a/packages/medusa/src/loaders/helpers/plugins.ts +++ b/packages/medusa/src/loaders/helpers/plugins.ts @@ -5,7 +5,7 @@ import { isPaymentProcessor, isPaymentService, } from "../../interfaces" -import { aliasTo, asFunction } from "awilix" +import { aliasTo, asFunction, Lifetime } from "awilix" type Context = { container: MedusaContainer @@ -25,12 +25,17 @@ export function registerPaymentServiceFromClass( container.registerAdd( "paymentProviders", - asFunction((cradle) => new klass(cradle, pluginDetails.options)) + asFunction((cradle) => new klass(cradle, pluginDetails.options), { + lifetime: Lifetime.SINGLETON, + }) ) container.register({ [registrationName]: asFunction( - (cradle) => new klass(cradle, pluginDetails.options) + (cradle) => new klass(cradle, pluginDetails.options), + { + lifetime: Lifetime.SINGLETON, + } ), [`pp_${(klass as unknown as typeof AbstractPaymentService).identifier}`]: aliasTo(registrationName), @@ -49,12 +54,17 @@ export function registerPaymentProcessorFromClass( container.registerAdd( "paymentProviders", - asFunction((cradle) => new klass(cradle, pluginDetails.options)) + asFunction((cradle) => new klass(cradle, pluginDetails.options), { + lifetime: Lifetime.SINGLETON, + }) ) container.register({ [registrationName]: asFunction( - (cradle) => new klass(cradle, pluginDetails.options) + (cradle) => new klass(cradle, pluginDetails.options), + { + lifetime: Lifetime.SINGLETON, + } ), [`pp_${(klass as unknown as typeof AbstractPaymentProcessor).identifier}`]: aliasTo(registrationName), diff --git a/packages/medusa/src/loaders/plugins.ts b/packages/medusa/src/loaders/plugins.ts index f3686ae30f40c..4511571b5aa03 100644 --- a/packages/medusa/src/loaders/plugins.ts +++ b/packages/medusa/src/loaders/plugins.ts @@ -6,7 +6,6 @@ import glob from "glob" import _ from "lodash" import { createRequireFromPath } from "medusa-core-utils" import { - BaseService as LegacyBaseService, FileService, FulfillmentService, OauthService, @@ -23,7 +22,6 @@ import { isPriceSelectionStrategy, isSearchService, isTaxCalculationStrategy, - TransactionBaseService as BaseService, } from "../interfaces" import { MiddlewareService } from "../services" import { @@ -364,16 +362,6 @@ export async function registerServices( const loaded = require(fn).default const name = formatRegistrationName(fn) - if ( - !(loaded.prototype instanceof LegacyBaseService) && - !(loaded.prototype instanceof BaseService) - ) { - const logger = container.resolve("logger") - const message = `The class must be a valid service implementation, please check ${fn}` - logger.error(message) - throw new Error(message) - } - const context = { container, pluginDetails, registrationName: name } registerPaymentServiceFromClass(loaded, context) @@ -627,14 +615,22 @@ function resolvePlugin(pluginName: string): { ) // warnOnIncompatiblePeerDependency(packageJSON.name, packageJSON) - const resolvedPathToDist = path.dirname( - requireSource.resolve(`${pluginName}/dist`) - ) const computedResolvedPath = resolvedPath + (process.env.DEV_MODE ? "/src" : "") - // Allow a plugin to choose to output the build to dist, only if not in dev mode - const isDistExist = !process.env.DEV_MODE && existsSync(resolvedPathToDist) + let resolvedPathToDist = "" + let isDistExist = false + + try { + resolvedPathToDist = resolvedPath + "/dist" + // Allow a plugin to choose to output the build to dist, only if not in dev mode + isDistExist = + resolvedPathToDist && + !process.env.DEV_MODE && + existsSync(resolvedPath + "/dist") + } catch (e) { + // noop + } return { resolve: isDistExist ? resolvedPathToDist : computedResolvedPath, diff --git a/packages/medusa/src/services/payment-provider.ts b/packages/medusa/src/services/payment-provider.ts index 9ac7843e78af3..d50c6b00a1164 100644 --- a/packages/medusa/src/services/payment-provider.ts +++ b/packages/medusa/src/services/payment-provider.ts @@ -356,17 +356,16 @@ export default class PaymentProviderService extends TransactionBaseService { let paymentResponse if (provider instanceof AbstractPaymentProcessor) { - paymentResponse = - (await provider.updatePayment({ - amount: context.amount, - context: context.context, - currency_code: context.currency_code, - customer: context.customer, - email: context.email, - billing_address: context.billing_address, - resource_id: context.resource_id, - paymentSessionData: paymentSession.data, - })) ?? {} + paymentResponse = await provider.updatePayment({ + amount: context.amount, + context: context.context, + currency_code: context.currency_code, + customer: context.customer, + email: context.email, + billing_address: context.billing_address, + resource_id: context.resource_id, + paymentSessionData: paymentSession.data, + }) if (paymentResponse && "error" in paymentResponse) { this.throwFromPaymentProcessorError(paymentResponse) @@ -377,7 +376,7 @@ export default class PaymentProviderService extends TransactionBaseService { .updatePayment(paymentSession.data, context) } - const sessionData = paymentResponse.session_data ?? paymentResponse + const sessionData = paymentResponse?.session_data ?? paymentResponse // If no update occurs, return the original session if (!sessionData) { From 0bbc46a1fe38f0a1a4f94d580adbc6827d2394f8 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Wed, 22 Feb 2023 16:20:36 +0100 Subject: [PATCH 18/36] fix util --- .../medusa-payment-stripe-processor/src/api/utils/utils.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts b/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts index f886397e6bb36..c60ef01d767f6 100644 --- a/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts +++ b/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts @@ -1,7 +1,6 @@ import { AwilixContainer } from "awilix" import Stripe from "stripe" import { PostgresError } from "@medusajs/medusa" -import { RETRY_STATUS_CODE } from "../hooks/stripe" const PAYMENT_PROVIDER_KEY = "pp_stripe" @@ -34,7 +33,7 @@ export function buildHandleCartPaymentErrorMessage( err?.detail ?? err?.message }` } - if (err?.code === RETRY_STATUS_CODE.toString()) { + if (err?.code === "409") { message = `Stripe webhook ${event} handle failed.\n${ err?.detail ?? err?.message }` From d6409fe010e7bf64d78f3f30466e4a812bc656ea Mon Sep 17 00:00:00 2001 From: adrien2p Date: Thu, 23 Feb 2023 12:18:53 +0100 Subject: [PATCH 19/36] fix tests + remove default life time --- .../src/core/__tests__/stripe-base.spec.ts | 36 +++++++++---------- .../medusa/src/loaders/helpers/plugins.ts | 10 ++---- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts index e04f2c3a5b633..d13cccdf4b53b 100644 --- a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts +++ b/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts @@ -175,8 +175,8 @@ describe("StripeTest", () => { expect(result).toEqual({ error: "An error occurred in InitiatePayment during the creation of the stripe customer", - code: undefined, - detail: undefined + code: "", + detail: "Error" }) }) @@ -201,8 +201,8 @@ describe("StripeTest", () => { expect(result).toEqual({ error: "An error occurred in InitiatePayment during the creation of the stripe payment intent", - code: undefined, - detail: undefined + code: "", + detail: "Error" }) }) }) @@ -265,8 +265,8 @@ describe("StripeTest", () => { expect(result).toEqual({ error: "An error occurred in cancelPayment during the cancellation of the payment", - code: undefined, - detail: undefined + code: "", + detail: "Error" }) }) }) @@ -306,8 +306,8 @@ describe("StripeTest", () => { expect(result).toEqual({ error: "An error occurred in deletePayment during the capture of the payment", - code: undefined, - detail: undefined + code: "", + detail: "Error" }) }) }) @@ -347,8 +347,8 @@ describe("StripeTest", () => { expect(result).toEqual({ error: "An error occurred in cancelPayment during the cancellation of the payment", - code: undefined, - detail: undefined + code: "", + detail: "Error" }) }) }) @@ -380,8 +380,8 @@ describe("StripeTest", () => { expect(result).toEqual({ error: "An error occurred in refundPayment during the refundPayment", - code: undefined, - detail: undefined + code: "", + detail: "Error" }) }) }) @@ -413,8 +413,8 @@ describe("StripeTest", () => { expect(result).toEqual({ error: "An error occurred in retrievePayment", - code: undefined, - detail: undefined + code: "", + detail: "Error" }) }) }) @@ -475,8 +475,8 @@ describe("StripeTest", () => { expect(result).toEqual({ error: "An error occurred in updatePayment during the initiate of the new payment for the new customer", - code: undefined, - detail: "An error occurred in InitiatePayment during the creation of the stripe customer" + EOL + code: "", + detail: "An error occurred in InitiatePayment during the creation of the stripe customer" + EOL + "Error" }) }) @@ -519,8 +519,8 @@ describe("StripeTest", () => { expect(result).toEqual({ error: "An error occurred in updatePayment during the update of the payment", - code: undefined, - detail: undefined, + code: "", + detail: "Error" }) }) }) diff --git a/packages/medusa/src/loaders/helpers/plugins.ts b/packages/medusa/src/loaders/helpers/plugins.ts index 69a57bf09e45c..6f13a8a28c3b0 100644 --- a/packages/medusa/src/loaders/helpers/plugins.ts +++ b/packages/medusa/src/loaders/helpers/plugins.ts @@ -32,10 +32,7 @@ export function registerPaymentServiceFromClass( container.register({ [registrationName]: asFunction( - (cradle) => new klass(cradle, pluginDetails.options), - { - lifetime: Lifetime.SINGLETON, - } + (cradle) => new klass(cradle, pluginDetails.options) ), [`pp_${(klass as unknown as typeof AbstractPaymentService).identifier}`]: aliasTo(registrationName), @@ -61,10 +58,7 @@ export function registerPaymentProcessorFromClass( container.register({ [registrationName]: asFunction( - (cradle) => new klass(cradle, pluginDetails.options), - { - lifetime: Lifetime.SINGLETON, - } + (cradle) => new klass(cradle, pluginDetails.options) ), [`pp_${(klass as unknown as typeof AbstractPaymentProcessor).identifier}`]: aliasTo(registrationName), From c25c25eadbab2cc3516bbb2fccbc52a3f40cc3ac Mon Sep 17 00:00:00 2001 From: adrien2p Date: Thu, 23 Feb 2023 12:31:12 +0100 Subject: [PATCH 20/36] refactor --- .../.gitignore | 4 - .../package.json | 45 --- packages/medusa-payment-stripe/.babelrc | 14 - packages/medusa-payment-stripe/.gitignore | 16 +- packages/medusa-payment-stripe/.npmignore | 8 - packages/medusa-payment-stripe/README.md | 4 + packages/medusa-payment-stripe/index.js | 1 - .../jest.config.js | 0 packages/medusa-payment-stripe/package.json | 39 +-- .../src/__fixtures__/data.ts | 0 .../src/__mocks__/cart.js | 216 ------------- .../src/__mocks__/customer.js | 39 --- .../src/__mocks__/eventbus.js | 10 - .../src/__mocks__/stripe.js | 87 ----- .../src/__mocks__/stripe.ts | 0 .../src/__mocks__/totals.js | 12 - .../src/api/hooks/index.ts | 0 .../src/api/hooks/stripe.ts | 0 .../medusa-payment-stripe/src/api/index.js | 10 - .../src/api/index.ts | 0 .../src/api/middlewares/await-middleware.js | 3 - .../src/api/middlewares/index.js | 5 - .../src/api/routes/hooks/index.js | 17 - .../src/api/routes/hooks/stripe.js | 136 -------- .../src/api/utils/utils.ts | 0 .../src/core/__fixtures__/data.ts | 0 .../src/core/__fixtures__/stripe-test.ts | 0 .../src/core/__tests__/stripe-base.spec.ts | 0 .../src/core/stripe-base.ts | 0 .../src/helpers/__tests__/stripe-base.js | 284 ---------------- .../src/helpers/stripe-base.js | 305 ------------------ .../src/index.ts | 0 .../src/services/stripe-bancontact.js | 18 -- .../src/services/stripe-bancontact.ts | 0 .../src/services/stripe-blik.js | 18 -- .../src/services/stripe-blik.ts | 0 .../src/services/stripe-giropay.js | 18 -- .../src/services/stripe-giropay.ts | 0 .../src/services/stripe-ideal.js | 18 -- .../src/services/stripe-ideal.ts | 0 .../src/services/stripe-provider.js | 15 - .../src/services/stripe-provider.ts | 0 .../src/services/stripe-przelewy24.js | 18 -- .../src/services/stripe-przelewy24.ts | 0 .../src/types.ts | 0 .../tsconfig.json | 0 .../tsconfig.spec.json | 0 yarn.lock | 33 +- 48 files changed, 22 insertions(+), 1371 deletions(-) delete mode 100644 packages/medusa-payment-stripe-processor/.gitignore delete mode 100644 packages/medusa-payment-stripe-processor/package.json delete mode 100644 packages/medusa-payment-stripe/.babelrc delete mode 100644 packages/medusa-payment-stripe/.npmignore delete mode 100644 packages/medusa-payment-stripe/index.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/jest.config.js (100%) rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/__fixtures__/data.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/__mocks__/cart.js delete mode 100644 packages/medusa-payment-stripe/src/__mocks__/customer.js delete mode 100644 packages/medusa-payment-stripe/src/__mocks__/eventbus.js delete mode 100644 packages/medusa-payment-stripe/src/__mocks__/stripe.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/__mocks__/stripe.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/__mocks__/totals.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/api/hooks/index.ts (100%) rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/api/hooks/stripe.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/api/index.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/api/index.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/api/middlewares/await-middleware.js delete mode 100644 packages/medusa-payment-stripe/src/api/middlewares/index.js delete mode 100644 packages/medusa-payment-stripe/src/api/routes/hooks/index.js delete mode 100644 packages/medusa-payment-stripe/src/api/routes/hooks/stripe.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/api/utils/utils.ts (100%) rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/core/__fixtures__/data.ts (100%) rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/core/__fixtures__/stripe-test.ts (100%) rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/core/__tests__/stripe-base.spec.ts (100%) rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/core/stripe-base.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/helpers/__tests__/stripe-base.js delete mode 100644 packages/medusa-payment-stripe/src/helpers/stripe-base.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/index.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/services/stripe-bancontact.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/services/stripe-bancontact.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/services/stripe-blik.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/services/stripe-blik.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/services/stripe-giropay.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/services/stripe-giropay.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/services/stripe-ideal.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/services/stripe-ideal.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/services/stripe-provider.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/services/stripe-provider.ts (100%) delete mode 100644 packages/medusa-payment-stripe/src/services/stripe-przelewy24.js rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/services/stripe-przelewy24.ts (100%) rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/src/types.ts (100%) rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/tsconfig.json (100%) rename packages/{medusa-payment-stripe-processor => medusa-payment-stripe}/tsconfig.spec.json (100%) diff --git a/packages/medusa-payment-stripe-processor/.gitignore b/packages/medusa-payment-stripe-processor/.gitignore deleted file mode 100644 index 384d378f948ba..0000000000000 --- a/packages/medusa-payment-stripe-processor/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -dist -node_modules -.DS_store -yarn.lock \ No newline at end of file diff --git a/packages/medusa-payment-stripe-processor/package.json b/packages/medusa-payment-stripe-processor/package.json deleted file mode 100644 index d29cbf831bb66..0000000000000 --- a/packages/medusa-payment-stripe-processor/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "medusa-payment-stripe-processor", - "version": "0.0.1", - "description": "Stripe Payment provider for Medusa Commerce", - "main": "dist/index.js", - "keywords": [ - "medusa-plugin", - "medusa-plugin-payment" - ], - "repository": { - "type": "git", - "url": "https://github.com/medusajs/medusa", - "directory": "packages/medusa-payment-stripe-processor" - }, - "publishConfig": { - "access": "public" - }, - "files": [ - "dist" - ], - "author": "Medusa", - "license": "MIT", - "scripts": { - "prepare": "cross-env NODE_ENV=production yarn run build", - "test": "jest --passWithNoTests src", - "build": "tsc", - "watch": "tsc --watch" - }, - "devDependencies": { - "@medusajs/medusa": "^1.7.7", - "@types/stripe": "^8.0.417", - "cross-env": "^5.2.1", - "jest": "^25.5.4" - }, - "peerDependencies": { - "@medusajs/medusa": "^1.7.7" - }, - "dependencies": { - "body-parser": "^1.19.0", - "express": "^4.17.1", - "medusa-core-utils": "^1.1.38", - "stripe": "^11.10.0" - }, - "gitHead": "cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e" -} diff --git a/packages/medusa-payment-stripe/.babelrc b/packages/medusa-payment-stripe/.babelrc deleted file mode 100644 index 75cbf1558b1b6..0000000000000 --- a/packages/medusa-payment-stripe/.babelrc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "plugins": [ - "@babel/plugin-proposal-optional-chaining", - "@babel/plugin-proposal-class-properties", - "@babel/plugin-transform-instanceof", - "@babel/plugin-transform-classes" - ], - "presets": ["@babel/preset-env"], - "env": { - "test": { - "plugins": ["@babel/plugin-transform-runtime"] - } - } -} diff --git a/packages/medusa-payment-stripe/.gitignore b/packages/medusa-payment-stripe/.gitignore index f04d2490fe215..384d378f948ba 100644 --- a/packages/medusa-payment-stripe/.gitignore +++ b/packages/medusa-payment-stripe/.gitignore @@ -1,16 +1,4 @@ -/lib +dist node_modules .DS_store -.env* -/*.js -!index.js -yarn.lock - -/dist - -/api -/services -/models -/subscribers -/helpers -/__mocks__ \ No newline at end of file +yarn.lock \ No newline at end of file diff --git a/packages/medusa-payment-stripe/.npmignore b/packages/medusa-payment-stripe/.npmignore deleted file mode 100644 index af4cbd1ba0b84..0000000000000 --- a/packages/medusa-payment-stripe/.npmignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_store -src -dist -yarn.lock -.babelrc - -.turbo -.yarn \ No newline at end of file diff --git a/packages/medusa-payment-stripe/README.md b/packages/medusa-payment-stripe/README.md index a52504cac4bc1..bd90a6a5bf8eb 100644 --- a/packages/medusa-payment-stripe/README.md +++ b/packages/medusa-payment-stripe/README.md @@ -17,3 +17,7 @@ Learn more about how you can use this plugin in the [documentaion](https://docs. ## Automatic Payment Methods If you wish to use [Stripe's automatic payment methods](https://stripe.com/docs/connect/automatic-payment-methods) set the `automatic_payment_methods` flag to true. + +## Deprecation + +The stripe plugin version `>=1.2.x` requires medusa `>=1.8.x` \ No newline at end of file diff --git a/packages/medusa-payment-stripe/index.js b/packages/medusa-payment-stripe/index.js deleted file mode 100644 index 172f1ae6a468c..0000000000000 --- a/packages/medusa-payment-stripe/index.js +++ /dev/null @@ -1 +0,0 @@ -// noop diff --git a/packages/medusa-payment-stripe-processor/jest.config.js b/packages/medusa-payment-stripe/jest.config.js similarity index 100% rename from packages/medusa-payment-stripe-processor/jest.config.js rename to packages/medusa-payment-stripe/jest.config.js diff --git a/packages/medusa-payment-stripe/package.json b/packages/medusa-payment-stripe/package.json index c3a4d21f5882d..8ec5e44968dd6 100644 --- a/packages/medusa-payment-stripe/package.json +++ b/packages/medusa-payment-stripe/package.json @@ -2,46 +2,35 @@ "name": "medusa-payment-stripe", "version": "1.1.53", "description": "Stripe Payment provider for Meduas Commerce", - "main": "index.js", + "main": "dist/index.js", "repository": { "type": "git", "url": "https://github.com/medusajs/medusa", "directory": "packages/medusa-payment-stripe" }, - "author": "Sebastian Rindom", + "files": ["dist"], + "author": "Medusa", "license": "MIT", - "devDependencies": { - "@babel/cli": "^7.7.5", - "@babel/core": "^7.7.5", - "@babel/node": "^7.7.4", - "@babel/plugin-proposal-class-properties": "^7.7.4", - "@babel/plugin-proposal-optional-chaining": "^7.12.7", - "@babel/plugin-transform-classes": "^7.9.5", - "@babel/plugin-transform-instanceof": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.7.6", - "@babel/preset-env": "^7.7.5", - "@babel/register": "^7.7.4", - "@babel/runtime": "^7.9.6", - "client-sessions": "^0.8.0", - "cross-env": "^5.2.1", - "jest": "^25.5.4", - "medusa-interfaces": "^1.3.6", - "medusa-test-utils": "^1.1.37" - }, "scripts": { "prepare": "cross-env NODE_ENV=production yarn run build", "test": "jest --passWithNoTests src", - "build": "babel src --out-dir . --ignore '**/__tests__','**/__mocks__'", - "watch": "babel -w src --out-dir . --ignore '**/__tests__','**/__mocks__'" + "build": "tsc", + "watch": "tsc --watch" + }, + "devDependencies": { + "@medusajs/medusa": "^1.7.7", + "@types/stripe": "^8.0.417", + "cross-env": "^5.2.1", + "jest": "^25.5.4" }, "peerDependencies": { - "medusa-interfaces": "1.3.6" + "@medusajs/medusa": "^1.7.7" }, "dependencies": { "body-parser": "^1.19.0", "express": "^4.17.1", - "medusa-core-utils": "^1.1.39", - "stripe": "^8.50.0" + "medusa-core-utils": "^1.1.38", + "stripe": "^11.10.0" }, "gitHead": "81a7ff73d012fda722f6e9ef0bd9ba0232d37808", "keywords": [ diff --git a/packages/medusa-payment-stripe-processor/src/__fixtures__/data.ts b/packages/medusa-payment-stripe/src/__fixtures__/data.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/__fixtures__/data.ts rename to packages/medusa-payment-stripe/src/__fixtures__/data.ts diff --git a/packages/medusa-payment-stripe/src/__mocks__/cart.js b/packages/medusa-payment-stripe/src/__mocks__/cart.js deleted file mode 100644 index c301361bdaad7..0000000000000 --- a/packages/medusa-payment-stripe/src/__mocks__/cart.js +++ /dev/null @@ -1,216 +0,0 @@ -import { IdMap } from "medusa-test-utils" - -export const carts = { - emptyCart: { - id: IdMap.getId("emptyCart"), - items: [], - region_id: IdMap.getId("testRegion"), - customer_id: "test-customer", - payment_sessions: [], - shipping_options: [ - { - id: IdMap.getId("freeShipping"), - profile_id: "default_profile", - data: { - some_data: "yes", - }, - }, - ], - }, - frCart: { - id: IdMap.getId("fr-cart"), - email: "lebron@james.com", - title: "test", - region_id: IdMap.getId("region-france"), - items: [ - { - id: IdMap.getId("line"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - - unit_price: 8, - variant: { - id: IdMap.getId("eur-8-us-10"), - }, - product: { - id: IdMap.getId("product"), - }, - // { - // unit_price: 10, - // variant: { - // id: IdMap.getId("eur-10-us-12"), - // }, - // product: { - // id: IdMap.getId("product"), - // }, - // quantity: 1, - // }, - quantity: 10, - }, - { - id: IdMap.getId("existingLine"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - unit_price: 10, - variant: { - id: IdMap.getId("eur-10-us-12"), - }, - product: { - id: IdMap.getId("product"), - }, - quantity: 1, - }, - ], - shipping_methods: [ - { - id: IdMap.getId("freeShipping"), - profile_id: "default_profile", - }, - ], - shipping_options: [ - { - id: IdMap.getId("freeShipping"), - profile_id: "default_profile", - }, - ], - payment_sessions: [ - { - provider_id: "stripe", - data: { - id: "pi_123456789", - customer: IdMap.getId("not-lebron"), - }, - }, - ], - payment_method: { - provider_id: "stripe", - data: { - id: "pi_123456789", - customer: IdMap.getId("not-lebron"), - }, - }, - region: { currency_code: "usd" }, - total: 100, - shipping_address: {}, - billing_address: {}, - discounts: [], - customer_id: IdMap.getId("lebron"), - context: {} - }, - frCartNoStripeCustomer: { - id: IdMap.getId("fr-cart-no-customer"), - title: "test", - region_id: IdMap.getId("region-france"), - items: [ - { - id: IdMap.getId("line"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - content: [ - { - unit_price: 8, - variant: { - id: IdMap.getId("eur-8-us-10"), - }, - product: { - id: IdMap.getId("product"), - }, - quantity: 1, - }, - { - unit_price: 10, - variant: { - id: IdMap.getId("eur-10-us-12"), - }, - product: { - id: IdMap.getId("product"), - }, - quantity: 1, - }, - ], - quantity: 10, - }, - { - id: IdMap.getId("existingLine"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - content: { - unit_price: 10, - variant: { - id: IdMap.getId("eur-10-us-12"), - }, - product: { - id: IdMap.getId("product"), - }, - quantity: 1, - }, - quantity: 10, - }, - ], - shipping_methods: [ - { - id: IdMap.getId("freeShipping"), - profile_id: "default_profile", - }, - ], - shipping_options: [ - { - id: IdMap.getId("freeShipping"), - profile_id: "default_profile", - }, - ], - payment_sessions: [ - { - provider_id: "stripe", - data: { - id: "pi_no", - customer: IdMap.getId("not-lebron"), - }, - }, - ], - payment_method: { - provider_id: "stripe", - data: { - id: "pi_no", - customer: IdMap.getId("not-lebron"), - }, - }, - shipping_address: {}, - billing_address: {}, - discounts: [], - customer_id: IdMap.getId("vvd"), - }, -} - -export const CartServiceMock = { - withTransaction: function () { - return this - }, - retrieve: jest.fn().mockImplementation((cartId) => { - if (cartId === IdMap.getId("fr-cart")) { - return Promise.resolve(carts.frCart) - } - if (cartId === IdMap.getId("fr-cart-no-customer")) { - return Promise.resolve(carts.frCartNoStripeCustomer) - } - if (cartId === IdMap.getId("emptyCart")) { - return Promise.resolve(carts.emptyCart) - } - return Promise.resolve(undefined) - }), - updatePaymentSession: jest - .fn() - .mockImplementation((cartId, stripe, paymentIntent) => { - return Promise.resolve() - }), -} - -const mock = jest.fn().mockImplementation(() => { - return CartServiceMock -}) - -export default mock diff --git a/packages/medusa-payment-stripe/src/__mocks__/customer.js b/packages/medusa-payment-stripe/src/__mocks__/customer.js deleted file mode 100644 index 421f661e8806a..0000000000000 --- a/packages/medusa-payment-stripe/src/__mocks__/customer.js +++ /dev/null @@ -1,39 +0,0 @@ -import { IdMap } from "medusa-test-utils" - -export const CustomerServiceMock = { - withTransaction: function () { - return this - }, - retrieve: jest.fn().mockImplementation((id) => { - if (id === IdMap.getId("lebron")) { - return Promise.resolve({ - _id: IdMap.getId("lebron"), - first_name: "LeBron", - last_name: "James", - email: "lebron@james.com", - password_hash: "1234", - metadata: { - stripe_id: "cus_123456789_new", - }, - }) - } - if (id === IdMap.getId("vvd")) { - return Promise.resolve({ - _id: IdMap.getId("vvd"), - first_name: "Virgil", - last_name: "Van Dijk", - email: "virg@vvd.com", - password_hash: "1234", - metadata: {}, - }) - } - return Promise.resolve(undefined) - }), - setMetadata: jest.fn().mockReturnValue(Promise.resolve()), -} - -const mock = jest.fn().mockImplementation(() => { - return CustomerServiceMock -}) - -export default mock diff --git a/packages/medusa-payment-stripe/src/__mocks__/eventbus.js b/packages/medusa-payment-stripe/src/__mocks__/eventbus.js deleted file mode 100644 index e9031d94284b5..0000000000000 --- a/packages/medusa-payment-stripe/src/__mocks__/eventbus.js +++ /dev/null @@ -1,10 +0,0 @@ -export const EventBusServiceMock = { - emit: jest.fn(), - subscribe: jest.fn(), -} - -const mock = jest.fn().mockImplementation(() => { - return EventBusServiceMock -}) - -export default mock diff --git a/packages/medusa-payment-stripe/src/__mocks__/stripe.js b/packages/medusa-payment-stripe/src/__mocks__/stripe.js deleted file mode 100644 index deb6bafc8513b..0000000000000 --- a/packages/medusa-payment-stripe/src/__mocks__/stripe.js +++ /dev/null @@ -1,87 +0,0 @@ -export const StripeMock = { - customers: { - create: jest.fn().mockImplementation((data) => { - if (data.email === "virg@vvd.com") { - return Promise.resolve({ - id: "cus_vvd", - email: "virg@vvd.com", - }) - } - if (data.email === "lebron@james.com") { - return Promise.resolve({ - id: "cus_lebron", - email: "lebron@james.com", - }) - } - }), - }, - paymentIntents: { - create: jest.fn().mockImplementation((data) => { - if (data.customer === "cus_123456789_new") { - return Promise.resolve({ - id: "pi_lebron", - amount: data.amount, - customer: "cus_123456789_new", - description: data?.description, - }) - } - if (data.customer === "cus_lebron") { - return Promise.resolve({ - id: "pi_lebron", - amount: data.amount, - customer: "cus_lebron", - description: data?.description, - }) - } - }), - retrieve: jest.fn().mockImplementation((data) => { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron", - }) - }), - update: jest.fn().mockImplementation((pi, data) => { - if (data.customer === "cus_lebron_2") { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron_2", - amount: 1000, - }) - } - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000, - }) - }), - capture: jest.fn().mockImplementation((data) => { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000, - status: "succeeded", - }) - }), - cancel: jest.fn().mockImplementation((data) => { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron", - status: "cancelled", - }) - }), - }, - refunds: { - create: jest.fn().mockImplementation((data) => { - return Promise.resolve({ - id: "re_123", - payment_intent: "pi_lebron", - amount: 1000, - status: "succeeded", - }) - }), - }, -} - -const stripe = jest.fn(() => StripeMock) - -export default stripe diff --git a/packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts b/packages/medusa-payment-stripe/src/__mocks__/stripe.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/__mocks__/stripe.ts rename to packages/medusa-payment-stripe/src/__mocks__/stripe.ts diff --git a/packages/medusa-payment-stripe/src/__mocks__/totals.js b/packages/medusa-payment-stripe/src/__mocks__/totals.js deleted file mode 100644 index 5163d4ee662c6..0000000000000 --- a/packages/medusa-payment-stripe/src/__mocks__/totals.js +++ /dev/null @@ -1,12 +0,0 @@ -export const TotalsServiceMock = { - withTransaction: function () { - return this - }, - getTotal: jest.fn(), -} - -const mock = jest.fn().mockImplementation(() => { - return TotalsServiceMock -}) - -export default mock diff --git a/packages/medusa-payment-stripe-processor/src/api/hooks/index.ts b/packages/medusa-payment-stripe/src/api/hooks/index.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/api/hooks/index.ts rename to packages/medusa-payment-stripe/src/api/hooks/index.ts diff --git a/packages/medusa-payment-stripe-processor/src/api/hooks/stripe.ts b/packages/medusa-payment-stripe/src/api/hooks/stripe.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/api/hooks/stripe.ts rename to packages/medusa-payment-stripe/src/api/hooks/stripe.ts diff --git a/packages/medusa-payment-stripe/src/api/index.js b/packages/medusa-payment-stripe/src/api/index.js deleted file mode 100644 index 50feeb7074d07..0000000000000 --- a/packages/medusa-payment-stripe/src/api/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import { Router } from "express" -import hooks from "./routes/hooks" - -export default (container) => { - const app = Router() - - hooks(app) - - return app -} diff --git a/packages/medusa-payment-stripe-processor/src/api/index.ts b/packages/medusa-payment-stripe/src/api/index.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/api/index.ts rename to packages/medusa-payment-stripe/src/api/index.ts diff --git a/packages/medusa-payment-stripe/src/api/middlewares/await-middleware.js b/packages/medusa-payment-stripe/src/api/middlewares/await-middleware.js deleted file mode 100644 index ca4821e6af150..0000000000000 --- a/packages/medusa-payment-stripe/src/api/middlewares/await-middleware.js +++ /dev/null @@ -1,3 +0,0 @@ -export default (fn) => - (...args) => - fn(...args).catch(args[2]) diff --git a/packages/medusa-payment-stripe/src/api/middlewares/index.js b/packages/medusa-payment-stripe/src/api/middlewares/index.js deleted file mode 100644 index c784e319a9a33..0000000000000 --- a/packages/medusa-payment-stripe/src/api/middlewares/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import { default as wrap } from "./await-middleware" - -export default { - wrap, -} diff --git a/packages/medusa-payment-stripe/src/api/routes/hooks/index.js b/packages/medusa-payment-stripe/src/api/routes/hooks/index.js deleted file mode 100644 index 68f1ccdb86fd7..0000000000000 --- a/packages/medusa-payment-stripe/src/api/routes/hooks/index.js +++ /dev/null @@ -1,17 +0,0 @@ -import { Router } from "express" -import bodyParser from "body-parser" -import middlewares from "../../middlewares" - -const route = Router() - -export default (app) => { - app.use("/stripe", route) - - route.post( - "/hooks", - // stripe constructEvent fails without body-parser - bodyParser.raw({ type: "application/json" }), - middlewares.wrap(require("./stripe").default) - ) - return app -} diff --git a/packages/medusa-payment-stripe/src/api/routes/hooks/stripe.js b/packages/medusa-payment-stripe/src/api/routes/hooks/stripe.js deleted file mode 100644 index 14ff981c645e6..0000000000000 --- a/packages/medusa-payment-stripe/src/api/routes/hooks/stripe.js +++ /dev/null @@ -1,136 +0,0 @@ -import { PostgresError } from "@medusajs/medusa/dist/utils" - -export default async (req, res) => { - const signature = req.headers["stripe-signature"] - - let event - try { - const stripeProviderService = req.scope.resolve("pp_stripe") - event = stripeProviderService.constructWebhookEvent(req.body, signature) - } catch (err) { - res.status(400).send(`Webhook Error: ${err.message}`) - return - } - - function isPaymentCollection(id) { - return id && id.startsWith("paycol") - } - - async function handleCartPayments(event, req, res, cartId) { - const manager = req.scope.resolve("manager") - const orderService = req.scope.resolve("orderService") - - const order = await orderService - .retrieveByCartId(cartId) - .catch(() => undefined) - - // handle payment intent events - switch (event.type) { - case "payment_intent.succeeded": - if (order) { - // If order is created but not captured, we attempt to do so - if (order.payment_status !== "captured") { - await manager.transaction(async (manager) => { - await orderService - .withTransaction(manager) - .capturePayment(order.id) - }) - } else { - // Otherwise, respond with 200 preventing Stripe from retrying - return res.sendStatus(200) - } - } else { - // If order is not created, we respond with 404 to trigger Stripe retry mechanism - return res.sendStatus(404) - } - break - case "payment_intent.amount_capturable_updated": - try { - await manager.transaction(async (manager) => { - await paymentIntentAmountCapturableEventHandler({ - order, - cartId, - container: req.scope, - transactionManager: manager, - }) - }) - } catch (err) { - let message = `Stripe webhook ${event} handling failed\n${ - err?.detail ?? err?.message - }` - if (err?.code === PostgresError.SERIALIZATION_FAILURE) { - message = `Stripe webhook ${event} handle failed. This can happen when this webhook is triggered during a cart completion and can be ignored. This event should be retried automatically.\n${ - err?.detail ?? err?.message - }` - } - this.logger_.warn(message) - return res.sendStatus(409) - } - break - default: - res.sendStatus(204) - return - } - - res.sendStatus(200) - } - - async function handlePaymentCollection(event, req, res, id, paymentIntentId) { - const manager = req.scope.resolve("manager") - const paymentCollectionService = req.scope.resolve( - "paymentCollectionService" - ) - - const paycol = await paymentCollectionService - .retrieve(id, { relations: ["payments"] }) - .catch(() => undefined) - - if (paycol?.payments?.length) { - if (event.type === "payment_intent.succeeded") { - const payment = paycol.payments.find( - (pay) => pay.data.id === paymentIntentId - ) - if (payment && !payment.captured_at) { - await manager.transaction(async (manager) => { - await paymentCollectionService - .withTransaction(manager) - .capture(payment.id) - }) - } - - res.sendStatus(200) - return - } - } - res.sendStatus(204) - } - - const paymentIntent = event.data.object - const cartId = paymentIntent.metadata.cart_id // Backward compatibility - const resourceId = paymentIntent.metadata.resource_id - - if (isPaymentCollection(resourceId)) { - await handlePaymentCollection(event, req, res, resourceId, paymentIntent.id) - } else { - await handleCartPayments(event, req, res, cartId ?? resourceId) - } -} - -async function paymentIntentAmountCapturableEventHandler({ - order, - cartId, - container, - transactionManager, -}) { - if (!order) { - const cartService = container.resolve("cartService") - const orderService = container.resolve("orderService") - - const cartServiceTx = cartService.withTransaction(transactionManager) - await cartServiceTx.setPaymentSession(cartId, "stripe") - await cartServiceTx.authorizePayment(cartId) - await orderService - .withTransaction(transactionManager) - .createFromCart(cartId) - } -} diff --git a/packages/medusa-payment-stripe-processor/src/api/utils/utils.ts b/packages/medusa-payment-stripe/src/api/utils/utils.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/api/utils/utils.ts rename to packages/medusa-payment-stripe/src/api/utils/utils.ts diff --git a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts b/packages/medusa-payment-stripe/src/core/__fixtures__/data.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/core/__fixtures__/data.ts rename to packages/medusa-payment-stripe/src/core/__fixtures__/data.ts diff --git a/packages/medusa-payment-stripe-processor/src/core/__fixtures__/stripe-test.ts b/packages/medusa-payment-stripe/src/core/__fixtures__/stripe-test.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/core/__fixtures__/stripe-test.ts rename to packages/medusa-payment-stripe/src/core/__fixtures__/stripe-test.ts diff --git a/packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/core/__tests__/stripe-base.spec.ts rename to packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts diff --git a/packages/medusa-payment-stripe-processor/src/core/stripe-base.ts b/packages/medusa-payment-stripe/src/core/stripe-base.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/core/stripe-base.ts rename to packages/medusa-payment-stripe/src/core/stripe-base.ts diff --git a/packages/medusa-payment-stripe/src/helpers/__tests__/stripe-base.js b/packages/medusa-payment-stripe/src/helpers/__tests__/stripe-base.js deleted file mode 100644 index 7bd3cf247d650..0000000000000 --- a/packages/medusa-payment-stripe/src/helpers/__tests__/stripe-base.js +++ /dev/null @@ -1,284 +0,0 @@ -import { carts } from "../../__mocks__/cart" -import StripeBase from "../stripe-base"; - -const fakeContainer = {} - -describe("StripeBase", () => { - describe("createPayment", () => { - let result - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test" - } - ) - - beforeEach(async () => { - jest.clearAllMocks() - }) - - it("returns created stripe payment intent for cart with existing customer", async () => { - const cart = carts.frCart - const context = { - cart, - amount: cart.total, - currency_code: cart.region?.currency_code, - } - Object.assign(context, cart) - - result = await stripeBase.createPayment(context) - expect(result).toEqual({ - session_data: { - id: "pi_lebron", - customer: "cus_lebron", - description: undefined, - amount: 100, - }, - update_requests: { - customer_metadata: { - stripe_id: "cus_lebron" - } - } - }) - }) - - it("returns created stripe payment intent for cart with no customer", async () => { - const cart = carts.frCart - const context = { - cart, - amount: cart.total, - currency_code: cart.region?.currency_code, - } - Object.assign(context, cart) - - context.cart.context.payment_description = 'some description' - - result = await stripeBase.createPayment(context) - expect(result).toEqual({ - session_data: { - id: "pi_lebron", - customer: "cus_lebron", - description: 'some description', - amount: 100, - }, - update_requests: { - customer_metadata: { - stripe_id: "cus_lebron" - } - } - }) - }) - - it("returns created stripe payment intent for cart with no customer and the options default description", async () => { - const localStripeProviderService = new StripeBase( - fakeContainer, - { - api_key: "test", - payment_description: "test options description" - }) - - const cart = carts.frCart - const context = { - cart, - amount: cart.total, - currency_code: cart.region?.currency_code, - } - Object.assign(context, cart) - - context.cart.context.payment_description = null - - result = await localStripeProviderService.createPayment(context) - expect(result).toEqual({ - session_data: { - id: "pi_lebron", - customer: "cus_lebron", - description: "test options description", - amount: 100, - }, - update_requests: { - customer_metadata: { - stripe_id: "cus_lebron" - } - } - }) - }) - }) - - describe("retrievePayment", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.retrievePayment({ - payment_method: { - data: { - id: "pi_lebron", - }, - }, - }) - }) - - it("returns stripe payment intent", () => { - expect(result).toEqual({ - id: "pi_lebron", - customer: "cus_lebron", - }) - }) - }) - - describe("updatePayment", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.updatePayment( - { - id: "pi_lebron", - amount: 800, - }, - { - total: 1000, - } - ) - }) - - it("returns updated stripe payment intent", () => { - expect(result).toEqual({ - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000, - }) - }) - }) - - describe("updatePaymentIntentCustomer", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.updatePaymentIntentCustomer( - "pi_lebron", - "cus_lebron_2" - ) - }) - - it("returns update stripe payment intent", () => { - expect(result).toEqual({ - id: "pi_lebron", - customer: "cus_lebron_2", - amount: 1000, - }) - }) - }) - - describe("capturePayment", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.capturePayment({ - data: { - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000, - }, - }) - }) - - it("returns captured stripe payment intent", () => { - expect(result).toEqual({ - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000, - status: "succeeded", - }) - }) - }) - - describe("refundPayment", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.refundPayment( - { - data: { - id: "re_123", - payment_intent: "pi_lebron", - amount: 1000, - status: "succeeded", - }, - }, - 1000 - ) - }) - - it("returns refunded stripe payment intent", () => { - expect(result).toEqual({ - id: "re_123", - payment_intent: "pi_lebron", - amount: 1000, - status: "succeeded", - }) - }) - }) - - describe("cancelPayment", () => { - let result - beforeAll(async () => { - jest.clearAllMocks() - const stripeBase = new StripeBase( - fakeContainer, - { - api_key: "test", - } - ) - - result = await stripeBase.cancelPayment({ - data: { - id: "pi_lebron", - customer: "cus_lebron", - status: "cancelled", - }, - }) - }) - - it("returns cancelled stripe payment intent", () => { - expect(result).toEqual({ - id: "pi_lebron", - customer: "cus_lebron", - status: "cancelled", - }) - }) - }) -}) diff --git a/packages/medusa-payment-stripe/src/helpers/stripe-base.js b/packages/medusa-payment-stripe/src/helpers/stripe-base.js deleted file mode 100644 index 7f5ea1a81f6ac..0000000000000 --- a/packages/medusa-payment-stripe/src/helpers/stripe-base.js +++ /dev/null @@ -1,305 +0,0 @@ -import { AbstractPaymentService } from "@medusajs/medusa" -import Stripe from "stripe" -import { PaymentSessionStatus } from "@medusajs/medusa/dist"; - -class StripeBase extends AbstractPaymentService { - static identifier = null - - constructor(_, options) { - super(_, options) - - /** - * Required Stripe options: - * { - * api_key: "stripe_secret_key", REQUIRED - * webhook_secret: "stripe_webhook_secret", REQUIRED - * // Use this flag to capture payment immediately (default is false) - * capture: true - * } - */ - this.options_ = options - - /** @private @const {Stripe} */ - this.stripe_ = Stripe(options.api_key) - } - - getPaymentIntentOptions() { - const options = {} - - if (this?.paymentIntentOptions?.capture_method) { - options.capture_method = this.paymentIntentOptions.capture_method - } - - if (this?.paymentIntentOptions?.setup_future_usage) { - options.setup_future_usage = this.paymentIntentOptions.setup_future_usage - } - - if (this?.paymentIntentOptions?.payment_method_types) { - options.payment_method_types = - this.paymentIntentOptions.payment_method_types - } - - return options - } - - /** - * Get payment session status - * statuses. - * @param {PaymentSessionData} paymentData - the data stored with the payment session - * @return {Promise} the status of the order - */ - async getStatus(paymentData) { - const { id } = paymentData - const paymentIntent = await this.stripe_.paymentIntents.retrieve(id) - - switch (paymentIntent.status) { - case "requires_payment_method": - case "requires_confirmation": - case "processing": - return PaymentSessionStatus.PENDING - case "requires_action": - return PaymentSessionStatus.REQUIRES_MORE - case "canceled": - return PaymentSessionStatus.CANCELED - case "requires_capture": - case "succeeded": - return PaymentSessionStatus.AUTHORIZED - default: - return PaymentSessionStatus.PENDING - } - } - - /** - * Fetches a customers saved payment methods if registered in Stripe. - * @param {Customer} customer - customer to fetch saved cards for - * @return {Promise} saved payments methods - */ - async retrieveSavedMethods(customer) { - if (customer.metadata && customer.metadata.stripe_id) { - const methods = await this.stripe_.paymentMethods.list({ - customer: customer.metadata.stripe_id, - type: "card", - }) - - return methods.data - } - - return [] - } - - /** - * Fetches a Stripe customer - * @param {string} customerId - Stripe customer id - * @return {Promise} Stripe customer - */ - async retrieveCustomer(customerId) { - if (!customerId) { - return - } - return await this.stripe_.customers.retrieve(customerId) - } - - /** - * Creates a Stripe payment intent. - * If customer is not registered in Stripe, we do so. - * @param {Cart & PaymentContext} context - context to use to create a payment for - * @return {Promise} Stripe payment intent - */ - async createPayment(context) { - const intentRequestData = this.getPaymentIntentOptions() - const { id: cart_id, email, context: cart_context, currency_code, amount, resource_id, customer } = context - - const intentRequest = { - description: - cart_context.payment_description ?? - this.options_?.payment_description, - amount: Math.round(amount), - currency: currency_code, - metadata: { cart_id, resource_id }, - capture_method: this.options_.capture ? "automatic" : "manual", - ...intentRequestData, - } - - if (this.options_?.automatic_payment_methods) { - intentRequest.automatic_payment_methods = { enabled: true } - } - - if (customer?.metadata?.stripe_id) { - intentRequest.customer = customer?.metadata?.stripe_id - } else { - const stripeCustomer = await this.stripe_.customers.create({ - email, - }) - - intentRequest.customer = stripeCustomer.id - } - - const session_data = await this.stripe_.paymentIntents.create( - intentRequest - ) - - return { - session_data, - update_requests: customer?.metadata?.stripe_id ? undefined : { - customer_metadata: { - stripe_id: intentRequest.customer - } - } - } - } - - /** - * Retrieves Stripe payment intent. - * @param {PaymentData} data - the data of the payment to retrieve - * @return {Promise} Stripe payment intent - */ - async retrievePayment(data) { - return await this.stripe_.paymentIntents.retrieve(data.id) - } - - /** - * Gets a Stripe payment intent and returns it. - * @param {PaymentSession} paymentSession - the data of the payment to retrieve - * @return {Promise} Stripe payment intent - */ - async getPaymentData(paymentSession) { - return await this.stripe_.paymentIntents.retrieve(paymentSession.data.id) - } - - /** - * Authorizes Stripe payment intent by simply returning - * the status for the payment intent in use. - * @param {PaymentSession} paymentSession - payment session data - * @param {Data} context - properties relevant to current context - * @return {Promise<{ data: PaymentSessionData; status: PaymentSessionStatus }>} result with data and status - */ - async authorizePayment(paymentSession, context = {}) { - const stat = await this.getStatus(paymentSession.data) - return { data: paymentSession.data, status: stat } - } - - async updatePaymentData(sessionData, update) { - return await this.stripe_.paymentIntents.update(sessionData.id, { - ...update.data, - }) - } - - /** - * Updates Stripe payment intent. - * @param {PaymentSessionData} paymentSessionData - payment session data. - * @param {Cart & PaymentContext} context - * @return {Promise} Stripe payment intent - */ - async updatePayment(paymentSessionData, context) { - const { amount, customer } = context - const stripeId = customer?.metadata?.stripe_id || undefined - - if (stripeId !== paymentSessionData.customer) { - return await this.createPayment(context) - } else { - if ( - amount && - paymentSessionData.amount === Math.round(amount) - ) { - return paymentSessionData - } - - return await this.stripe_.paymentIntents.update(paymentSessionData.id, { - amount: Math.round(amount), - }) - } - } - - async deletePayment(payment) { - const { id } = payment.data - return this.stripe_.paymentIntents.cancel(id).catch((err) => { - if (err.statusCode === 400) { - return - } - throw err - }) - } - - /** - * Updates customer of Stripe payment intent. - * @param {string} paymentIntentId - id of payment intent to update - * @param {string} customerId - id of \ Stripe customer - * @return {object} Stripe payment intent - */ - async updatePaymentIntentCustomer(paymentIntentId, customerId) { - return await this.stripe_.paymentIntents.update(paymentIntentId, { - customer: customerId, - }) - } - - /** - * Captures payment for Stripe payment intent. - * @param {Payment} payment - payment method data from cart - * @return {Promise} Stripe payment intent - */ - async capturePayment(payment) { - const { id } = payment.data - try { - const intent = await this.stripe_.paymentIntents.capture(id) - return intent - } catch (error) { - if (error.code === "payment_intent_unexpected_state") { - if (error.payment_intent.status === "succeeded") { - return error.payment_intent - } - } - throw error - } - } - - /** - * Refunds payment for Stripe payment intent. - * @param {Payment} payment - payment method data from cart - * @param {number} refundAmount - amount to refund - * @return {Promise} refunded payment intent - */ - async refundPayment(payment, amountToRefund) { - const { id } = payment.data - await this.stripe_.refunds.create({ - amount: Math.round(amountToRefund), - payment_intent: id, - }) - - return payment.data - } - - /** - * Cancels payment for Stripe payment intent. - * @param {Payment} payment - payment method data from cart - * @return {Promise} canceled payment intent - */ - async cancelPayment(payment) { - const { id } = payment.data - try { - return await this.stripe_.paymentIntents.cancel(id) - } catch (error) { - if (error.payment_intent.status === "canceled") { - return error.payment_intent - } - - throw error - } - } - - /** - * Constructs Stripe Webhook event - * @param {object} data - the data of the webhook request: req.body - * @param {object} signature - the Stripe signature on the event, that - * ensures integrity of the webhook event - * @return {object} Stripe Webhook event - */ - constructWebhookEvent(data, signature) { - return this.stripe_.webhooks.constructEvent( - data, - signature, - this.options_.webhook_secret - ) - } -} - -export default StripeBase diff --git a/packages/medusa-payment-stripe-processor/src/index.ts b/packages/medusa-payment-stripe/src/index.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/index.ts rename to packages/medusa-payment-stripe/src/index.ts diff --git a/packages/medusa-payment-stripe/src/services/stripe-bancontact.js b/packages/medusa-payment-stripe/src/services/stripe-bancontact.js deleted file mode 100644 index a12f9d52515f8..0000000000000 --- a/packages/medusa-payment-stripe/src/services/stripe-bancontact.js +++ /dev/null @@ -1,18 +0,0 @@ -import StripeBase from "../helpers/stripe-base" - -class BancontactProviderService extends StripeBase { - static identifier = "stripe-bancontact" - - constructor(_, options) { - super(_, options) - } - - get paymentIntentOptions() { - return { - payment_method_types: ["bancontact"], - capture_method: "automatic", - } - } -} - -export default BancontactProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts b/packages/medusa-payment-stripe/src/services/stripe-bancontact.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/services/stripe-bancontact.ts rename to packages/medusa-payment-stripe/src/services/stripe-bancontact.ts diff --git a/packages/medusa-payment-stripe/src/services/stripe-blik.js b/packages/medusa-payment-stripe/src/services/stripe-blik.js deleted file mode 100644 index 6e18a17fcc947..0000000000000 --- a/packages/medusa-payment-stripe/src/services/stripe-blik.js +++ /dev/null @@ -1,18 +0,0 @@ -import StripeBase from "../helpers/stripe-base" - -class BlikProviderService extends StripeBase { - static identifier = "stripe-blik" - - constructor(_, options) { - super(_, options) - } - - get paymentIntentOptions() { - return { - payment_method_types: ["blik"], - capture_method: "automatic", - } - } -} - -export default BlikProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts b/packages/medusa-payment-stripe/src/services/stripe-blik.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/services/stripe-blik.ts rename to packages/medusa-payment-stripe/src/services/stripe-blik.ts diff --git a/packages/medusa-payment-stripe/src/services/stripe-giropay.js b/packages/medusa-payment-stripe/src/services/stripe-giropay.js deleted file mode 100644 index 94b19415f03f3..0000000000000 --- a/packages/medusa-payment-stripe/src/services/stripe-giropay.js +++ /dev/null @@ -1,18 +0,0 @@ -import StripeBase from "../helpers/stripe-base" - -class GiropayProviderService extends StripeBase { - static identifier = "stripe-giropay" - - constructor(_, options) { - super(_, options) - } - - get paymentIntentOptions() { - return { - payment_method_types: ["giropay"], - capture_method: "automatic", - } - } -} - -export default GiropayProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts b/packages/medusa-payment-stripe/src/services/stripe-giropay.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/services/stripe-giropay.ts rename to packages/medusa-payment-stripe/src/services/stripe-giropay.ts diff --git a/packages/medusa-payment-stripe/src/services/stripe-ideal.js b/packages/medusa-payment-stripe/src/services/stripe-ideal.js deleted file mode 100644 index 6d20df143cd5f..0000000000000 --- a/packages/medusa-payment-stripe/src/services/stripe-ideal.js +++ /dev/null @@ -1,18 +0,0 @@ -import StripeBase from "../helpers/stripe-base" - -class IdealProviderService extends StripeBase { - static identifier = "stripe-ideal" - - constructor(_, options) { - super(_, options) - } - - get paymentIntentOptions() { - return { - payment_method_types: ["ideal"], - capture_method: "automatic", - } - } -} - -export default IdealProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts b/packages/medusa-payment-stripe/src/services/stripe-ideal.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/services/stripe-ideal.ts rename to packages/medusa-payment-stripe/src/services/stripe-ideal.ts diff --git a/packages/medusa-payment-stripe/src/services/stripe-provider.js b/packages/medusa-payment-stripe/src/services/stripe-provider.js deleted file mode 100644 index ac2f47a23220d..0000000000000 --- a/packages/medusa-payment-stripe/src/services/stripe-provider.js +++ /dev/null @@ -1,15 +0,0 @@ -import StripeBase from "../helpers/stripe-base"; - -class StripeProviderService extends StripeBase { - static identifier = "stripe" - - constructor(_, options) { - super(_, options) - } - - get paymentIntentOptions() { - return {} - } -} - -export default StripeProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts b/packages/medusa-payment-stripe/src/services/stripe-provider.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/services/stripe-provider.ts rename to packages/medusa-payment-stripe/src/services/stripe-provider.ts diff --git a/packages/medusa-payment-stripe/src/services/stripe-przelewy24.js b/packages/medusa-payment-stripe/src/services/stripe-przelewy24.js deleted file mode 100644 index 236d8c38b017b..0000000000000 --- a/packages/medusa-payment-stripe/src/services/stripe-przelewy24.js +++ /dev/null @@ -1,18 +0,0 @@ -import StripeBase from "../helpers/stripe-base" - -class Przelewy24ProviderService extends StripeBase { - static identifier = "stripe-przelewy24" - - constructor(_, options) { - super(_, options) - } - - get paymentIntentOptions() { - return { - payment_method_types: ["p24"], - capture_method: "automatic", - } - } -} - -export default Przelewy24ProviderService diff --git a/packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts b/packages/medusa-payment-stripe/src/services/stripe-przelewy24.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/services/stripe-przelewy24.ts rename to packages/medusa-payment-stripe/src/services/stripe-przelewy24.ts diff --git a/packages/medusa-payment-stripe-processor/src/types.ts b/packages/medusa-payment-stripe/src/types.ts similarity index 100% rename from packages/medusa-payment-stripe-processor/src/types.ts rename to packages/medusa-payment-stripe/src/types.ts diff --git a/packages/medusa-payment-stripe-processor/tsconfig.json b/packages/medusa-payment-stripe/tsconfig.json similarity index 100% rename from packages/medusa-payment-stripe-processor/tsconfig.json rename to packages/medusa-payment-stripe/tsconfig.json diff --git a/packages/medusa-payment-stripe-processor/tsconfig.spec.json b/packages/medusa-payment-stripe/tsconfig.spec.json similarity index 100% rename from packages/medusa-payment-stripe-processor/tsconfig.spec.json rename to packages/medusa-payment-stripe/tsconfig.spec.json diff --git a/yarn.lock b/yarn.lock index aa8daa87b2188..4b8cfbabbc2ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25706,9 +25706,9 @@ __metadata: languageName: unknown linkType: soft -"medusa-payment-stripe-processor@workspace:packages/medusa-payment-stripe-processor": +"medusa-payment-stripe@workspace:packages/medusa-payment-stripe": version: 0.0.0-use.local - resolution: "medusa-payment-stripe-processor@workspace:packages/medusa-payment-stripe-processor" + resolution: "medusa-payment-stripe@workspace:packages/medusa-payment-stripe" dependencies: "@medusajs/medusa": ^1.7.7 "@types/stripe": ^8.0.417 @@ -25723,35 +25723,6 @@ __metadata: languageName: unknown linkType: soft -"medusa-payment-stripe@workspace:packages/medusa-payment-stripe": - version: 0.0.0-use.local - resolution: "medusa-payment-stripe@workspace:packages/medusa-payment-stripe" - dependencies: - "@babel/cli": ^7.7.5 - "@babel/core": ^7.7.5 - "@babel/node": ^7.7.4 - "@babel/plugin-proposal-class-properties": ^7.7.4 - "@babel/plugin-proposal-optional-chaining": ^7.12.7 - "@babel/plugin-transform-classes": ^7.9.5 - "@babel/plugin-transform-instanceof": ^7.8.3 - "@babel/plugin-transform-runtime": ^7.7.6 - "@babel/preset-env": ^7.7.5 - "@babel/register": ^7.7.4 - "@babel/runtime": ^7.9.6 - body-parser: ^1.19.0 - client-sessions: ^0.8.0 - cross-env: ^5.2.1 - express: ^4.17.1 - jest: ^25.5.4 - medusa-core-utils: ^1.1.39 - medusa-interfaces: ^1.3.6 - medusa-test-utils: ^1.1.37 - stripe: ^8.50.0 - peerDependencies: - medusa-interfaces: 1.3.6 - languageName: unknown - linkType: soft - "medusa-plugin-algolia@workspace:packages/medusa-plugin-algolia": version: 0.0.0-use.local resolution: "medusa-plugin-algolia@workspace:packages/medusa-plugin-algolia" From b882792f2461b96a8618fc3b7203bf19b46c56a2 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Thu, 23 Feb 2023 12:34:35 +0100 Subject: [PATCH 21/36] update eslint --- .eslintignore | 2 +- .eslintrc.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintignore b/.eslintignore index b42392c6a7d26..201dccdc07700 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,7 +7,7 @@ jest* packages/* # List of packages to Lint !packages/medusa -!packages/medusa-payment-stripe-processor +!packages/medusa-payment-stripe diff --git a/.eslintrc.js b/.eslintrc.js index d65fa8b7c8c5f..d1cd830744a7d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -82,7 +82,7 @@ module.exports = { parserOptions: { project: [ "./packages/medusa/tsconfig.json", - "./packages/medusa-payment-stripe-processor/tsconfig.json", + "./packages/medusa-payment-stripe/tsconfig.json", ] }, rules: { From 48de57aab0e1b2814730b63a7c36843f69941457 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Thu, 23 Feb 2023 12:51:46 +0100 Subject: [PATCH 22/36] refactor plugin loader --- packages/medusa/src/loaders/plugins.ts | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/packages/medusa/src/loaders/plugins.ts b/packages/medusa/src/loaders/plugins.ts index 4511571b5aa03..ac3d27ac995eb 100644 --- a/packages/medusa/src/loaders/plugins.ts +++ b/packages/medusa/src/loaders/plugins.ts @@ -618,19 +618,12 @@ function resolvePlugin(pluginName: string): { const computedResolvedPath = resolvedPath + (process.env.DEV_MODE ? "/src" : "") - let resolvedPathToDist = "" - let isDistExist = false - - try { - resolvedPathToDist = resolvedPath + "/dist" - // Allow a plugin to choose to output the build to dist, only if not in dev mode - isDistExist = - resolvedPathToDist && - !process.env.DEV_MODE && - existsSync(resolvedPath + "/dist") - } catch (e) { - // noop - } + // Add support for a plugin to output the build into a dist directory + const resolvedPathToDist = resolvedPath + "/dist" + const isDistExist = + resolvedPathToDist && + !process.env.DEV_MODE && + existsSync(resolvedPath + "/dist") return { resolve: isDistExist ? resolvedPathToDist : computedResolvedPath, From 26b8e2bf96ebc407dab97618b7a056a770c078c8 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Thu, 23 Feb 2023 13:16:05 +0100 Subject: [PATCH 23/36] cleanup --- packages/medusa-payment-stripe/package.json | 4 +++- .../src/__fixtures__/data.ts | 2 +- .../src/api/hooks/stripe.ts | 8 +++----- packages/medusa-payment-stripe/src/index.ts | 1 - .../src/interfaces/cart-completion-strategy.ts | 1 + .../medusa/src/strategies/cart-completion.ts | 17 +++++++---------- 6 files changed, 15 insertions(+), 18 deletions(-) delete mode 100644 packages/medusa-payment-stripe/src/index.ts diff --git a/packages/medusa-payment-stripe/package.json b/packages/medusa-payment-stripe/package.json index 8ec5e44968dd6..8c7c645836521 100644 --- a/packages/medusa-payment-stripe/package.json +++ b/packages/medusa-payment-stripe/package.json @@ -8,7 +8,9 @@ "url": "https://github.com/medusajs/medusa", "directory": "packages/medusa-payment-stripe" }, - "files": ["dist"], + "files": [ + "dist" + ], "author": "Medusa", "license": "MIT", "scripts": { diff --git a/packages/medusa-payment-stripe/src/__fixtures__/data.ts b/packages/medusa-payment-stripe/src/__fixtures__/data.ts index 9ab2e88a37ab1..fc2040fd25dba 100644 --- a/packages/medusa-payment-stripe/src/__fixtures__/data.ts +++ b/packages/medusa-payment-stripe/src/__fixtures__/data.ts @@ -27,4 +27,4 @@ export const PaymentIntentDataByStatus = { id: "succeeded", status: "succeeded" }, -} \ No newline at end of file +} diff --git a/packages/medusa-payment-stripe/src/api/hooks/stripe.ts b/packages/medusa-payment-stripe/src/api/hooks/stripe.ts index 84571144bd835..1c7454e0d2cce 100644 --- a/packages/medusa-payment-stripe/src/api/hooks/stripe.ts +++ b/packages/medusa-payment-stripe/src/api/hooks/stripe.ts @@ -146,11 +146,9 @@ async function paymentIntentAmountCapturableEventHandler({ .withTransaction(transactionManager) .retrieve(cartId, { select: ["context"] }) - const { response_code, response_body } = await completionStrat.complete( - cartId, - idempotencyKey, - { ip: cart.context?.ip as string } - ) + const { response_code, response_body } = await completionStrat + .withTransaction(transactionManager) + .complete(cartId, idempotencyKey, { ip: cart.context?.ip as string }) if (response_code !== 200) { throw new MedusaError( diff --git a/packages/medusa-payment-stripe/src/index.ts b/packages/medusa-payment-stripe/src/index.ts deleted file mode 100644 index 625c0891b2c30..0000000000000 --- a/packages/medusa-payment-stripe/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -// noop \ No newline at end of file diff --git a/packages/medusa/src/interfaces/cart-completion-strategy.ts b/packages/medusa/src/interfaces/cart-completion-strategy.ts index c28dc849bea84..933c569ff1e27 100644 --- a/packages/medusa/src/interfaces/cart-completion-strategy.ts +++ b/packages/medusa/src/interfaces/cart-completion-strategy.ts @@ -27,6 +27,7 @@ export interface ICartCompletionStrategy { } export abstract class AbstractCartCompletionStrategy + extends TransactionBaseService implements ICartCompletionStrategy { abstract complete( diff --git a/packages/medusa/src/strategies/cart-completion.ts b/packages/medusa/src/strategies/cart-completion.ts index e1d592ac9e1d8..634d08674db0d 100644 --- a/packages/medusa/src/strategies/cart-completion.ts +++ b/packages/medusa/src/strategies/cart-completion.ts @@ -30,8 +30,6 @@ type InjectedDependencies = { } class CartCompletionStrategy extends AbstractCartCompletionStrategy { - protected manager_: EntityManager - // eslint-disable-next-line max-len protected readonly productVariantInventoryService_: ProductVariantInventoryService protected readonly paymentProviderService_: PaymentProviderService @@ -47,9 +45,9 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy { cartService, orderService, swapService, - manager, }: InjectedDependencies) { - super() + // eslint-disable-next-line prefer-rest-params + super(arguments[0]) this.paymentProviderService_ = paymentProviderService this.productVariantInventoryService_ = productVariantInventoryService @@ -57,7 +55,6 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy { this.cartService_ = cartService this.orderService_ = orderService this.swapService_ = swapService - this.manager_ = manager } async complete( @@ -73,7 +70,7 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy { while (inProgress) { switch (idempotencyKey.recovery_point) { case "started": { - await this.manager_ + await this.activeManager_ .transaction("SERIALIZABLE", async (transactionManager) => { idempotencyKey = await this.idempotencyKeyService_ .withTransaction(transactionManager) @@ -90,7 +87,7 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy { break } case "tax_lines_created": { - await this.manager_ + await this.activeManager_ .transaction("SERIALIZABLE", async (transactionManager) => { idempotencyKey = await this.idempotencyKeyService_ .withTransaction(transactionManager) @@ -111,7 +108,7 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy { } case "payment_authorized": { - await this.manager_ + await this.activeManager_ .transaction("SERIALIZABLE", async (transactionManager) => { idempotencyKey = await this.idempotencyKeyService_ .withTransaction(transactionManager) @@ -134,7 +131,7 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy { } default: - await this.manager_.transaction(async (transactionManager) => { + await this.activeManager_.transaction(async (transactionManager) => { idempotencyKey = await this.idempotencyKeyService_ .withTransaction(transactionManager) .update(idempotencyKey.idempotency_key, { @@ -149,7 +146,7 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy { if (err) { if (idempotencyKey.recovery_point !== "started") { - await this.manager_.transaction(async (transactionManager) => { + await this.activeManager_.transaction(async (transactionManager) => { try { await this.orderService_ .withTransaction(transactionManager) From 73301da0834f215c5c645288f79942b9afed310b Mon Sep 17 00:00:00 2001 From: adrien2p Date: Thu, 23 Feb 2023 13:18:24 +0100 Subject: [PATCH 24/36] eslint clean --- .eslintrc.js | 2 +- .../src/__fixtures__/data.ts | 14 +- .../src/core/__fixtures__/data.ts | 80 +++--- .../src/core/__fixtures__/stripe-test.ts | 10 +- .../src/core/__tests__/stripe-base.spec.ts | 235 +++++++++++------- 5 files changed, 200 insertions(+), 141 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index d1cd830744a7d..9893804579d03 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -82,7 +82,7 @@ module.exports = { parserOptions: { project: [ "./packages/medusa/tsconfig.json", - "./packages/medusa-payment-stripe/tsconfig.json", + "./packages/medusa-payment-stripe/tsconfig.spec.json", ] }, rules: { diff --git a/packages/medusa-payment-stripe/src/__fixtures__/data.ts b/packages/medusa-payment-stripe/src/__fixtures__/data.ts index fc2040fd25dba..ae3e4571a4dc9 100644 --- a/packages/medusa-payment-stripe/src/__fixtures__/data.ts +++ b/packages/medusa-payment-stripe/src/__fixtures__/data.ts @@ -1,30 +1,30 @@ export const PaymentIntentDataByStatus = { REQUIRE_PAYMENT_METHOD: { id: "requires_payment_method", - status: "requires_payment_method" + status: "requires_payment_method", }, REQUIRES_CONFIRMATION: { id: "requires_confirmation", - status: "requires_confirmation" + status: "requires_confirmation", }, PROCESSING: { id: "processing", - status: "processing" + status: "processing", }, REQUIRES_ACTION: { id: "requires_action", - status: "requires_action" + status: "requires_action", }, CANCELED: { id: "canceled", - status: "canceled" + status: "canceled", }, REQUIRES_CAPTURE: { id: "requires_capture", - status: "requires_capture" + status: "requires_capture", }, SUCCEEDED: { id: "succeeded", - status: "succeeded" + status: "succeeded", }, } diff --git a/packages/medusa-payment-stripe/src/core/__fixtures__/data.ts b/packages/medusa-payment-stripe/src/core/__fixtures__/data.ts index 6d22d871f2019..3ef41086dbeb5 100644 --- a/packages/medusa-payment-stripe/src/core/__fixtures__/data.ts +++ b/packages/medusa-payment-stripe/src/core/__fixtures__/data.ts @@ -2,9 +2,9 @@ import { EXISTING_CUSTOMER_EMAIL, FAIL_INTENT_ID, PARTIALLY_FAIL_INTENT_ID, - WRONG_CUSTOMER_EMAIL -} from "../../__mocks__/stripe"; -import { PaymentIntentDataByStatus } from "../../__fixtures__/data"; + WRONG_CUSTOMER_EMAIL, +} from "../../__mocks__/stripe" +import { PaymentIntentDataByStatus } from "../../__fixtures__/data" // INITIATE PAYMENT DATA @@ -15,7 +15,7 @@ export const initiatePaymentContextWithExistingCustomer = { resource_id: "test", customer: {}, context: {}, - paymentSessionData: {} + paymentSessionData: {}, } export const initiatePaymentContextWithExistingCustomerStripeId = { @@ -25,11 +25,11 @@ export const initiatePaymentContextWithExistingCustomerStripeId = { resource_id: "test", customer: { metadata: { - stripe_id: "test" - } + stripe_id: "test", + }, }, context: {}, - paymentSessionData: {} + paymentSessionData: {}, } export const initiatePaymentContextWithWrongEmail = { @@ -39,7 +39,7 @@ export const initiatePaymentContextWithWrongEmail = { resource_id: "test", customer: {}, context: {}, - paymentSessionData: {} + paymentSessionData: {}, } export const initiatePaymentContextWithFailIntentCreation = { @@ -49,83 +49,83 @@ export const initiatePaymentContextWithFailIntentCreation = { resource_id: "test", customer: {}, context: { - payment_description: "fail" + payment_description: "fail", }, - paymentSessionData: {} + paymentSessionData: {}, } // AUTHORIZE PAYMENT DATA export const authorizePaymentSuccessData = { - id: PaymentIntentDataByStatus.SUCCEEDED.id + id: PaymentIntentDataByStatus.SUCCEEDED.id, } // CANCEL PAYMENT DATA export const cancelPaymentSuccessData = { - id: PaymentIntentDataByStatus.SUCCEEDED.id + id: PaymentIntentDataByStatus.SUCCEEDED.id, } export const cancelPaymentFailData = { - id: FAIL_INTENT_ID + id: FAIL_INTENT_ID, } export const cancelPaymentPartiallyFailData = { - id: PARTIALLY_FAIL_INTENT_ID + id: PARTIALLY_FAIL_INTENT_ID, } // CAPTURE PAYMENT DATA export const capturePaymentContextSuccessData = { paymentSessionData: { - id: PaymentIntentDataByStatus.SUCCEEDED.id - } + id: PaymentIntentDataByStatus.SUCCEEDED.id, + }, } export const capturePaymentContextFailData = { paymentSessionData: { - id: FAIL_INTENT_ID - } + id: FAIL_INTENT_ID, + }, } export const capturePaymentContextPartiallyFailData = { paymentSessionData: { - id: PARTIALLY_FAIL_INTENT_ID - } + id: PARTIALLY_FAIL_INTENT_ID, + }, } // DELETE PAYMENT DATA export const deletePaymentSuccessData = { - id: PaymentIntentDataByStatus.SUCCEEDED.id + id: PaymentIntentDataByStatus.SUCCEEDED.id, } export const deletePaymentFailData = { - id: FAIL_INTENT_ID + id: FAIL_INTENT_ID, } export const deletePaymentPartiallyFailData = { - id: PARTIALLY_FAIL_INTENT_ID + id: PARTIALLY_FAIL_INTENT_ID, } // REFUND PAYMENT DATA export const refundPaymentSuccessData = { - id: PaymentIntentDataByStatus.SUCCEEDED.id + id: PaymentIntentDataByStatus.SUCCEEDED.id, } export const refundPaymentFailData = { - id: FAIL_INTENT_ID + id: FAIL_INTENT_ID, } // RETRIEVE PAYMENT DATA export const retrievePaymentSuccessData = { - id: PaymentIntentDataByStatus.SUCCEEDED.id + id: PaymentIntentDataByStatus.SUCCEEDED.id, } export const retrievePaymentFailData = { - id: FAIL_INTENT_ID + id: FAIL_INTENT_ID, } // UPDATE PAYMENT DATA @@ -140,7 +140,7 @@ export const updatePaymentContextWithExistingCustomer = { paymentSessionData: { customer: "test", amount: 1000, - } + }, } export const updatePaymentContextWithExistingCustomerStripeId = { @@ -150,14 +150,14 @@ export const updatePaymentContextWithExistingCustomerStripeId = { resource_id: "test", customer: { metadata: { - stripe_id: "test" - } + stripe_id: "test", + }, }, context: {}, paymentSessionData: { customer: "test", amount: 1000, - } + }, } export const updatePaymentContextWithWrongEmail = { @@ -170,7 +170,7 @@ export const updatePaymentContextWithWrongEmail = { paymentSessionData: { customer: "test", amount: 1000, - } + }, } export const updatePaymentContextWithDifferentAmount = { @@ -180,15 +180,15 @@ export const updatePaymentContextWithDifferentAmount = { resource_id: "test", customer: { metadata: { - stripe_id: "test" - } + stripe_id: "test", + }, }, context: {}, paymentSessionData: { id: PaymentIntentDataByStatus.SUCCEEDED.id, customer: "test", amount: 1000, - } + }, } export const updatePaymentContextFailWithDifferentAmount = { @@ -198,17 +198,17 @@ export const updatePaymentContextFailWithDifferentAmount = { resource_id: "test", customer: { metadata: { - stripe_id: "test" - } + stripe_id: "test", + }, }, context: { metadata: { - stripe_id: "test" - } + stripe_id: "test", + }, }, paymentSessionData: { id: FAIL_INTENT_ID, customer: "test", amount: 1000, - } + }, } diff --git a/packages/medusa-payment-stripe/src/core/__fixtures__/stripe-test.ts b/packages/medusa-payment-stripe/src/core/__fixtures__/stripe-test.ts index 3452e78dd06ad..6d60d45c09236 100644 --- a/packages/medusa-payment-stripe/src/core/__fixtures__/stripe-test.ts +++ b/packages/medusa-payment-stripe/src/core/__fixtures__/stripe-test.ts @@ -1,12 +1,12 @@ -import StripeBase from "../stripe-base"; -import { PaymentIntentOptions } from "../../types"; +import StripeBase from "../stripe-base" +import { PaymentIntentOptions } from "../../types" export class StripeTest extends StripeBase { constructor(_, options) { - super(_, options); + super(_, options) } - + get paymentIntentOptions(): PaymentIntentOptions { return {} } -} \ No newline at end of file +} diff --git a/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts index d13cccdf4b53b..25f1a18873507 100644 --- a/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts +++ b/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts @@ -30,14 +30,14 @@ import { import { PARTIALLY_FAIL_INTENT_ID, STRIPE_ID, - StripeMock + StripeMock, } from "../../__mocks__/stripe" -import { ErrorIntentStatus } from "../../types"; +import { ErrorIntentStatus } from "../../types" const container = {} describe("StripeTest", () => { - describe('getPaymentStatus', function () { + describe("getPaymentStatus", function () { let stripeTest beforeAll(async () => { @@ -54,48 +54,48 @@ describe("StripeTest", () => { let status: PaymentSessionStatus status = await stripeTest.getPaymentStatus({ - id: PaymentIntentDataByStatus.REQUIRE_PAYMENT_METHOD.id + id: PaymentIntentDataByStatus.REQUIRE_PAYMENT_METHOD.id, }) expect(status).toBe(PaymentSessionStatus.PENDING) status = await stripeTest.getPaymentStatus({ - id: PaymentIntentDataByStatus.REQUIRES_CONFIRMATION.id + id: PaymentIntentDataByStatus.REQUIRES_CONFIRMATION.id, }) expect(status).toBe(PaymentSessionStatus.PENDING) status = await stripeTest.getPaymentStatus({ - id: PaymentIntentDataByStatus.PROCESSING.id + id: PaymentIntentDataByStatus.PROCESSING.id, }) expect(status).toBe(PaymentSessionStatus.PENDING) status = await stripeTest.getPaymentStatus({ - id: PaymentIntentDataByStatus.REQUIRES_ACTION.id + id: PaymentIntentDataByStatus.REQUIRES_ACTION.id, }) expect(status).toBe(PaymentSessionStatus.REQUIRES_MORE) status = await stripeTest.getPaymentStatus({ - id: PaymentIntentDataByStatus.CANCELED.id + id: PaymentIntentDataByStatus.CANCELED.id, }) expect(status).toBe(PaymentSessionStatus.CANCELED) status = await stripeTest.getPaymentStatus({ - id: PaymentIntentDataByStatus.REQUIRES_CAPTURE.id + id: PaymentIntentDataByStatus.REQUIRES_CAPTURE.id, }) expect(status).toBe(PaymentSessionStatus.AUTHORIZED) status = await stripeTest.getPaymentStatus({ - id: PaymentIntentDataByStatus.SUCCEEDED.id + id: PaymentIntentDataByStatus.SUCCEEDED.id, }) expect(status).toBe(PaymentSessionStatus.AUTHORIZED) status = await stripeTest.getPaymentStatus({ - id: "unknown-id" + id: "unknown-id", }) expect(status).toBe(PaymentSessionStatus.PENDING) }) }) - describe('initiatePayment', function () { + describe("initiatePayment", function () { let stripeTest beforeAll(async () => { @@ -109,11 +109,13 @@ describe("StripeTest", () => { }) it("should succeed with an existing customer but no stripe id", async () => { - const result = await stripeTest.initiatePayment(initiatePaymentContextWithExistingCustomer) + const result = await stripeTest.initiatePayment( + initiatePaymentContextWithExistingCustomer + ) expect(StripeMock.customers.create).toHaveBeenCalled() expect(StripeMock.customers.create).toHaveBeenCalledWith({ - email: initiatePaymentContextWithExistingCustomer.email + email: initiatePaymentContextWithExistingCustomer.email, }) expect(StripeMock.paymentIntents.create).toHaveBeenCalled() @@ -122,8 +124,10 @@ describe("StripeTest", () => { description: undefined, amount: initiatePaymentContextWithExistingCustomer.amount, currency: initiatePaymentContextWithExistingCustomer.currency_code, - metadata: { resource_id: initiatePaymentContextWithExistingCustomer.resource_id }, - capture_method: "manual" + metadata: { + resource_id: initiatePaymentContextWithExistingCustomer.resource_id, + }, + capture_method: "manual", }) ) @@ -132,15 +136,17 @@ describe("StripeTest", () => { session_data: expect.any(Object), update_requests: { customer_metadata: { - stripe_id: STRIPE_ID - } - } + stripe_id: STRIPE_ID, + }, + }, }) ) }) it("should succeed with an existing customer with an existing stripe id", async () => { - const result = await stripeTest.initiatePayment(initiatePaymentContextWithExistingCustomerStripeId) + const result = await stripeTest.initiatePayment( + initiatePaymentContextWithExistingCustomerStripeId + ) expect(StripeMock.customers.create).not.toHaveBeenCalled() @@ -150,64 +156,77 @@ describe("StripeTest", () => { description: undefined, amount: initiatePaymentContextWithExistingCustomer.amount, currency: initiatePaymentContextWithExistingCustomer.currency_code, - metadata: { resource_id: initiatePaymentContextWithExistingCustomer.resource_id }, - capture_method: "manual" + metadata: { + resource_id: initiatePaymentContextWithExistingCustomer.resource_id, + }, + capture_method: "manual", }) ) expect(result).toEqual( expect.objectContaining({ session_data: expect.any(Object), - update_requests: undefined + update_requests: undefined, }) ) }) it("should fail on customer creation", async () => { - const result = await stripeTest.initiatePayment(initiatePaymentContextWithWrongEmail) + const result = await stripeTest.initiatePayment( + initiatePaymentContextWithWrongEmail + ) expect(StripeMock.customers.create).toHaveBeenCalled() expect(StripeMock.customers.create).toHaveBeenCalledWith({ - email: initiatePaymentContextWithWrongEmail.email + email: initiatePaymentContextWithWrongEmail.email, }) expect(StripeMock.paymentIntents.create).not.toHaveBeenCalled() expect(result).toEqual({ - error: "An error occurred in InitiatePayment during the creation of the stripe customer", + error: + "An error occurred in InitiatePayment during the creation of the stripe customer", code: "", - detail: "Error" + detail: "Error", }) }) it("should fail on payment intents creation", async () => { - const result = await stripeTest.initiatePayment(initiatePaymentContextWithFailIntentCreation) + const result = await stripeTest.initiatePayment( + initiatePaymentContextWithFailIntentCreation + ) expect(StripeMock.customers.create).toHaveBeenCalled() expect(StripeMock.customers.create).toHaveBeenCalledWith({ - email: initiatePaymentContextWithFailIntentCreation.email + email: initiatePaymentContextWithFailIntentCreation.email, }) expect(StripeMock.paymentIntents.create).toHaveBeenCalled() expect(StripeMock.paymentIntents.create).toHaveBeenCalledWith( expect.objectContaining({ - description: initiatePaymentContextWithFailIntentCreation.context.payment_description, + description: + initiatePaymentContextWithFailIntentCreation.context + .payment_description, amount: initiatePaymentContextWithFailIntentCreation.amount, currency: initiatePaymentContextWithFailIntentCreation.currency_code, - metadata: { resource_id: initiatePaymentContextWithFailIntentCreation.resource_id }, - capture_method: "manual" + metadata: { + resource_id: + initiatePaymentContextWithFailIntentCreation.resource_id, + }, + capture_method: "manual", }) ) expect(result).toEqual({ - error: "An error occurred in InitiatePayment during the creation of the stripe payment intent", + error: + "An error occurred in InitiatePayment during the creation of the stripe payment intent", code: "", - detail: "Error" + detail: "Error", }) }) }) - describe('authorizePayment', function () { + describe("authorizePayment", function () { let stripeTest beforeAll(async () => { @@ -221,16 +240,18 @@ describe("StripeTest", () => { }) it("should succeed", async () => { - const result = await stripeTest.authorizePayment(authorizePaymentSuccessData) + const result = await stripeTest.authorizePayment( + authorizePaymentSuccessData + ) expect(result).toEqual({ data: authorizePaymentSuccessData, - status: PaymentSessionStatus.AUTHORIZED + status: PaymentSessionStatus.AUTHORIZED, }) }) }) - describe('cancelPayment', function () { + describe("cancelPayment", function () { let stripeTest beforeAll(async () => { @@ -247,16 +268,18 @@ describe("StripeTest", () => { const result = await stripeTest.cancelPayment(cancelPaymentSuccessData) expect(result).toEqual({ - id: PaymentIntentDataByStatus.SUCCEEDED.id + id: PaymentIntentDataByStatus.SUCCEEDED.id, }) }) it("should fail on intent cancellation but still return the intent", async () => { - const result = await stripeTest.cancelPayment(cancelPaymentPartiallyFailData) + const result = await stripeTest.cancelPayment( + cancelPaymentPartiallyFailData + ) expect(result).toEqual({ id: PARTIALLY_FAIL_INTENT_ID, - status: ErrorIntentStatus.CANCELED + status: ErrorIntentStatus.CANCELED, }) }) @@ -264,14 +287,15 @@ describe("StripeTest", () => { const result = await stripeTest.cancelPayment(cancelPaymentFailData) expect(result).toEqual({ - error: "An error occurred in cancelPayment during the cancellation of the payment", + error: + "An error occurred in cancelPayment during the cancellation of the payment", code: "", - detail: "Error" + detail: "Error", }) }) }) - describe('capturePayment', function () { + describe("capturePayment", function () { let stripeTest beforeAll(async () => { @@ -285,34 +309,41 @@ describe("StripeTest", () => { }) it("should succeed", async () => { - const result = await stripeTest.capturePayment(capturePaymentContextSuccessData) + const result = await stripeTest.capturePayment( + capturePaymentContextSuccessData + ) expect(result).toEqual({ - id: PaymentIntentDataByStatus.SUCCEEDED.id + id: PaymentIntentDataByStatus.SUCCEEDED.id, }) }) it("should fail on intent capture but still return the intent", async () => { - const result = await stripeTest.capturePayment(capturePaymentContextPartiallyFailData) + const result = await stripeTest.capturePayment( + capturePaymentContextPartiallyFailData + ) expect(result).toEqual({ id: PARTIALLY_FAIL_INTENT_ID, - status: ErrorIntentStatus.SUCCEEDED + status: ErrorIntentStatus.SUCCEEDED, }) }) it("should fail on intent capture", async () => { - const result = await stripeTest.capturePayment(capturePaymentContextFailData) + const result = await stripeTest.capturePayment( + capturePaymentContextFailData + ) expect(result).toEqual({ - error: "An error occurred in deletePayment during the capture of the payment", + error: + "An error occurred in deletePayment during the capture of the payment", code: "", - detail: "Error" + detail: "Error", }) }) }) - describe('deletePayment', function () { + describe("deletePayment", function () { let stripeTest beforeAll(async () => { @@ -329,16 +360,18 @@ describe("StripeTest", () => { const result = await stripeTest.cancelPayment(deletePaymentSuccessData) expect(result).toEqual({ - id: PaymentIntentDataByStatus.SUCCEEDED.id + id: PaymentIntentDataByStatus.SUCCEEDED.id, }) }) it("should fail on intent cancellation but still return the intent", async () => { - const result = await stripeTest.cancelPayment(deletePaymentPartiallyFailData) + const result = await stripeTest.cancelPayment( + deletePaymentPartiallyFailData + ) expect(result).toEqual({ id: PARTIALLY_FAIL_INTENT_ID, - status: ErrorIntentStatus.CANCELED + status: ErrorIntentStatus.CANCELED, }) }) @@ -346,14 +379,15 @@ describe("StripeTest", () => { const result = await stripeTest.cancelPayment(deletePaymentFailData) expect(result).toEqual({ - error: "An error occurred in cancelPayment during the cancellation of the payment", + error: + "An error occurred in cancelPayment during the cancellation of the payment", code: "", - detail: "Error" + detail: "Error", }) }) }) - describe('refundPayment', function () { + describe("refundPayment", function () { let stripeTest const refundAmount = 500 @@ -368,25 +402,31 @@ describe("StripeTest", () => { }) it("should succeed", async () => { - const result = await stripeTest.refundPayment(refundPaymentSuccessData, refundAmount) + const result = await stripeTest.refundPayment( + refundPaymentSuccessData, + refundAmount + ) expect(result).toEqual({ - id: PaymentIntentDataByStatus.SUCCEEDED.id + id: PaymentIntentDataByStatus.SUCCEEDED.id, }) }) it("should fail on refund creation", async () => { - const result = await stripeTest.refundPayment(refundPaymentFailData, refundAmount) + const result = await stripeTest.refundPayment( + refundPaymentFailData, + refundAmount + ) expect(result).toEqual({ error: "An error occurred in refundPayment during the refundPayment", code: "", - detail: "Error" + detail: "Error", }) }) }) - describe('retrievePayment', function () { + describe("retrievePayment", function () { let stripeTest beforeAll(async () => { @@ -400,11 +440,13 @@ describe("StripeTest", () => { }) it("should succeed", async () => { - const result = await stripeTest.retrievePayment(retrievePaymentSuccessData) + const result = await stripeTest.retrievePayment( + retrievePaymentSuccessData + ) expect(result).toEqual({ id: PaymentIntentDataByStatus.SUCCEEDED.id, - status: PaymentIntentDataByStatus.SUCCEEDED.status + status: PaymentIntentDataByStatus.SUCCEEDED.status, }) }) @@ -414,12 +456,12 @@ describe("StripeTest", () => { expect(result).toEqual({ error: "An error occurred in retrievePayment", code: "", - detail: "Error" + detail: "Error", }) }) }) - describe('updatePayment', function () { + describe("updatePayment", function () { let stripeTest beforeAll(async () => { @@ -433,11 +475,13 @@ describe("StripeTest", () => { }) it("should succeed to initiate a payment with an existing customer but no stripe id", async () => { - const result = await stripeTest.updatePayment(updatePaymentContextWithExistingCustomer) + const result = await stripeTest.updatePayment( + updatePaymentContextWithExistingCustomer + ) expect(StripeMock.customers.create).toHaveBeenCalled() expect(StripeMock.customers.create).toHaveBeenCalledWith({ - email: updatePaymentContextWithExistingCustomer.email + email: updatePaymentContextWithExistingCustomer.email, }) expect(StripeMock.paymentIntents.create).toHaveBeenCalled() @@ -446,8 +490,10 @@ describe("StripeTest", () => { description: undefined, amount: updatePaymentContextWithExistingCustomer.amount, currency: updatePaymentContextWithExistingCustomer.currency_code, - metadata: { resource_id: updatePaymentContextWithExistingCustomer.resource_id }, - capture_method: "manual" + metadata: { + resource_id: updatePaymentContextWithExistingCustomer.resource_id, + }, + capture_method: "manual", }) ) @@ -456,32 +502,40 @@ describe("StripeTest", () => { session_data: expect.any(Object), update_requests: { customer_metadata: { - stripe_id: STRIPE_ID - } - } + stripe_id: STRIPE_ID, + }, + }, }) ) }) it("should fail to initiate a payment with an existing customer but no stripe id", async () => { - const result = await stripeTest.updatePayment(updatePaymentContextWithWrongEmail) + const result = await stripeTest.updatePayment( + updatePaymentContextWithWrongEmail + ) expect(StripeMock.customers.create).toHaveBeenCalled() expect(StripeMock.customers.create).toHaveBeenCalledWith({ - email: updatePaymentContextWithWrongEmail.email + email: updatePaymentContextWithWrongEmail.email, }) expect(StripeMock.paymentIntents.create).not.toHaveBeenCalled() expect(result).toEqual({ - error: "An error occurred in updatePayment during the initiate of the new payment for the new customer", + error: + "An error occurred in updatePayment during the initiate of the new payment for the new customer", code: "", - detail: "An error occurred in InitiatePayment during the creation of the stripe customer" + EOL + "Error" + detail: + "An error occurred in InitiatePayment during the creation of the stripe customer" + + EOL + + "Error", }) }) it("should succeed but no update occurs when the amount did not changed", async () => { - const result = await stripeTest.updatePayment(updatePaymentContextWithExistingCustomerStripeId) + const result = await stripeTest.updatePayment( + updatePaymentContextWithExistingCustomerStripeId + ) expect(StripeMock.paymentIntents.update).not.toHaveBeenCalled() @@ -489,38 +543,43 @@ describe("StripeTest", () => { }) it("should succeed to update the intent with the new amount", async () => { - const result = await stripeTest.updatePayment(updatePaymentContextWithDifferentAmount) + const result = await stripeTest.updatePayment( + updatePaymentContextWithDifferentAmount + ) expect(StripeMock.paymentIntents.update).toHaveBeenCalled() expect(StripeMock.paymentIntents.update).toHaveBeenCalledWith( - updatePaymentContextWithDifferentAmount.paymentSessionData.id , + updatePaymentContextWithDifferentAmount.paymentSessionData.id, { - amount: updatePaymentContextWithDifferentAmount.amount + amount: updatePaymentContextWithDifferentAmount.amount, } ) expect(result).toEqual({ session_data: expect.objectContaining({ amount: updatePaymentContextWithDifferentAmount.amount, - }) + }), }) }) it("should fail to update the intent with the new amount", async () => { - const result = await stripeTest.updatePayment(updatePaymentContextFailWithDifferentAmount) + const result = await stripeTest.updatePayment( + updatePaymentContextFailWithDifferentAmount + ) expect(StripeMock.paymentIntents.update).toHaveBeenCalled() expect(StripeMock.paymentIntents.update).toHaveBeenCalledWith( - updatePaymentContextFailWithDifferentAmount.paymentSessionData.id , + updatePaymentContextFailWithDifferentAmount.paymentSessionData.id, { - amount: updatePaymentContextFailWithDifferentAmount.amount + amount: updatePaymentContextFailWithDifferentAmount.amount, } ) expect(result).toEqual({ - error: "An error occurred in updatePayment during the update of the payment", + error: + "An error occurred in updatePayment during the update of the payment", code: "", - detail: "Error" + detail: "Error", }) }) }) From 02cac3c21fa7979e2f03603a86672be25bca0132 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Thu, 23 Feb 2023 13:22:26 +0100 Subject: [PATCH 25/36] readme + cleanup --- packages/medusa-payment-stripe/README.md | 6 +++++- packages/medusa-payment-stripe/src/api/hooks/stripe.ts | 2 +- packages/medusa-payment-stripe/tsconfig.json | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/medusa-payment-stripe/README.md b/packages/medusa-payment-stripe/README.md index bd90a6a5bf8eb..c685ca46ab30a 100644 --- a/packages/medusa-payment-stripe/README.md +++ b/packages/medusa-payment-stripe/README.md @@ -10,7 +10,11 @@ Learn more about how you can use this plugin in the [documentaion](https://docs. { api_key: "STRIPE_API_KEY", webhook_secret: "STRIPE_WEBHOOK_SECRET", - automatic_payment_methods: true + + // automatic_payment_methods: true, + + // This description will be used if the cart context does not provide one. + // payment_description: "custom description to apply", } ``` diff --git a/packages/medusa-payment-stripe/src/api/hooks/stripe.ts b/packages/medusa-payment-stripe/src/api/hooks/stripe.ts index 1c7454e0d2cce..ab834295dd7af 100644 --- a/packages/medusa-payment-stripe/src/api/hooks/stripe.ts +++ b/packages/medusa-payment-stripe/src/api/hooks/stripe.ts @@ -138,7 +138,7 @@ async function paymentIntentAmountCapturableEventHandler({ throw new MedusaError( MedusaError.Types.UNEXPECTED_STATE, "Failed to create idempotency key", - "409" + "400" ) } diff --git a/packages/medusa-payment-stripe/tsconfig.json b/packages/medusa-payment-stripe/tsconfig.json index babbc0f28482e..5043999ee2469 100644 --- a/packages/medusa-payment-stripe/tsconfig.json +++ b/packages/medusa-payment-stripe/tsconfig.json @@ -30,4 +30,4 @@ "src/**/__fixtures__", "node_modules" ] -} \ No newline at end of file +} From b094efc038a11263d5b4f25f98e6e74616645fb6 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Mon, 27 Feb 2023 14:45:49 +0100 Subject: [PATCH 26/36] chore: feedback and cleanup --- .../medusa-payment-stripe/__mocks__/cart.js | 195 +++++ .../__mocks__/customer.js | 45 + .../__mocks__/eventbus.js | 16 + .../medusa-payment-stripe/__mocks__/stripe.js | 98 +++ .../medusa-payment-stripe/__mocks__/totals.js | 15 + packages/medusa-payment-stripe/api/index.js | 20 + .../api/middlewares/await-middleware.js | 14 + .../api/middlewares/index.js | 15 + .../api/routes/hooks/index.js | 27 + .../api/routes/hooks/stripe.js | 348 ++++++++ .../helpers/stripe-base.js | 772 ++++++++++++++++++ .../services/__mocks__/stripe-provider.js | 63 ++ .../services/stripe-bancontact.js | 65 ++ .../services/stripe-blik.js | 65 ++ .../services/stripe-giropay.js | 65 ++ .../services/stripe-ideal.js | 65 ++ .../services/stripe-provider.js | 62 ++ .../services/stripe-przelewy24.js | 65 ++ .../src/__fixtures__/data.ts | 2 +- .../src/api/hooks/index.ts | 4 +- .../src/api/hooks/stripe.ts | 145 +--- .../src/api/utils/utils.ts | 221 ++++- .../src/core/__tests__/stripe-base.spec.ts | 2 +- .../medusa-payment-stripe/subscribers/cart.js | 125 +++ packages/medusa/src/api/middlewares/index.ts | 12 + packages/medusa/src/index.js | 1 + 26 files changed, 2375 insertions(+), 152 deletions(-) create mode 100644 packages/medusa-payment-stripe/__mocks__/cart.js create mode 100644 packages/medusa-payment-stripe/__mocks__/customer.js create mode 100644 packages/medusa-payment-stripe/__mocks__/eventbus.js create mode 100644 packages/medusa-payment-stripe/__mocks__/stripe.js create mode 100644 packages/medusa-payment-stripe/__mocks__/totals.js create mode 100644 packages/medusa-payment-stripe/api/index.js create mode 100644 packages/medusa-payment-stripe/api/middlewares/await-middleware.js create mode 100644 packages/medusa-payment-stripe/api/middlewares/index.js create mode 100644 packages/medusa-payment-stripe/api/routes/hooks/index.js create mode 100644 packages/medusa-payment-stripe/api/routes/hooks/stripe.js create mode 100644 packages/medusa-payment-stripe/helpers/stripe-base.js create mode 100644 packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js create mode 100644 packages/medusa-payment-stripe/services/stripe-bancontact.js create mode 100644 packages/medusa-payment-stripe/services/stripe-blik.js create mode 100644 packages/medusa-payment-stripe/services/stripe-giropay.js create mode 100644 packages/medusa-payment-stripe/services/stripe-ideal.js create mode 100644 packages/medusa-payment-stripe/services/stripe-provider.js create mode 100644 packages/medusa-payment-stripe/services/stripe-przelewy24.js create mode 100644 packages/medusa-payment-stripe/subscribers/cart.js diff --git a/packages/medusa-payment-stripe/__mocks__/cart.js b/packages/medusa-payment-stripe/__mocks__/cart.js new file mode 100644 index 0000000000000..eebabc2ef0bd5 --- /dev/null +++ b/packages/medusa-payment-stripe/__mocks__/cart.js @@ -0,0 +1,195 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.carts = exports.CartServiceMock = void 0; + +var _medusaTestUtils = require("medusa-test-utils"); + +var carts = { + emptyCart: { + id: _medusaTestUtils.IdMap.getId("emptyCart"), + items: [], + region_id: _medusaTestUtils.IdMap.getId("testRegion"), + customer_id: "test-customer", + payment_sessions: [], + shipping_options: [{ + id: _medusaTestUtils.IdMap.getId("freeShipping"), + profile_id: "default_profile", + data: { + some_data: "yes" + } + }] + }, + frCart: { + id: _medusaTestUtils.IdMap.getId("fr-cart"), + email: "lebron@james.com", + title: "test", + region_id: _medusaTestUtils.IdMap.getId("region-france"), + items: [{ + id: _medusaTestUtils.IdMap.getId("line"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + unit_price: 8, + variant: { + id: _medusaTestUtils.IdMap.getId("eur-8-us-10") + }, + product: { + id: _medusaTestUtils.IdMap.getId("product") + }, + // { + // unit_price: 10, + // variant: { + // id: IdMap.getId("eur-10-us-12"), + // }, + // product: { + // id: IdMap.getId("product"), + // }, + // quantity: 1, + // }, + quantity: 10 + }, { + id: _medusaTestUtils.IdMap.getId("existingLine"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + unit_price: 10, + variant: { + id: _medusaTestUtils.IdMap.getId("eur-10-us-12") + }, + product: { + id: _medusaTestUtils.IdMap.getId("product") + }, + quantity: 1 + }], + shipping_methods: [{ + id: _medusaTestUtils.IdMap.getId("freeShipping"), + profile_id: "default_profile" + }], + shipping_options: [{ + id: _medusaTestUtils.IdMap.getId("freeShipping"), + profile_id: "default_profile" + }], + payment_sessions: [{ + provider_id: "stripe", + data: { + id: "pi_123456789", + customer: _medusaTestUtils.IdMap.getId("not-lebron") + } + }], + payment_method: { + provider_id: "stripe", + data: { + id: "pi_123456789", + customer: _medusaTestUtils.IdMap.getId("not-lebron") + } + }, + shipping_address: {}, + billing_address: {}, + discounts: [], + customer_id: _medusaTestUtils.IdMap.getId("lebron"), + context: {} + }, + frCartNoStripeCustomer: { + id: _medusaTestUtils.IdMap.getId("fr-cart-no-customer"), + title: "test", + region_id: _medusaTestUtils.IdMap.getId("region-france"), + items: [{ + id: _medusaTestUtils.IdMap.getId("line"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + content: [{ + unit_price: 8, + variant: { + id: _medusaTestUtils.IdMap.getId("eur-8-us-10") + }, + product: { + id: _medusaTestUtils.IdMap.getId("product") + }, + quantity: 1 + }, { + unit_price: 10, + variant: { + id: _medusaTestUtils.IdMap.getId("eur-10-us-12") + }, + product: { + id: _medusaTestUtils.IdMap.getId("product") + }, + quantity: 1 + }], + quantity: 10 + }, { + id: _medusaTestUtils.IdMap.getId("existingLine"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + content: { + unit_price: 10, + variant: { + id: _medusaTestUtils.IdMap.getId("eur-10-us-12") + }, + product: { + id: _medusaTestUtils.IdMap.getId("product") + }, + quantity: 1 + }, + quantity: 10 + }], + shipping_methods: [{ + id: _medusaTestUtils.IdMap.getId("freeShipping"), + profile_id: "default_profile" + }], + shipping_options: [{ + id: _medusaTestUtils.IdMap.getId("freeShipping"), + profile_id: "default_profile" + }], + payment_sessions: [{ + provider_id: "stripe", + data: { + id: "pi_no", + customer: _medusaTestUtils.IdMap.getId("not-lebron") + } + }], + payment_method: { + provider_id: "stripe", + data: { + id: "pi_no", + customer: _medusaTestUtils.IdMap.getId("not-lebron") + } + }, + shipping_address: {}, + billing_address: {}, + discounts: [], + customer_id: _medusaTestUtils.IdMap.getId("vvd") + } +}; +exports.carts = carts; +var CartServiceMock = { + retrieve: jest.fn().mockImplementation(function (cartId) { + if (cartId === _medusaTestUtils.IdMap.getId("fr-cart")) { + return Promise.resolve(carts.frCart); + } + + if (cartId === _medusaTestUtils.IdMap.getId("fr-cart-no-customer")) { + return Promise.resolve(carts.frCartNoStripeCustomer); + } + + if (cartId === _medusaTestUtils.IdMap.getId("emptyCart")) { + return Promise.resolve(carts.emptyCart); + } + + return Promise.resolve(undefined); + }), + updatePaymentSession: jest.fn().mockImplementation(function (cartId, stripe, paymentIntent) { + return Promise.resolve(); + }) +}; +exports.CartServiceMock = CartServiceMock; +var mock = jest.fn().mockImplementation(function () { + return CartServiceMock; +}); +var _default = mock; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/customer.js b/packages/medusa-payment-stripe/__mocks__/customer.js new file mode 100644 index 0000000000000..72cd299080511 --- /dev/null +++ b/packages/medusa-payment-stripe/__mocks__/customer.js @@ -0,0 +1,45 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.CustomerServiceMock = void 0; + +var _medusaTestUtils = require("medusa-test-utils"); + +var CustomerServiceMock = { + retrieve: jest.fn().mockImplementation(function (id) { + if (id === _medusaTestUtils.IdMap.getId("lebron")) { + return Promise.resolve({ + _id: _medusaTestUtils.IdMap.getId("lebron"), + first_name: "LeBron", + last_name: "James", + email: "lebron@james.com", + password_hash: "1234", + metadata: { + stripe_id: "cus_123456789_new" + } + }); + } + + if (id === _medusaTestUtils.IdMap.getId("vvd")) { + return Promise.resolve({ + _id: _medusaTestUtils.IdMap.getId("vvd"), + first_name: "Virgil", + last_name: "Van Dijk", + email: "virg@vvd.com", + password_hash: "1234", + metadata: {} + }); + } + + return Promise.resolve(undefined); + }), + setMetadata: jest.fn().mockReturnValue(Promise.resolve()) +}; +exports.CustomerServiceMock = CustomerServiceMock; +var mock = jest.fn().mockImplementation(function () { + return CustomerServiceMock; +}); +var _default = mock; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/eventbus.js b/packages/medusa-payment-stripe/__mocks__/eventbus.js new file mode 100644 index 0000000000000..b445554189888 --- /dev/null +++ b/packages/medusa-payment-stripe/__mocks__/eventbus.js @@ -0,0 +1,16 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.EventBusServiceMock = void 0; +var EventBusServiceMock = { + emit: jest.fn(), + subscribe: jest.fn() +}; +exports.EventBusServiceMock = EventBusServiceMock; +var mock = jest.fn().mockImplementation(function () { + return EventBusServiceMock; +}); +var _default = mock; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/stripe.js b/packages/medusa-payment-stripe/__mocks__/stripe.js new file mode 100644 index 0000000000000..df9dbbb98c267 --- /dev/null +++ b/packages/medusa-payment-stripe/__mocks__/stripe.js @@ -0,0 +1,98 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.StripeMock = void 0; +var StripeMock = { + customers: { + create: jest.fn().mockImplementation(function (data) { + if (data.email === "virg@vvd.com") { + return Promise.resolve({ + id: "cus_vvd", + email: "virg@vvd.com" + }); + } + + if (data.email === "lebron@james.com") { + return Promise.resolve({ + id: "cus_lebron", + email: "lebron@james.com" + }); + } + }) + }, + paymentIntents: { + create: jest.fn().mockImplementation(function (data) { + if (data.customer === "cus_123456789_new") { + return Promise.resolve({ + id: "pi_lebron", + amount: 100, + customer: "cus_123456789_new", + description: data === null || data === void 0 ? void 0 : data.description + }); + } + + if (data.customer === "cus_lebron") { + return Promise.resolve({ + id: "pi_lebron", + amount: 100, + customer: "cus_lebron", + description: data === null || data === void 0 ? void 0 : data.description + }); + } + }), + retrieve: jest.fn().mockImplementation(function (data) { + return Promise.resolve({ + id: "pi_lebron", + customer: "cus_lebron" + }); + }), + update: jest.fn().mockImplementation(function (pi, data) { + if (data.customer === "cus_lebron_2") { + return Promise.resolve({ + id: "pi_lebron", + customer: "cus_lebron_2", + amount: 1000 + }); + } + + return Promise.resolve({ + id: "pi_lebron", + customer: "cus_lebron", + amount: 1000 + }); + }), + capture: jest.fn().mockImplementation(function (data) { + return Promise.resolve({ + id: "pi_lebron", + customer: "cus_lebron", + amount: 1000, + status: "succeeded" + }); + }), + cancel: jest.fn().mockImplementation(function (data) { + return Promise.resolve({ + id: "pi_lebron", + customer: "cus_lebron", + status: "cancelled" + }); + }) + }, + refunds: { + create: jest.fn().mockImplementation(function (data) { + return Promise.resolve({ + id: "re_123", + payment_intent: "pi_lebron", + amount: 1000, + status: "succeeded" + }); + }) + } +}; +exports.StripeMock = StripeMock; +var stripe = jest.fn(function () { + return StripeMock; +}); +var _default = stripe; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/totals.js b/packages/medusa-payment-stripe/__mocks__/totals.js new file mode 100644 index 0000000000000..576d1231e94a1 --- /dev/null +++ b/packages/medusa-payment-stripe/__mocks__/totals.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.TotalsServiceMock = void 0; +var TotalsServiceMock = { + getTotal: jest.fn() +}; +exports.TotalsServiceMock = TotalsServiceMock; +var mock = jest.fn().mockImplementation(function () { + return TotalsServiceMock; +}); +var _default = mock; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/index.js b/packages/medusa-payment-stripe/api/index.js new file mode 100644 index 0000000000000..20411274f2adc --- /dev/null +++ b/packages/medusa-payment-stripe/api/index.js @@ -0,0 +1,20 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _express = require("express"); + +var _hooks = _interopRequireDefault(require("./routes/hooks")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +var _default = function _default(container) { + var app = (0, _express.Router)(); + (0, _hooks["default"])(app); + return app; +}; + +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/middlewares/await-middleware.js b/packages/medusa-payment-stripe/api/middlewares/await-middleware.js new file mode 100644 index 0000000000000..36ee66cf7eb15 --- /dev/null +++ b/packages/medusa-payment-stripe/api/middlewares/await-middleware.js @@ -0,0 +1,14 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _default = function _default(fn) { + return function () { + return fn.apply(void 0, arguments)["catch"](arguments.length <= 2 ? undefined : arguments[2]); + }; +}; + +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/middlewares/index.js b/packages/medusa-payment-stripe/api/middlewares/index.js new file mode 100644 index 0000000000000..1d5f479eb7e89 --- /dev/null +++ b/packages/medusa-payment-stripe/api/middlewares/index.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _awaitMiddleware = _interopRequireDefault(require("./await-middleware")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +var _default = { + wrap: _awaitMiddleware["default"] +}; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/routes/hooks/index.js b/packages/medusa-payment-stripe/api/routes/hooks/index.js new file mode 100644 index 0000000000000..d18bf49c71547 --- /dev/null +++ b/packages/medusa-payment-stripe/api/routes/hooks/index.js @@ -0,0 +1,27 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _express = require("express"); + +var _bodyParser = _interopRequireDefault(require("body-parser")); + +var _middlewares = _interopRequireDefault(require("../../middlewares")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +var route = (0, _express.Router)(); + +var _default = function _default(app) { + app.use("/stripe", route); + route.post("/hooks", // stripe constructEvent fails without body-parser + _bodyParser["default"].raw({ + type: "application/json" + }), _middlewares["default"].wrap(require("./stripe")["default"])); + return app; +}; + +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/routes/hooks/stripe.js b/packages/medusa-payment-stripe/api/routes/hooks/stripe.js new file mode 100644 index 0000000000000..2b0b08b4dde27 --- /dev/null +++ b/packages/medusa-payment-stripe/api/routes/hooks/stripe.js @@ -0,0 +1,348 @@ +"use strict"; + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _utils = require("@medusajs/medusa/dist/utils"); + +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +var _default = /*#__PURE__*/function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(req, res) { + var signature, event, stripeProviderService, isPaymentCollection, handleCartPayments, _handleCartPayments, handlePaymentCollection, _handlePaymentCollection, paymentIntent, cartId, resourceId; + + return _regeneratorRuntime().wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + _handlePaymentCollection = function _handlePaymentCollect2() { + _handlePaymentCollection = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(event, req, res, id, paymentIntentId) { + var _paycol$payments; + + var manager, paymentCollectionService, paycol, payment; + return _regeneratorRuntime().wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + manager = req.scope.resolve("manager"); + paymentCollectionService = req.scope.resolve("paymentCollectionService"); + _context5.next = 4; + return paymentCollectionService.retrieve(id, { + relations: ["payments"] + })["catch"](function () { + return undefined; + }); + + case 4: + paycol = _context5.sent; + + if (!(paycol !== null && paycol !== void 0 && (_paycol$payments = paycol.payments) !== null && _paycol$payments !== void 0 && _paycol$payments.length)) { + _context5.next = 13; + break; + } + + if (!(event.type === "payment_intent.succeeded")) { + _context5.next = 13; + break; + } + + payment = paycol.payments.find(function (pay) { + return pay.data.id === paymentIntentId; + }); + + if (!(payment && !payment.captured_at)) { + _context5.next = 11; + break; + } + + _context5.next = 11; + return manager.transaction( /*#__PURE__*/function () { + var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(manager) { + return _regeneratorRuntime().wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return paymentCollectionService.withTransaction(manager).capture(payment.id); + + case 2: + case "end": + return _context4.stop(); + } + } + }, _callee4); + })); + + return function (_x14) { + return _ref4.apply(this, arguments); + }; + }()); + + case 11: + res.sendStatus(200); + return _context5.abrupt("return"); + + case 13: + res.sendStatus(204); + + case 14: + case "end": + return _context5.stop(); + } + } + }, _callee5); + })); + return _handlePaymentCollection.apply(this, arguments); + }; + + handlePaymentCollection = function _handlePaymentCollect(_x7, _x8, _x9, _x10, _x11) { + return _handlePaymentCollection.apply(this, arguments); + }; + + _handleCartPayments = function _handleCartPayments3() { + _handleCartPayments = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(event, req, res, cartId) { + var manager, orderService, order, _err$detail, message, _err$detail2; + + return _regeneratorRuntime().wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + manager = req.scope.resolve("manager"); + orderService = req.scope.resolve("orderService"); + _context3.next = 4; + return orderService.retrieveByCartId(cartId)["catch"](function () { + return undefined; + }); + + case 4: + order = _context3.sent; + _context3.t0 = event.type; + _context3.next = _context3.t0 === "payment_intent.succeeded" ? 8 : _context3.t0 === "payment_intent.amount_capturable_updated" ? 19 : 31; + break; + + case 8: + if (!order) { + _context3.next = 17; + break; + } + + if (!(order.payment_status !== "captured")) { + _context3.next = 14; + break; + } + + _context3.next = 12; + return manager.transaction( /*#__PURE__*/function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(manager) { + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return orderService.withTransaction(manager).capturePayment(order.id); + + case 2: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + + return function (_x12) { + return _ref2.apply(this, arguments); + }; + }()); + + case 12: + _context3.next = 15; + break; + + case 14: + return _context3.abrupt("return", res.sendStatus(200)); + + case 15: + _context3.next = 18; + break; + + case 17: + return _context3.abrupt("return", res.sendStatus(404)); + + case 18: + return _context3.abrupt("break", 33); + + case 19: + _context3.prev = 19; + _context3.next = 22; + return manager.transaction( /*#__PURE__*/function () { + var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(manager) { + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return paymentIntentAmountCapturableEventHandler({ + order: order, + cartId: cartId, + container: req.scope, + transactionManager: manager + }); + + case 2: + case "end": + return _context2.stop(); + } + } + }, _callee2); + })); + + return function (_x13) { + return _ref3.apply(this, arguments); + }; + }()); + + case 22: + _context3.next = 30; + break; + + case 24: + _context3.prev = 24; + _context3.t1 = _context3["catch"](19); + message = "Stripe webhook ".concat(event, " handling failed\n").concat((_err$detail = _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.detail) !== null && _err$detail !== void 0 ? _err$detail : _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.message); + + if ((_context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.code) === _utils.PostgresError.SERIALIZATION_FAILURE) { + message = "Stripe webhook ".concat(event, " handle failed. This can happen when this webhook is triggered during a cart completion and can be ignored. This event should be retried automatically.\n").concat((_err$detail2 = _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.detail) !== null && _err$detail2 !== void 0 ? _err$detail2 : _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.message); + } + + this.logger_.warn(message); + return _context3.abrupt("return", res.sendStatus(409)); + + case 30: + return _context3.abrupt("break", 33); + + case 31: + res.sendStatus(204); + return _context3.abrupt("return"); + + case 33: + res.sendStatus(200); + + case 34: + case "end": + return _context3.stop(); + } + } + }, _callee3, this, [[19, 24]]); + })); + return _handleCartPayments.apply(this, arguments); + }; + + handleCartPayments = function _handleCartPayments2(_x3, _x4, _x5, _x6) { + return _handleCartPayments.apply(this, arguments); + }; + + isPaymentCollection = function _isPaymentCollection(id) { + return id && id.startsWith("paycol"); + }; + + signature = req.headers["stripe-signature"]; + _context6.prev = 6; + stripeProviderService = req.scope.resolve("pp_stripe"); + event = stripeProviderService.constructWebhookEvent(req.body, signature); + _context6.next = 15; + break; + + case 11: + _context6.prev = 11; + _context6.t0 = _context6["catch"](6); + res.status(400).send("Webhook Error: ".concat(_context6.t0.message)); + return _context6.abrupt("return"); + + case 15: + paymentIntent = event.data.object; + cartId = paymentIntent.metadata.cart_id; // Backward compatibility + + resourceId = paymentIntent.metadata.resource_id; + + if (!isPaymentCollection(resourceId)) { + _context6.next = 23; + break; + } + + _context6.next = 21; + return handlePaymentCollection(event, req, res, resourceId, paymentIntent.id); + + case 21: + _context6.next = 25; + break; + + case 23: + _context6.next = 25; + return handleCartPayments(event, req, res, cartId !== null && cartId !== void 0 ? cartId : resourceId); + + case 25: + case "end": + return _context6.stop(); + } + } + }, _callee6, null, [[6, 11]]); + })); + + return function (_x, _x2) { + return _ref.apply(this, arguments); + }; +}(); + +exports["default"] = _default; + +function paymentIntentAmountCapturableEventHandler(_x15) { + return _paymentIntentAmountCapturableEventHandler.apply(this, arguments); +} + +function _paymentIntentAmountCapturableEventHandler() { + _paymentIntentAmountCapturableEventHandler = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(_ref5) { + var order, cartId, container, transactionManager, cartService, orderService, cartServiceTx; + return _regeneratorRuntime().wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + order = _ref5.order, cartId = _ref5.cartId, container = _ref5.container, transactionManager = _ref5.transactionManager; + + if (order) { + _context7.next = 11; + break; + } + + cartService = container.resolve("cartService"); + orderService = container.resolve("orderService"); + cartServiceTx = cartService.withTransaction(transactionManager); + _context7.next = 7; + return cartServiceTx.setPaymentSession(cartId, "stripe"); + + case 7: + _context7.next = 9; + return cartServiceTx.authorizePayment(cartId); + + case 9: + _context7.next = 11; + return orderService.withTransaction(transactionManager).createFromCart(cartId); + + case 11: + case "end": + return _context7.stop(); + } + } + }, _callee7); + })); + return _paymentIntentAmountCapturableEventHandler.apply(this, arguments); +} \ No newline at end of file diff --git a/packages/medusa-payment-stripe/helpers/stripe-base.js b/packages/medusa-payment-stripe/helpers/stripe-base.js new file mode 100644 index 0000000000000..21e89b544f4c6 --- /dev/null +++ b/packages/medusa-payment-stripe/helpers/stripe-base.js @@ -0,0 +1,772 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _medusa = require("@medusajs/medusa"); + +var _stripe = _interopRequireDefault(require("stripe")); + +var _dist = require("@medusajs/medusa/dist"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var StripeBase = /*#__PURE__*/function (_AbstractPaymentServi) { + _inherits(StripeBase, _AbstractPaymentServi); + + var _super = _createSuper(StripeBase); + + function StripeBase(_, options) { + var _this; + + _classCallCheck(this, StripeBase); + + _this = _super.call(this, _, options); + /** + * Required Stripe options: + * { + * api_key: "stripe_secret_key", REQUIRED + * webhook_secret: "stripe_webhook_secret", REQUIRED + * // Use this flag to capture payment immediately (default is false) + * capture: true + * } + */ + + _this.options_ = options; + /** @private @const {Stripe} */ + + _this.stripe_ = (0, _stripe["default"])(options.api_key); + return _this; + } + + _createClass(StripeBase, [{ + key: "getPaymentIntentOptions", + value: function getPaymentIntentOptions() { + var _this$paymentIntentOp, _this$paymentIntentOp2, _this$paymentIntentOp3; + + var options = {}; + + if (this !== null && this !== void 0 && (_this$paymentIntentOp = this.paymentIntentOptions) !== null && _this$paymentIntentOp !== void 0 && _this$paymentIntentOp.capture_method) { + options.capture_method = this.paymentIntentOptions.capture_method; + } + + if (this !== null && this !== void 0 && (_this$paymentIntentOp2 = this.paymentIntentOptions) !== null && _this$paymentIntentOp2 !== void 0 && _this$paymentIntentOp2.setup_future_usage) { + options.setup_future_usage = this.paymentIntentOptions.setup_future_usage; + } + + if (this !== null && this !== void 0 && (_this$paymentIntentOp3 = this.paymentIntentOptions) !== null && _this$paymentIntentOp3 !== void 0 && _this$paymentIntentOp3.payment_method_types) { + options.payment_method_types = this.paymentIntentOptions.payment_method_types; + } + + return options; + } + /** + * Get payment session status + * statuses. + * @param {PaymentSessionData} paymentData - the data stored with the payment session + * @return {Promise} the status of the order + */ + + }, { + key: "getStatus", + value: function () { + var _getStatus = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(paymentData) { + var id, paymentIntent; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + id = paymentData.id; + _context.next = 3; + return this.stripe_.paymentIntents.retrieve(id); + + case 3: + paymentIntent = _context.sent; + _context.t0 = paymentIntent.status; + _context.next = _context.t0 === "requires_payment_method" ? 7 : _context.t0 === "requires_confirmation" ? 7 : _context.t0 === "processing" ? 7 : _context.t0 === "requires_action" ? 8 : _context.t0 === "canceled" ? 9 : _context.t0 === "requires_capture" ? 10 : _context.t0 === "succeeded" ? 10 : 11; + break; + + case 7: + return _context.abrupt("return", _dist.PaymentSessionStatus.PENDING); + + case 8: + return _context.abrupt("return", _dist.PaymentSessionStatus.REQUIRES_MORE); + + case 9: + return _context.abrupt("return", _dist.PaymentSessionStatus.CANCELED); + + case 10: + return _context.abrupt("return", _dist.PaymentSessionStatus.AUTHORIZED); + + case 11: + return _context.abrupt("return", _dist.PaymentSessionStatus.PENDING); + + case 12: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function getStatus(_x) { + return _getStatus.apply(this, arguments); + } + + return getStatus; + }() + /** + * Fetches a customers saved payment methods if registered in Stripe. + * @param {Customer} customer - customer to fetch saved cards for + * @return {Promise} saved payments methods + */ + + }, { + key: "retrieveSavedMethods", + value: function () { + var _retrieveSavedMethods = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(customer) { + var methods; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (!(customer.metadata && customer.metadata.stripe_id)) { + _context2.next = 5; + break; + } + + _context2.next = 3; + return this.stripe_.paymentMethods.list({ + customer: customer.metadata.stripe_id, + type: "card" + }); + + case 3: + methods = _context2.sent; + return _context2.abrupt("return", methods.data); + + case 5: + return _context2.abrupt("return", []); + + case 6: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function retrieveSavedMethods(_x2) { + return _retrieveSavedMethods.apply(this, arguments); + } + + return retrieveSavedMethods; + }() + /** + * Fetches a Stripe customer + * @param {string} customerId - Stripe customer id + * @return {Promise} Stripe customer + */ + + }, { + key: "retrieveCustomer", + value: function () { + var _retrieveCustomer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(customerId) { + return _regeneratorRuntime().wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + if (customerId) { + _context3.next = 2; + break; + } + + return _context3.abrupt("return"); + + case 2: + _context3.next = 4; + return this.stripe_.customers.retrieve(customerId); + + case 4: + return _context3.abrupt("return", _context3.sent); + + case 5: + case "end": + return _context3.stop(); + } + } + }, _callee3, this); + })); + + function retrieveCustomer(_x3) { + return _retrieveCustomer.apply(this, arguments); + } + + return retrieveCustomer; + }() + /** + * Creates a Stripe payment intent. + * If customer is not registered in Stripe, we do so. + * @param {Cart & PaymentContext} context - context to use to create a payment for + * @return {Promise} Stripe payment intent + */ + + }, { + key: "createPayment", + value: function () { + var _createPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(context) { + var _cart_context$payment, _this$options_, _this$options_2, _customer$metadata, _customer$metadata3; + + var intentRequestData, cart_id, email, cart_context, currency_code, amount, resource_id, customer, intentRequest, _customer$metadata2, stripeCustomer, session_data; + + return _regeneratorRuntime().wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + intentRequestData = this.getPaymentIntentOptions(); + cart_id = context.id, email = context.email, cart_context = context.context, currency_code = context.currency_code, amount = context.amount, resource_id = context.resource_id, customer = context.customer; + intentRequest = _objectSpread({ + description: (_cart_context$payment = cart_context.payment_description) !== null && _cart_context$payment !== void 0 ? _cart_context$payment : (_this$options_ = this.options_) === null || _this$options_ === void 0 ? void 0 : _this$options_.payment_description, + amount: Math.round(amount), + currency: currency_code, + metadata: { + cart_id: cart_id, + resource_id: resource_id + }, + capture_method: this.options_.capture ? "automatic" : "manual" + }, intentRequestData); + + if ((_this$options_2 = this.options_) !== null && _this$options_2 !== void 0 && _this$options_2.automatic_payment_methods) { + intentRequest.automatic_payment_methods = { + enabled: true + }; + } + + if (!(customer !== null && customer !== void 0 && (_customer$metadata = customer.metadata) !== null && _customer$metadata !== void 0 && _customer$metadata.stripe_id)) { + _context4.next = 8; + break; + } + + intentRequest.customer = customer === null || customer === void 0 ? void 0 : (_customer$metadata2 = customer.metadata) === null || _customer$metadata2 === void 0 ? void 0 : _customer$metadata2.stripe_id; + _context4.next = 12; + break; + + case 8: + _context4.next = 10; + return this.stripe_.customers.create({ + email: email + }); + + case 10: + stripeCustomer = _context4.sent; + intentRequest.customer = stripeCustomer.id; + + case 12: + _context4.next = 14; + return this.stripe_.paymentIntents.create(intentRequest); + + case 14: + session_data = _context4.sent; + return _context4.abrupt("return", { + session_data: session_data, + update_requests: customer !== null && customer !== void 0 && (_customer$metadata3 = customer.metadata) !== null && _customer$metadata3 !== void 0 && _customer$metadata3.stripe_id ? undefined : { + customer_metadata: { + stripe_id: intentRequest.customer + } + } + }); + + case 16: + case "end": + return _context4.stop(); + } + } + }, _callee4, this); + })); + + function createPayment(_x4) { + return _createPayment.apply(this, arguments); + } + + return createPayment; + }() + /** + * Retrieves Stripe payment intent. + * @param {PaymentData} data - the data of the payment to retrieve + * @return {Promise} Stripe payment intent + */ + + }, { + key: "retrievePayment", + value: function () { + var _retrievePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(data) { + return _regeneratorRuntime().wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + _context5.next = 2; + return this.stripe_.paymentIntents.retrieve(data.id); + + case 2: + return _context5.abrupt("return", _context5.sent); + + case 3: + case "end": + return _context5.stop(); + } + } + }, _callee5, this); + })); + + function retrievePayment(_x5) { + return _retrievePayment.apply(this, arguments); + } + + return retrievePayment; + }() + /** + * Gets a Stripe payment intent and returns it. + * @param {PaymentSession} paymentSession - the data of the payment to retrieve + * @return {Promise} Stripe payment intent + */ + + }, { + key: "getPaymentData", + value: function () { + var _getPaymentData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(paymentSession) { + return _regeneratorRuntime().wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + _context6.next = 2; + return this.stripe_.paymentIntents.retrieve(paymentSession.data.id); + + case 2: + return _context6.abrupt("return", _context6.sent); + + case 3: + case "end": + return _context6.stop(); + } + } + }, _callee6, this); + })); + + function getPaymentData(_x6) { + return _getPaymentData.apply(this, arguments); + } + + return getPaymentData; + }() + /** + * Authorizes Stripe payment intent by simply returning + * the status for the payment intent in use. + * @param {PaymentSession} paymentSession - payment session data + * @param {Data} context - properties relevant to current context + * @return {Promise<{ data: PaymentSessionData; status: PaymentSessionStatus }>} result with data and status + */ + + }, { + key: "authorizePayment", + value: function () { + var _authorizePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(paymentSession) { + var context, + stat, + _args7 = arguments; + return _regeneratorRuntime().wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + context = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {}; + _context7.next = 3; + return this.getStatus(paymentSession.data); + + case 3: + stat = _context7.sent; + return _context7.abrupt("return", { + data: paymentSession.data, + status: stat + }); + + case 5: + case "end": + return _context7.stop(); + } + } + }, _callee7, this); + })); + + function authorizePayment(_x7) { + return _authorizePayment.apply(this, arguments); + } + + return authorizePayment; + }() + }, { + key: "updatePaymentData", + value: function () { + var _updatePaymentData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(sessionData, update) { + return _regeneratorRuntime().wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + _context8.next = 2; + return this.stripe_.paymentIntents.update(sessionData.id, _objectSpread({}, update.data)); + + case 2: + return _context8.abrupt("return", _context8.sent); + + case 3: + case "end": + return _context8.stop(); + } + } + }, _callee8, this); + })); + + function updatePaymentData(_x8, _x9) { + return _updatePaymentData.apply(this, arguments); + } + + return updatePaymentData; + }() + /** + * Updates Stripe payment intent. + * @param {PaymentSessionData} paymentSessionData - payment session data. + * @param {Cart & PaymentContext} context + * @return {Promise} Stripe payment intent + */ + + }, { + key: "updatePayment", + value: function () { + var _updatePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(paymentSessionData, context) { + var _customer$metadata4; + + var amount, customer, stripeId; + return _regeneratorRuntime().wrap(function _callee9$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + amount = context.amount, customer = context.customer; + stripeId = (customer === null || customer === void 0 ? void 0 : (_customer$metadata4 = customer.metadata) === null || _customer$metadata4 === void 0 ? void 0 : _customer$metadata4.stripe_id) || undefined; + + if (!(stripeId !== paymentSessionData.customer)) { + _context9.next = 8; + break; + } + + _context9.next = 5; + return this.createPayment(context); + + case 5: + return _context9.abrupt("return", _context9.sent); + + case 8: + if (!(amount && paymentSessionData.amount === Math.round(amount))) { + _context9.next = 10; + break; + } + + return _context9.abrupt("return", paymentSessionData); + + case 10: + _context9.next = 12; + return this.stripe_.paymentIntents.update(paymentSessionData.id, { + amount: Math.round(amount) + }); + + case 12: + return _context9.abrupt("return", _context9.sent); + + case 13: + case "end": + return _context9.stop(); + } + } + }, _callee9, this); + })); + + function updatePayment(_x10, _x11) { + return _updatePayment.apply(this, arguments); + } + + return updatePayment; + }() + }, { + key: "deletePayment", + value: function () { + var _deletePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(payment) { + var id; + return _regeneratorRuntime().wrap(function _callee10$(_context10) { + while (1) { + switch (_context10.prev = _context10.next) { + case 0: + id = payment.data.id; + return _context10.abrupt("return", this.stripe_.paymentIntents.cancel(id)["catch"](function (err) { + if (err.statusCode === 400) { + return; + } + + throw err; + })); + + case 2: + case "end": + return _context10.stop(); + } + } + }, _callee10, this); + })); + + function deletePayment(_x12) { + return _deletePayment.apply(this, arguments); + } + + return deletePayment; + }() + /** + * Updates customer of Stripe payment intent. + * @param {string} paymentIntentId - id of payment intent to update + * @param {string} customerId - id of \ Stripe customer + * @return {object} Stripe payment intent + */ + + }, { + key: "updatePaymentIntentCustomer", + value: function () { + var _updatePaymentIntentCustomer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(paymentIntentId, customerId) { + return _regeneratorRuntime().wrap(function _callee11$(_context11) { + while (1) { + switch (_context11.prev = _context11.next) { + case 0: + _context11.next = 2; + return this.stripe_.paymentIntents.update(paymentIntentId, { + customer: customerId + }); + + case 2: + return _context11.abrupt("return", _context11.sent); + + case 3: + case "end": + return _context11.stop(); + } + } + }, _callee11, this); + })); + + function updatePaymentIntentCustomer(_x13, _x14) { + return _updatePaymentIntentCustomer.apply(this, arguments); + } + + return updatePaymentIntentCustomer; + }() + /** + * Captures payment for Stripe payment intent. + * @param {Payment} payment - payment method data from cart + * @return {Promise} Stripe payment intent + */ + + }, { + key: "capturePayment", + value: function () { + var _capturePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee12(payment) { + var id, intent; + return _regeneratorRuntime().wrap(function _callee12$(_context12) { + while (1) { + switch (_context12.prev = _context12.next) { + case 0: + id = payment.data.id; + _context12.prev = 1; + _context12.next = 4; + return this.stripe_.paymentIntents.capture(id); + + case 4: + intent = _context12.sent; + return _context12.abrupt("return", intent); + + case 8: + _context12.prev = 8; + _context12.t0 = _context12["catch"](1); + + if (!(_context12.t0.code === "payment_intent_unexpected_state")) { + _context12.next = 13; + break; + } + + if (!(_context12.t0.payment_intent.status === "succeeded")) { + _context12.next = 13; + break; + } + + return _context12.abrupt("return", _context12.t0.payment_intent); + + case 13: + throw _context12.t0; + + case 14: + case "end": + return _context12.stop(); + } + } + }, _callee12, this, [[1, 8]]); + })); + + function capturePayment(_x15) { + return _capturePayment.apply(this, arguments); + } + + return capturePayment; + }() + /** + * Refunds payment for Stripe payment intent. + * @param {Payment} payment - payment method data from cart + * @param {number} refundAmount - amount to refund + * @return {Promise} refunded payment intent + */ + + }, { + key: "refundPayment", + value: function () { + var _refundPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee13(payment, amountToRefund) { + var id; + return _regeneratorRuntime().wrap(function _callee13$(_context13) { + while (1) { + switch (_context13.prev = _context13.next) { + case 0: + id = payment.data.id; + _context13.next = 3; + return this.stripe_.refunds.create({ + amount: Math.round(amountToRefund), + payment_intent: id + }); + + case 3: + return _context13.abrupt("return", payment.data); + + case 4: + case "end": + return _context13.stop(); + } + } + }, _callee13, this); + })); + + function refundPayment(_x16, _x17) { + return _refundPayment.apply(this, arguments); + } + + return refundPayment; + }() + /** + * Cancels payment for Stripe payment intent. + * @param {Payment} payment - payment method data from cart + * @return {Promise} canceled payment intent + */ + + }, { + key: "cancelPayment", + value: function () { + var _cancelPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee14(payment) { + var id; + return _regeneratorRuntime().wrap(function _callee14$(_context14) { + while (1) { + switch (_context14.prev = _context14.next) { + case 0: + id = payment.data.id; + _context14.prev = 1; + _context14.next = 4; + return this.stripe_.paymentIntents.cancel(id); + + case 4: + return _context14.abrupt("return", _context14.sent); + + case 7: + _context14.prev = 7; + _context14.t0 = _context14["catch"](1); + + if (!(_context14.t0.payment_intent.status === "canceled")) { + _context14.next = 11; + break; + } + + return _context14.abrupt("return", _context14.t0.payment_intent); + + case 11: + throw _context14.t0; + + case 12: + case "end": + return _context14.stop(); + } + } + }, _callee14, this, [[1, 7]]); + })); + + function cancelPayment(_x18) { + return _cancelPayment.apply(this, arguments); + } + + return cancelPayment; + }() + /** + * Constructs Stripe Webhook event + * @param {object} data - the data of the webhook request: req.body + * @param {object} signature - the Stripe signature on the event, that + * ensures integrity of the webhook event + * @return {object} Stripe Webhook event + */ + + }, { + key: "constructWebhookEvent", + value: function constructWebhookEvent(data, signature) { + return this.stripe_.webhooks.constructEvent(data, signature, this.options_.webhook_secret); + } + }]); + + return StripeBase; +}(_medusa.AbstractPaymentService); + +_defineProperty(StripeBase, "identifier", null); + +var _default = StripeBase; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js b/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js new file mode 100644 index 0000000000000..9f58040cea0db --- /dev/null +++ b/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js @@ -0,0 +1,63 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.StripeProviderServiceMock = void 0; + +var _medusaTestUtils = require("medusa-test-utils"); + +var StripeProviderServiceMock = { + retrievePayment: jest.fn().mockImplementation(function (payData) { + if (payData.id === "pi_123456789") { + return Promise.resolve({ + id: "pi", + customer: "cus_123456789" + }); + } + + if (payData.id === "pi_no") { + return Promise.resolve({ + id: "pi_no" + }); + } + + return Promise.resolve(undefined); + }), + cancelPayment: jest.fn().mockImplementation(function (cart) { + return Promise.resolve(); + }), + updatePaymentIntentCustomer: jest.fn().mockImplementation(function (cart) { + return Promise.resolve(); + }), + retrieveCustomer: jest.fn().mockImplementation(function (customerId) { + if (customerId === "cus_123456789_new") { + return Promise.resolve({ + id: "cus_123456789_new" + }); + } + + return Promise.resolve(undefined); + }), + createCustomer: jest.fn().mockImplementation(function (customer) { + if (customer._id === _medusaTestUtils.IdMap.getId("vvd")) { + return Promise.resolve({ + id: "cus_123456789_new_vvd" + }); + } + + return Promise.resolve(undefined); + }), + createPayment: jest.fn().mockImplementation(function (cart) { + return Promise.resolve({ + id: "pi_new", + customer: "cus_123456789_new" + }); + }) +}; +exports.StripeProviderServiceMock = StripeProviderServiceMock; +var mock = jest.fn().mockImplementation(function () { + return StripeProviderServiceMock; +}); +var _default = mock; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-bancontact.js b/packages/medusa-payment-stripe/services/stripe-bancontact.js new file mode 100644 index 0000000000000..1fef577f0fa3c --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-bancontact.js @@ -0,0 +1,65 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var BancontactProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(BancontactProviderService, _StripeBase); + + var _super = _createSuper(BancontactProviderService); + + function BancontactProviderService(_, options) { + _classCallCheck(this, BancontactProviderService); + + return _super.call(this, _, options); + } + + _createClass(BancontactProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return { + payment_method_types: ["bancontact"], + capture_method: "automatic" + }; + } + }]); + + return BancontactProviderService; +}(_stripeBase["default"]); + +_defineProperty(BancontactProviderService, "identifier", "stripe-bancontact"); + +var _default = BancontactProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-blik.js b/packages/medusa-payment-stripe/services/stripe-blik.js new file mode 100644 index 0000000000000..0b05d94eb0b4c --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-blik.js @@ -0,0 +1,65 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var BlikProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(BlikProviderService, _StripeBase); + + var _super = _createSuper(BlikProviderService); + + function BlikProviderService(_, options) { + _classCallCheck(this, BlikProviderService); + + return _super.call(this, _, options); + } + + _createClass(BlikProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return { + payment_method_types: ["blik"], + capture_method: "automatic" + }; + } + }]); + + return BlikProviderService; +}(_stripeBase["default"]); + +_defineProperty(BlikProviderService, "identifier", "stripe-blik"); + +var _default = BlikProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-giropay.js b/packages/medusa-payment-stripe/services/stripe-giropay.js new file mode 100644 index 0000000000000..8c7cb1587b923 --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-giropay.js @@ -0,0 +1,65 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var GiropayProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(GiropayProviderService, _StripeBase); + + var _super = _createSuper(GiropayProviderService); + + function GiropayProviderService(_, options) { + _classCallCheck(this, GiropayProviderService); + + return _super.call(this, _, options); + } + + _createClass(GiropayProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return { + payment_method_types: ["giropay"], + capture_method: "automatic" + }; + } + }]); + + return GiropayProviderService; +}(_stripeBase["default"]); + +_defineProperty(GiropayProviderService, "identifier", "stripe-giropay"); + +var _default = GiropayProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-ideal.js b/packages/medusa-payment-stripe/services/stripe-ideal.js new file mode 100644 index 0000000000000..ced727f5fc289 --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-ideal.js @@ -0,0 +1,65 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var IdealProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(IdealProviderService, _StripeBase); + + var _super = _createSuper(IdealProviderService); + + function IdealProviderService(_, options) { + _classCallCheck(this, IdealProviderService); + + return _super.call(this, _, options); + } + + _createClass(IdealProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return { + payment_method_types: ["ideal"], + capture_method: "automatic" + }; + } + }]); + + return IdealProviderService; +}(_stripeBase["default"]); + +_defineProperty(IdealProviderService, "identifier", "stripe-ideal"); + +var _default = IdealProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-provider.js b/packages/medusa-payment-stripe/services/stripe-provider.js new file mode 100644 index 0000000000000..f201e497afbf7 --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-provider.js @@ -0,0 +1,62 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var StripeProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(StripeProviderService, _StripeBase); + + var _super = _createSuper(StripeProviderService); + + function StripeProviderService(_, options) { + _classCallCheck(this, StripeProviderService); + + return _super.call(this, _, options); + } + + _createClass(StripeProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return {}; + } + }]); + + return StripeProviderService; +}(_stripeBase["default"]); + +_defineProperty(StripeProviderService, "identifier", "stripe"); + +var _default = StripeProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-przelewy24.js b/packages/medusa-payment-stripe/services/stripe-przelewy24.js new file mode 100644 index 0000000000000..00bb7df48c610 --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-przelewy24.js @@ -0,0 +1,65 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var Przelewy24ProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(Przelewy24ProviderService, _StripeBase); + + var _super = _createSuper(Przelewy24ProviderService); + + function Przelewy24ProviderService(_, options) { + _classCallCheck(this, Przelewy24ProviderService); + + return _super.call(this, _, options); + } + + _createClass(Przelewy24ProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return { + payment_method_types: ["p24"], + capture_method: "automatic" + }; + } + }]); + + return Przelewy24ProviderService; +}(_stripeBase["default"]); + +_defineProperty(Przelewy24ProviderService, "identifier", "stripe-przelewy24"); + +var _default = Przelewy24ProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/src/__fixtures__/data.ts b/packages/medusa-payment-stripe/src/__fixtures__/data.ts index ae3e4571a4dc9..3db0a5d4d1dae 100644 --- a/packages/medusa-payment-stripe/src/__fixtures__/data.ts +++ b/packages/medusa-payment-stripe/src/__fixtures__/data.ts @@ -1,5 +1,5 @@ export const PaymentIntentDataByStatus = { - REQUIRE_PAYMENT_METHOD: { + REQUIRES_PAYMENT_METHOD: { id: "requires_payment_method", status: "requires_payment_method", }, diff --git a/packages/medusa-payment-stripe/src/api/hooks/index.ts b/packages/medusa-payment-stripe/src/api/hooks/index.ts index f938080bdbe7e..87a02f60c0f39 100644 --- a/packages/medusa-payment-stripe/src/api/hooks/index.ts +++ b/packages/medusa-payment-stripe/src/api/hooks/index.ts @@ -1,7 +1,7 @@ import stripeHooks from "./stripe" import { Router } from "express" import bodyParser from "body-parser" -import middlewares from "@medusajs/medusa/dist/api/middlewares" +import { wrapHandler } from "@medusajs/medusa" const route = Router() @@ -12,7 +12,7 @@ export default (app) => { "/hooks", // stripe constructEvent fails without body-parser bodyParser.raw({ type: "application/json" }), - middlewares.wrap(stripeHooks) + wrapHandler(stripeHooks) ) return app } diff --git a/packages/medusa-payment-stripe/src/api/hooks/stripe.ts b/packages/medusa-payment-stripe/src/api/hooks/stripe.ts index ab834295dd7af..37b6670846184 100644 --- a/packages/medusa-payment-stripe/src/api/hooks/stripe.ts +++ b/packages/medusa-payment-stripe/src/api/hooks/stripe.ts @@ -1,15 +1,5 @@ import { Request, Response } from "express" -import { - buildHandleCartPaymentErrorMessage, - constructWebhook, - isPaymentCollection, -} from "../utils/utils" -import { - AbstractCartCompletionStrategy, - CartService, - IdempotencyKeyService, -} from "@medusajs/medusa" -import { MedusaError } from "medusa-core-utils" +import { constructWebhook, handlePaymentHook } from "../utils/utils" export default async (req: Request, res: Response) => { let event @@ -25,137 +15,6 @@ export default async (req: Request, res: Response) => { } const paymentIntent = event.data.object - const cartId = paymentIntent.metadata.cart_id // Backward compatibility - const resourceId = paymentIntent.metadata.resource_id - if (isPaymentCollection(resourceId)) { - await handlePaymentCollection(event, req, res, resourceId, paymentIntent.id) - } else { - await handleCartPayments(event, req, res, cartId ?? resourceId) - } -} - -async function handleCartPayments(event, req, res, cartId) { - const manager = req.scope.resolve("manager") - const orderService = req.scope.resolve("orderService") - const logger = req.scope.resolve("logger") - - const order = await orderService - .retrieveByCartId(cartId) - .catch(() => undefined) - - // handle payment intent events - switch (event.type) { - case "payment_intent.succeeded": - if (order) { - // If order is created but not captured, we attempt to do so - if (order.payment_status !== "captured") { - await manager.transaction(async (manager) => { - await orderService.withTransaction(manager).capturePayment(order.id) - }) - } else { - // Otherwise, respond with 200 preventing Stripe from retrying - return res.sendStatus(200) - } - } else { - // If order is not created, we respond with 404 to trigger Stripe retry mechanism - return res.sendStatus(404) - } - break - case "payment_intent.amount_capturable_updated": - try { - await manager.transaction(async (manager) => { - await paymentIntentAmountCapturableEventHandler({ - order, - cartId, - container: req.scope, - transactionManager: manager, - }) - }) - } catch (err) { - const message = buildHandleCartPaymentErrorMessage(event, err) - logger.warn(message) - return res.sendStatus(409) - } - break - default: - res.sendStatus(204) - return - } - - res.sendStatus(200) -} - -async function handlePaymentCollection(event, req, res, id, paymentIntentId) { - const manager = req.scope.resolve("manager") - const paymentCollectionService = req.scope.resolve("paymentCollectionService") - - const paycol = await paymentCollectionService - .retrieve(id, { relations: ["payments"] }) - .catch(() => undefined) - - if (paycol?.payments?.length) { - if (event.type === "payment_intent.succeeded") { - const payment = paycol.payments.find( - (pay) => pay.data.id === paymentIntentId - ) - if (payment && !payment.captured_at) { - await manager.transaction(async (manager) => { - await paymentCollectionService - .withTransaction(manager) - .capture(payment.id) - }) - } - - res.sendStatus(200) - return - } - } - res.sendStatus(204) -} - -async function paymentIntentAmountCapturableEventHandler({ - order, - cartId, - container, - transactionManager, -}) { - if (!order) { - const completionStrat: AbstractCartCompletionStrategy = container.resolve( - "cartCompletionStrategy" - ) - const cartService: CartService = container.resolve("cartService") - const idempotencyKeyService: IdempotencyKeyService = container.resolve( - "idempotencyKeyService" - ) - - let idempotencyKey - try { - idempotencyKey = await idempotencyKeyService - .withTransaction(transactionManager) - .initializeRequest("", "post", { cart_id: cartId }, "/stripe/hooks") - } catch (error) { - throw new MedusaError( - MedusaError.Types.UNEXPECTED_STATE, - "Failed to create idempotency key", - "400" - ) - } - - const cart = await cartService - .withTransaction(transactionManager) - .retrieve(cartId, { select: ["context"] }) - - const { response_code, response_body } = await completionStrat - .withTransaction(transactionManager) - .complete(cartId, idempotencyKey, { ip: cart.context?.ip as string }) - - if (response_code !== 200) { - throw new MedusaError( - MedusaError.Types.UNEXPECTED_STATE, - response_body["message"], - response_body["code"].toString() - ) - } - } + await handlePaymentHook(event, req, res, paymentIntent) } diff --git a/packages/medusa-payment-stripe/src/api/utils/utils.ts b/packages/medusa-payment-stripe/src/api/utils/utils.ts index c60ef01d767f6..046025c0932bf 100644 --- a/packages/medusa-payment-stripe/src/api/utils/utils.ts +++ b/packages/medusa-payment-stripe/src/api/utils/utils.ts @@ -1,6 +1,13 @@ import { AwilixContainer } from "awilix" import Stripe from "stripe" -import { PostgresError } from "@medusajs/medusa" +import { + AbstractCartCompletionStrategy, + CartService, + IdempotencyKeyService, + PostgresError, +} from "@medusajs/medusa" +import { EOL } from "os" +import { MedusaError } from "medusa-core-utils" const PAYMENT_PROVIDER_KEY = "pp_stripe" @@ -21,10 +28,7 @@ export function isPaymentCollection(id) { return id && id.startsWith("paycol") } -export function buildHandleCartPaymentErrorMessage( - event: string, - err: Stripe.StripeRawError -): string { +export function buildError(event: string, err: Stripe.StripeRawError): string { let message = `Stripe webhook ${event} handling failed\n${ err?.detail ?? err?.message }` @@ -41,3 +45,210 @@ export function buildHandleCartPaymentErrorMessage( return message } + +export async function handlePaymentHook(event, req, res, paymentIntent) { + const logger = req.scope.resolve("logger") + + const cartId = paymentIntent.metadata.cart_id // Backward compatibility + const resourceId = paymentIntent.metadata.resource_id + + switch (event.type) { + case "payment_intent.succeeded": + try { + await onPaymentIntentSucceeded({ + paymentIntent, + cartId, + resourceId, + isPaymentCollection: isPaymentCollection(resourceId), + container: req.scope, + }) + } catch (err) { + const message = buildError(event, err) + logger.warn(message) + return res.sendStatus(409) + } + + break + case "payment_intent.amount_capturable_updated": + try { + await onPaymentAmountCapturableUpdate({ + paymentIntent, + cartId, + container: req.scope, + }) + } catch (err) { + const message = buildError(event, err) + logger.warn(message) + return res.sendStatus(409) + } + + break + case "payment_intent.payment_failed": { + const intent = event.data.object + const message = + intent.last_payment_error && intent.last_payment_error.message + logger.error( + `The payment of the payment intent ${intent.id} has failed${EOL}${message}` + ) + break + } + default: + res.sendStatus(204) + return + } + + res.sendStatus(200) +} + +async function onPaymentIntentSucceeded({ + paymentIntent, + cartId, + resourceId, + isPaymentCollection, + container, +}) { + const manager = container.resolve("manager") + + await manager.transaction(async (transactionManager) => { + await completeCartIfNecessary({ + paymentIntent, + cartId, + container, + transactionManager, + }) + + if (isPaymentCollection) { + await capturePaymenCollectiontIfNecessary({ + paymentIntent, + resourceId, + container, + }) + } else { + await capturePaymentIfNecessary({ + cartId, + transactionManager, + container, + }) + } + }) +} + +async function onPaymentAmountCapturableUpdate({ + paymentIntent, + cartId, + container, +}) { + const manager = container.resolve("manager") + + await manager.transaction(async (transactionManager) => { + await completeCartIfNecessary({ + paymentIntent, + cartId, + container, + transactionManager, + }) + }) +} + +async function capturePaymenCollectiontIfNecessary({ + paymentIntent, + resourceId, + container, +}) { + const manager = container.resolve("manager") + const paymentCollectionService = container.resolve("paymentCollectionService") + + const paycol = await paymentCollectionService + .retrieve(resourceId, { relations: ["payments"] }) + .catch(() => undefined) + + if (paycol?.payments?.length) { + const payment = paycol.payments.find( + (pay) => pay.data.id === paymentIntent.id + ) + + if (payment && !payment.captured_at) { + await manager.transaction(async (manager) => { + await paymentCollectionService + .withTransaction(manager) + .capture(payment.id) + }) + } + } +} + +async function capturePaymentIfNecessary({ + cartId, + transactionManager, + container, +}) { + const orderService = container.resolve("orderService") + const order = await orderService + .retrieveByCartId(cartId) + .catch(() => undefined) + + if (order.payment_status !== "captured") { + const orderService = container.resolve("orderService") + await orderService + .withTransaction(transactionManager) + .capturePayment(order.id) + } +} + +async function completeCartIfNecessary({ + paymentIntent, + cartId, + container, + transactionManager, +}) { + const orderService = container.resolve("orderService") + const order = await orderService + .retrieveByCartId(cartId) + .catch(() => undefined) + + if (!order) { + const completionStrat: AbstractCartCompletionStrategy = container.resolve( + "cartCompletionStrategy" + ) + const cartService: CartService = container.resolve("cartService") + const idempotencyKeyService: IdempotencyKeyService = container.resolve( + "idempotencyKeyService" + ) + + let idempotencyKey + try { + idempotencyKey = await idempotencyKeyService + .withTransaction(transactionManager) + .create({ + request_method: "post", + request_path: "/stripe/hooks", + request_params: { + cart_id: cartId, + payment_intent_id: paymentIntent.id, + }, + }) + } catch (error) { + throw new MedusaError( + MedusaError.Types.UNEXPECTED_STATE, + "Failed to create idempotency key", + "400" + ) + } + + const cart = await cartService + .withTransaction(transactionManager) + .retrieve(cartId, { select: ["context"] }) + + const { response_code, response_body } = await completionStrat + .withTransaction(transactionManager) + .complete(cartId, idempotencyKey, { ip: cart.context?.ip as string }) + + if (response_code !== 200) { + throw new MedusaError( + MedusaError.Types.UNEXPECTED_STATE, + response_body["message"], + response_body["code"].toString() + ) + } + } +} diff --git a/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts index 25f1a18873507..e400b3891b1bd 100644 --- a/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts +++ b/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts @@ -54,7 +54,7 @@ describe("StripeTest", () => { let status: PaymentSessionStatus status = await stripeTest.getPaymentStatus({ - id: PaymentIntentDataByStatus.REQUIRE_PAYMENT_METHOD.id, + id: PaymentIntentDataByStatus.REQUIRES_PAYMENT_METHOD.id, }) expect(status).toBe(PaymentSessionStatus.PENDING) diff --git a/packages/medusa-payment-stripe/subscribers/cart.js b/packages/medusa-payment-stripe/subscribers/cart.js new file mode 100644 index 0000000000000..23d641c870710 --- /dev/null +++ b/packages/medusa-payment-stripe/subscribers/cart.js @@ -0,0 +1,125 @@ +"use strict"; + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +var CartSubscriber = /*#__PURE__*/function () { + function CartSubscriber(_ref) { + var _this = this; + + var cartService = _ref.cartService, + customerService = _ref.customerService, + paymentProviderService = _ref.paymentProviderService, + eventBusService = _ref.eventBusService; + + _classCallCheck(this, CartSubscriber); + + this.cartService_ = cartService; + this.customerService_ = customerService; + this.paymentProviderService_ = paymentProviderService; + this.eventBus_ = eventBusService; + this.eventBus_.subscribe("cart.customer_updated", /*#__PURE__*/function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(cart) { + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return _this.onCustomerUpdated(cart); + + case 2: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + + return function (_x) { + return _ref2.apply(this, arguments); + }; + }()); + } + + _createClass(CartSubscriber, [{ + key: "onCustomerUpdated", + value: function () { + var _onCustomerUpdated = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(cartId) { + var _cart$payment_session; + + var cart, session; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return this.cartService_.retrieve(cartId, { + select: ["subtotal", "tax_total", "shipping_total", "discount_total", "total"], + relations: ["items", "billing_address", "shipping_address", "region", "region.payment_providers", "items", "items.adjustments", "payment_sessions", "customer"] + }); + + case 2: + cart = _context2.sent; + + if ((_cart$payment_session = cart.payment_sessions) !== null && _cart$payment_session !== void 0 && _cart$payment_session.length) { + _context2.next = 5; + break; + } + + return _context2.abrupt("return", Promise.resolve()); + + case 5: + session = cart.payment_sessions.find(function (ps) { + return ps.provider_id === "stripe"; + }); + + if (!session) { + _context2.next = 10; + break; + } + + _context2.next = 9; + return this.paymentProviderService_.updateSession(session, cart); + + case 9: + return _context2.abrupt("return", _context2.sent); + + case 10: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function onCustomerUpdated(_x2) { + return _onCustomerUpdated.apply(this, arguments); + } + + return onCustomerUpdated; + }() + }]); + + return CartSubscriber; +}(); + +var _default = CartSubscriber; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa/src/api/middlewares/index.ts b/packages/medusa/src/api/middlewares/index.ts index 68aa757c54674..c85cf54a2bb9b 100644 --- a/packages/medusa/src/api/middlewares/index.ts +++ b/packages/medusa/src/api/middlewares/index.ts @@ -10,11 +10,23 @@ export { doesConditionBelongToDiscount } from "./discount/does-condition-belong- export { transformIncludesOptions } from "./transform-includes-options" export { transformBody } from "./transform-body" export { transformQuery } from "./transform-query" +export { default as authenticate } from "./authenticate" +export { default as authenticateCustomer } from "./authenticate-customer" +export { default as wrapHandler } from "./await-middleware" +export { default as normalizeQuery } from "./normalized-query" +export { default as requireCustomerAuthentication } from "./require-customer-authentication" +/** + * @deprecated you can now import the middlewares directly without passing by the default export + * e.g `import { wrapHandler } from "@medusajs/medusa" + */ export default { authenticate, authenticateCustomer, requireCustomerAuthentication, normalizeQuery, + /** + * @deprecated use `import { wrapHandler } from "@medusajs/medusa"` + */ wrap, } diff --git a/packages/medusa/src/index.js b/packages/medusa/src/index.js index 57a6103537b66..a1e454f5b7986 100644 --- a/packages/medusa/src/index.js +++ b/packages/medusa/src/index.js @@ -1,4 +1,5 @@ export * from "./api" +export * from "./api/middlewares" export * from "./interfaces" export * from "./models" export * from "./services" From bc4a45da5803a933140bbcfa1cd4282beeaee2e3 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Mon, 27 Feb 2023 14:46:53 +0100 Subject: [PATCH 27/36] remove default identifier --- packages/medusa-payment-stripe/src/core/stripe-base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/medusa-payment-stripe/src/core/stripe-base.ts b/packages/medusa-payment-stripe/src/core/stripe-base.ts index 017845d657d0e..89ec3b25149be 100644 --- a/packages/medusa-payment-stripe/src/core/stripe-base.ts +++ b/packages/medusa-payment-stripe/src/core/stripe-base.ts @@ -16,7 +16,7 @@ import { } from "../types" abstract class StripeBase extends AbstractPaymentProcessor { - static identifier = "stripe" + static identifier = "" protected readonly options_: StripeOptions protected stripe_: Stripe From 18573999fe7ea122ca7dbd4ca46ea23350b014c3 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Mon, 27 Feb 2023 14:49:36 +0100 Subject: [PATCH 28/36] remove build files --- .../medusa-payment-stripe/__mocks__/cart.js | 195 ----- .../__mocks__/customer.js | 45 - .../__mocks__/eventbus.js | 16 - .../medusa-payment-stripe/__mocks__/stripe.js | 98 --- .../medusa-payment-stripe/__mocks__/totals.js | 15 - packages/medusa-payment-stripe/api/index.js | 20 - .../api/middlewares/await-middleware.js | 14 - .../api/middlewares/index.js | 15 - .../api/routes/hooks/index.js | 27 - .../api/routes/hooks/stripe.js | 348 -------- .../helpers/stripe-base.js | 772 ------------------ .../services/__mocks__/stripe-provider.js | 63 -- .../services/stripe-bancontact.js | 65 -- .../services/stripe-blik.js | 65 -- .../services/stripe-giropay.js | 65 -- .../services/stripe-ideal.js | 65 -- .../services/stripe-provider.js | 62 -- .../services/stripe-przelewy24.js | 65 -- .../medusa-payment-stripe/subscribers/cart.js | 125 --- 19 files changed, 2140 deletions(-) delete mode 100644 packages/medusa-payment-stripe/__mocks__/cart.js delete mode 100644 packages/medusa-payment-stripe/__mocks__/customer.js delete mode 100644 packages/medusa-payment-stripe/__mocks__/eventbus.js delete mode 100644 packages/medusa-payment-stripe/__mocks__/stripe.js delete mode 100644 packages/medusa-payment-stripe/__mocks__/totals.js delete mode 100644 packages/medusa-payment-stripe/api/index.js delete mode 100644 packages/medusa-payment-stripe/api/middlewares/await-middleware.js delete mode 100644 packages/medusa-payment-stripe/api/middlewares/index.js delete mode 100644 packages/medusa-payment-stripe/api/routes/hooks/index.js delete mode 100644 packages/medusa-payment-stripe/api/routes/hooks/stripe.js delete mode 100644 packages/medusa-payment-stripe/helpers/stripe-base.js delete mode 100644 packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-bancontact.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-blik.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-giropay.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-ideal.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-provider.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-przelewy24.js delete mode 100644 packages/medusa-payment-stripe/subscribers/cart.js diff --git a/packages/medusa-payment-stripe/__mocks__/cart.js b/packages/medusa-payment-stripe/__mocks__/cart.js deleted file mode 100644 index eebabc2ef0bd5..0000000000000 --- a/packages/medusa-payment-stripe/__mocks__/cart.js +++ /dev/null @@ -1,195 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.carts = exports.CartServiceMock = void 0; - -var _medusaTestUtils = require("medusa-test-utils"); - -var carts = { - emptyCart: { - id: _medusaTestUtils.IdMap.getId("emptyCart"), - items: [], - region_id: _medusaTestUtils.IdMap.getId("testRegion"), - customer_id: "test-customer", - payment_sessions: [], - shipping_options: [{ - id: _medusaTestUtils.IdMap.getId("freeShipping"), - profile_id: "default_profile", - data: { - some_data: "yes" - } - }] - }, - frCart: { - id: _medusaTestUtils.IdMap.getId("fr-cart"), - email: "lebron@james.com", - title: "test", - region_id: _medusaTestUtils.IdMap.getId("region-france"), - items: [{ - id: _medusaTestUtils.IdMap.getId("line"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - unit_price: 8, - variant: { - id: _medusaTestUtils.IdMap.getId("eur-8-us-10") - }, - product: { - id: _medusaTestUtils.IdMap.getId("product") - }, - // { - // unit_price: 10, - // variant: { - // id: IdMap.getId("eur-10-us-12"), - // }, - // product: { - // id: IdMap.getId("product"), - // }, - // quantity: 1, - // }, - quantity: 10 - }, { - id: _medusaTestUtils.IdMap.getId("existingLine"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - unit_price: 10, - variant: { - id: _medusaTestUtils.IdMap.getId("eur-10-us-12") - }, - product: { - id: _medusaTestUtils.IdMap.getId("product") - }, - quantity: 1 - }], - shipping_methods: [{ - id: _medusaTestUtils.IdMap.getId("freeShipping"), - profile_id: "default_profile" - }], - shipping_options: [{ - id: _medusaTestUtils.IdMap.getId("freeShipping"), - profile_id: "default_profile" - }], - payment_sessions: [{ - provider_id: "stripe", - data: { - id: "pi_123456789", - customer: _medusaTestUtils.IdMap.getId("not-lebron") - } - }], - payment_method: { - provider_id: "stripe", - data: { - id: "pi_123456789", - customer: _medusaTestUtils.IdMap.getId("not-lebron") - } - }, - shipping_address: {}, - billing_address: {}, - discounts: [], - customer_id: _medusaTestUtils.IdMap.getId("lebron"), - context: {} - }, - frCartNoStripeCustomer: { - id: _medusaTestUtils.IdMap.getId("fr-cart-no-customer"), - title: "test", - region_id: _medusaTestUtils.IdMap.getId("region-france"), - items: [{ - id: _medusaTestUtils.IdMap.getId("line"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - content: [{ - unit_price: 8, - variant: { - id: _medusaTestUtils.IdMap.getId("eur-8-us-10") - }, - product: { - id: _medusaTestUtils.IdMap.getId("product") - }, - quantity: 1 - }, { - unit_price: 10, - variant: { - id: _medusaTestUtils.IdMap.getId("eur-10-us-12") - }, - product: { - id: _medusaTestUtils.IdMap.getId("product") - }, - quantity: 1 - }], - quantity: 10 - }, { - id: _medusaTestUtils.IdMap.getId("existingLine"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - content: { - unit_price: 10, - variant: { - id: _medusaTestUtils.IdMap.getId("eur-10-us-12") - }, - product: { - id: _medusaTestUtils.IdMap.getId("product") - }, - quantity: 1 - }, - quantity: 10 - }], - shipping_methods: [{ - id: _medusaTestUtils.IdMap.getId("freeShipping"), - profile_id: "default_profile" - }], - shipping_options: [{ - id: _medusaTestUtils.IdMap.getId("freeShipping"), - profile_id: "default_profile" - }], - payment_sessions: [{ - provider_id: "stripe", - data: { - id: "pi_no", - customer: _medusaTestUtils.IdMap.getId("not-lebron") - } - }], - payment_method: { - provider_id: "stripe", - data: { - id: "pi_no", - customer: _medusaTestUtils.IdMap.getId("not-lebron") - } - }, - shipping_address: {}, - billing_address: {}, - discounts: [], - customer_id: _medusaTestUtils.IdMap.getId("vvd") - } -}; -exports.carts = carts; -var CartServiceMock = { - retrieve: jest.fn().mockImplementation(function (cartId) { - if (cartId === _medusaTestUtils.IdMap.getId("fr-cart")) { - return Promise.resolve(carts.frCart); - } - - if (cartId === _medusaTestUtils.IdMap.getId("fr-cart-no-customer")) { - return Promise.resolve(carts.frCartNoStripeCustomer); - } - - if (cartId === _medusaTestUtils.IdMap.getId("emptyCart")) { - return Promise.resolve(carts.emptyCart); - } - - return Promise.resolve(undefined); - }), - updatePaymentSession: jest.fn().mockImplementation(function (cartId, stripe, paymentIntent) { - return Promise.resolve(); - }) -}; -exports.CartServiceMock = CartServiceMock; -var mock = jest.fn().mockImplementation(function () { - return CartServiceMock; -}); -var _default = mock; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/customer.js b/packages/medusa-payment-stripe/__mocks__/customer.js deleted file mode 100644 index 72cd299080511..0000000000000 --- a/packages/medusa-payment-stripe/__mocks__/customer.js +++ /dev/null @@ -1,45 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.CustomerServiceMock = void 0; - -var _medusaTestUtils = require("medusa-test-utils"); - -var CustomerServiceMock = { - retrieve: jest.fn().mockImplementation(function (id) { - if (id === _medusaTestUtils.IdMap.getId("lebron")) { - return Promise.resolve({ - _id: _medusaTestUtils.IdMap.getId("lebron"), - first_name: "LeBron", - last_name: "James", - email: "lebron@james.com", - password_hash: "1234", - metadata: { - stripe_id: "cus_123456789_new" - } - }); - } - - if (id === _medusaTestUtils.IdMap.getId("vvd")) { - return Promise.resolve({ - _id: _medusaTestUtils.IdMap.getId("vvd"), - first_name: "Virgil", - last_name: "Van Dijk", - email: "virg@vvd.com", - password_hash: "1234", - metadata: {} - }); - } - - return Promise.resolve(undefined); - }), - setMetadata: jest.fn().mockReturnValue(Promise.resolve()) -}; -exports.CustomerServiceMock = CustomerServiceMock; -var mock = jest.fn().mockImplementation(function () { - return CustomerServiceMock; -}); -var _default = mock; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/eventbus.js b/packages/medusa-payment-stripe/__mocks__/eventbus.js deleted file mode 100644 index b445554189888..0000000000000 --- a/packages/medusa-payment-stripe/__mocks__/eventbus.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.EventBusServiceMock = void 0; -var EventBusServiceMock = { - emit: jest.fn(), - subscribe: jest.fn() -}; -exports.EventBusServiceMock = EventBusServiceMock; -var mock = jest.fn().mockImplementation(function () { - return EventBusServiceMock; -}); -var _default = mock; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/stripe.js b/packages/medusa-payment-stripe/__mocks__/stripe.js deleted file mode 100644 index df9dbbb98c267..0000000000000 --- a/packages/medusa-payment-stripe/__mocks__/stripe.js +++ /dev/null @@ -1,98 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.StripeMock = void 0; -var StripeMock = { - customers: { - create: jest.fn().mockImplementation(function (data) { - if (data.email === "virg@vvd.com") { - return Promise.resolve({ - id: "cus_vvd", - email: "virg@vvd.com" - }); - } - - if (data.email === "lebron@james.com") { - return Promise.resolve({ - id: "cus_lebron", - email: "lebron@james.com" - }); - } - }) - }, - paymentIntents: { - create: jest.fn().mockImplementation(function (data) { - if (data.customer === "cus_123456789_new") { - return Promise.resolve({ - id: "pi_lebron", - amount: 100, - customer: "cus_123456789_new", - description: data === null || data === void 0 ? void 0 : data.description - }); - } - - if (data.customer === "cus_lebron") { - return Promise.resolve({ - id: "pi_lebron", - amount: 100, - customer: "cus_lebron", - description: data === null || data === void 0 ? void 0 : data.description - }); - } - }), - retrieve: jest.fn().mockImplementation(function (data) { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron" - }); - }), - update: jest.fn().mockImplementation(function (pi, data) { - if (data.customer === "cus_lebron_2") { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron_2", - amount: 1000 - }); - } - - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000 - }); - }), - capture: jest.fn().mockImplementation(function (data) { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000, - status: "succeeded" - }); - }), - cancel: jest.fn().mockImplementation(function (data) { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron", - status: "cancelled" - }); - }) - }, - refunds: { - create: jest.fn().mockImplementation(function (data) { - return Promise.resolve({ - id: "re_123", - payment_intent: "pi_lebron", - amount: 1000, - status: "succeeded" - }); - }) - } -}; -exports.StripeMock = StripeMock; -var stripe = jest.fn(function () { - return StripeMock; -}); -var _default = stripe; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/totals.js b/packages/medusa-payment-stripe/__mocks__/totals.js deleted file mode 100644 index 576d1231e94a1..0000000000000 --- a/packages/medusa-payment-stripe/__mocks__/totals.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.TotalsServiceMock = void 0; -var TotalsServiceMock = { - getTotal: jest.fn() -}; -exports.TotalsServiceMock = TotalsServiceMock; -var mock = jest.fn().mockImplementation(function () { - return TotalsServiceMock; -}); -var _default = mock; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/index.js b/packages/medusa-payment-stripe/api/index.js deleted file mode 100644 index 20411274f2adc..0000000000000 --- a/packages/medusa-payment-stripe/api/index.js +++ /dev/null @@ -1,20 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _express = require("express"); - -var _hooks = _interopRequireDefault(require("./routes/hooks")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -var _default = function _default(container) { - var app = (0, _express.Router)(); - (0, _hooks["default"])(app); - return app; -}; - -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/middlewares/await-middleware.js b/packages/medusa-payment-stripe/api/middlewares/await-middleware.js deleted file mode 100644 index 36ee66cf7eb15..0000000000000 --- a/packages/medusa-payment-stripe/api/middlewares/await-middleware.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _default = function _default(fn) { - return function () { - return fn.apply(void 0, arguments)["catch"](arguments.length <= 2 ? undefined : arguments[2]); - }; -}; - -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/middlewares/index.js b/packages/medusa-payment-stripe/api/middlewares/index.js deleted file mode 100644 index 1d5f479eb7e89..0000000000000 --- a/packages/medusa-payment-stripe/api/middlewares/index.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _awaitMiddleware = _interopRequireDefault(require("./await-middleware")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -var _default = { - wrap: _awaitMiddleware["default"] -}; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/routes/hooks/index.js b/packages/medusa-payment-stripe/api/routes/hooks/index.js deleted file mode 100644 index d18bf49c71547..0000000000000 --- a/packages/medusa-payment-stripe/api/routes/hooks/index.js +++ /dev/null @@ -1,27 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _express = require("express"); - -var _bodyParser = _interopRequireDefault(require("body-parser")); - -var _middlewares = _interopRequireDefault(require("../../middlewares")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -var route = (0, _express.Router)(); - -var _default = function _default(app) { - app.use("/stripe", route); - route.post("/hooks", // stripe constructEvent fails without body-parser - _bodyParser["default"].raw({ - type: "application/json" - }), _middlewares["default"].wrap(require("./stripe")["default"])); - return app; -}; - -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/routes/hooks/stripe.js b/packages/medusa-payment-stripe/api/routes/hooks/stripe.js deleted file mode 100644 index 2b0b08b4dde27..0000000000000 --- a/packages/medusa-payment-stripe/api/routes/hooks/stripe.js +++ /dev/null @@ -1,348 +0,0 @@ -"use strict"; - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _utils = require("@medusajs/medusa/dist/utils"); - -function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } - -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } - -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } - -var _default = /*#__PURE__*/function () { - var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(req, res) { - var signature, event, stripeProviderService, isPaymentCollection, handleCartPayments, _handleCartPayments, handlePaymentCollection, _handlePaymentCollection, paymentIntent, cartId, resourceId; - - return _regeneratorRuntime().wrap(function _callee6$(_context6) { - while (1) { - switch (_context6.prev = _context6.next) { - case 0: - _handlePaymentCollection = function _handlePaymentCollect2() { - _handlePaymentCollection = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(event, req, res, id, paymentIntentId) { - var _paycol$payments; - - var manager, paymentCollectionService, paycol, payment; - return _regeneratorRuntime().wrap(function _callee5$(_context5) { - while (1) { - switch (_context5.prev = _context5.next) { - case 0: - manager = req.scope.resolve("manager"); - paymentCollectionService = req.scope.resolve("paymentCollectionService"); - _context5.next = 4; - return paymentCollectionService.retrieve(id, { - relations: ["payments"] - })["catch"](function () { - return undefined; - }); - - case 4: - paycol = _context5.sent; - - if (!(paycol !== null && paycol !== void 0 && (_paycol$payments = paycol.payments) !== null && _paycol$payments !== void 0 && _paycol$payments.length)) { - _context5.next = 13; - break; - } - - if (!(event.type === "payment_intent.succeeded")) { - _context5.next = 13; - break; - } - - payment = paycol.payments.find(function (pay) { - return pay.data.id === paymentIntentId; - }); - - if (!(payment && !payment.captured_at)) { - _context5.next = 11; - break; - } - - _context5.next = 11; - return manager.transaction( /*#__PURE__*/function () { - var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(manager) { - return _regeneratorRuntime().wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - _context4.next = 2; - return paymentCollectionService.withTransaction(manager).capture(payment.id); - - case 2: - case "end": - return _context4.stop(); - } - } - }, _callee4); - })); - - return function (_x14) { - return _ref4.apply(this, arguments); - }; - }()); - - case 11: - res.sendStatus(200); - return _context5.abrupt("return"); - - case 13: - res.sendStatus(204); - - case 14: - case "end": - return _context5.stop(); - } - } - }, _callee5); - })); - return _handlePaymentCollection.apply(this, arguments); - }; - - handlePaymentCollection = function _handlePaymentCollect(_x7, _x8, _x9, _x10, _x11) { - return _handlePaymentCollection.apply(this, arguments); - }; - - _handleCartPayments = function _handleCartPayments3() { - _handleCartPayments = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(event, req, res, cartId) { - var manager, orderService, order, _err$detail, message, _err$detail2; - - return _regeneratorRuntime().wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - manager = req.scope.resolve("manager"); - orderService = req.scope.resolve("orderService"); - _context3.next = 4; - return orderService.retrieveByCartId(cartId)["catch"](function () { - return undefined; - }); - - case 4: - order = _context3.sent; - _context3.t0 = event.type; - _context3.next = _context3.t0 === "payment_intent.succeeded" ? 8 : _context3.t0 === "payment_intent.amount_capturable_updated" ? 19 : 31; - break; - - case 8: - if (!order) { - _context3.next = 17; - break; - } - - if (!(order.payment_status !== "captured")) { - _context3.next = 14; - break; - } - - _context3.next = 12; - return manager.transaction( /*#__PURE__*/function () { - var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(manager) { - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return orderService.withTransaction(manager).capturePayment(order.id); - - case 2: - case "end": - return _context.stop(); - } - } - }, _callee); - })); - - return function (_x12) { - return _ref2.apply(this, arguments); - }; - }()); - - case 12: - _context3.next = 15; - break; - - case 14: - return _context3.abrupt("return", res.sendStatus(200)); - - case 15: - _context3.next = 18; - break; - - case 17: - return _context3.abrupt("return", res.sendStatus(404)); - - case 18: - return _context3.abrupt("break", 33); - - case 19: - _context3.prev = 19; - _context3.next = 22; - return manager.transaction( /*#__PURE__*/function () { - var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(manager) { - return _regeneratorRuntime().wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - _context2.next = 2; - return paymentIntentAmountCapturableEventHandler({ - order: order, - cartId: cartId, - container: req.scope, - transactionManager: manager - }); - - case 2: - case "end": - return _context2.stop(); - } - } - }, _callee2); - })); - - return function (_x13) { - return _ref3.apply(this, arguments); - }; - }()); - - case 22: - _context3.next = 30; - break; - - case 24: - _context3.prev = 24; - _context3.t1 = _context3["catch"](19); - message = "Stripe webhook ".concat(event, " handling failed\n").concat((_err$detail = _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.detail) !== null && _err$detail !== void 0 ? _err$detail : _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.message); - - if ((_context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.code) === _utils.PostgresError.SERIALIZATION_FAILURE) { - message = "Stripe webhook ".concat(event, " handle failed. This can happen when this webhook is triggered during a cart completion and can be ignored. This event should be retried automatically.\n").concat((_err$detail2 = _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.detail) !== null && _err$detail2 !== void 0 ? _err$detail2 : _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.message); - } - - this.logger_.warn(message); - return _context3.abrupt("return", res.sendStatus(409)); - - case 30: - return _context3.abrupt("break", 33); - - case 31: - res.sendStatus(204); - return _context3.abrupt("return"); - - case 33: - res.sendStatus(200); - - case 34: - case "end": - return _context3.stop(); - } - } - }, _callee3, this, [[19, 24]]); - })); - return _handleCartPayments.apply(this, arguments); - }; - - handleCartPayments = function _handleCartPayments2(_x3, _x4, _x5, _x6) { - return _handleCartPayments.apply(this, arguments); - }; - - isPaymentCollection = function _isPaymentCollection(id) { - return id && id.startsWith("paycol"); - }; - - signature = req.headers["stripe-signature"]; - _context6.prev = 6; - stripeProviderService = req.scope.resolve("pp_stripe"); - event = stripeProviderService.constructWebhookEvent(req.body, signature); - _context6.next = 15; - break; - - case 11: - _context6.prev = 11; - _context6.t0 = _context6["catch"](6); - res.status(400).send("Webhook Error: ".concat(_context6.t0.message)); - return _context6.abrupt("return"); - - case 15: - paymentIntent = event.data.object; - cartId = paymentIntent.metadata.cart_id; // Backward compatibility - - resourceId = paymentIntent.metadata.resource_id; - - if (!isPaymentCollection(resourceId)) { - _context6.next = 23; - break; - } - - _context6.next = 21; - return handlePaymentCollection(event, req, res, resourceId, paymentIntent.id); - - case 21: - _context6.next = 25; - break; - - case 23: - _context6.next = 25; - return handleCartPayments(event, req, res, cartId !== null && cartId !== void 0 ? cartId : resourceId); - - case 25: - case "end": - return _context6.stop(); - } - } - }, _callee6, null, [[6, 11]]); - })); - - return function (_x, _x2) { - return _ref.apply(this, arguments); - }; -}(); - -exports["default"] = _default; - -function paymentIntentAmountCapturableEventHandler(_x15) { - return _paymentIntentAmountCapturableEventHandler.apply(this, arguments); -} - -function _paymentIntentAmountCapturableEventHandler() { - _paymentIntentAmountCapturableEventHandler = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(_ref5) { - var order, cartId, container, transactionManager, cartService, orderService, cartServiceTx; - return _regeneratorRuntime().wrap(function _callee7$(_context7) { - while (1) { - switch (_context7.prev = _context7.next) { - case 0: - order = _ref5.order, cartId = _ref5.cartId, container = _ref5.container, transactionManager = _ref5.transactionManager; - - if (order) { - _context7.next = 11; - break; - } - - cartService = container.resolve("cartService"); - orderService = container.resolve("orderService"); - cartServiceTx = cartService.withTransaction(transactionManager); - _context7.next = 7; - return cartServiceTx.setPaymentSession(cartId, "stripe"); - - case 7: - _context7.next = 9; - return cartServiceTx.authorizePayment(cartId); - - case 9: - _context7.next = 11; - return orderService.withTransaction(transactionManager).createFromCart(cartId); - - case 11: - case "end": - return _context7.stop(); - } - } - }, _callee7); - })); - return _paymentIntentAmountCapturableEventHandler.apply(this, arguments); -} \ No newline at end of file diff --git a/packages/medusa-payment-stripe/helpers/stripe-base.js b/packages/medusa-payment-stripe/helpers/stripe-base.js deleted file mode 100644 index 21e89b544f4c6..0000000000000 --- a/packages/medusa-payment-stripe/helpers/stripe-base.js +++ /dev/null @@ -1,772 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _medusa = require("@medusajs/medusa"); - -var _stripe = _interopRequireDefault(require("stripe")); - -var _dist = require("@medusajs/medusa/dist"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } - -function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } - -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } - -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var StripeBase = /*#__PURE__*/function (_AbstractPaymentServi) { - _inherits(StripeBase, _AbstractPaymentServi); - - var _super = _createSuper(StripeBase); - - function StripeBase(_, options) { - var _this; - - _classCallCheck(this, StripeBase); - - _this = _super.call(this, _, options); - /** - * Required Stripe options: - * { - * api_key: "stripe_secret_key", REQUIRED - * webhook_secret: "stripe_webhook_secret", REQUIRED - * // Use this flag to capture payment immediately (default is false) - * capture: true - * } - */ - - _this.options_ = options; - /** @private @const {Stripe} */ - - _this.stripe_ = (0, _stripe["default"])(options.api_key); - return _this; - } - - _createClass(StripeBase, [{ - key: "getPaymentIntentOptions", - value: function getPaymentIntentOptions() { - var _this$paymentIntentOp, _this$paymentIntentOp2, _this$paymentIntentOp3; - - var options = {}; - - if (this !== null && this !== void 0 && (_this$paymentIntentOp = this.paymentIntentOptions) !== null && _this$paymentIntentOp !== void 0 && _this$paymentIntentOp.capture_method) { - options.capture_method = this.paymentIntentOptions.capture_method; - } - - if (this !== null && this !== void 0 && (_this$paymentIntentOp2 = this.paymentIntentOptions) !== null && _this$paymentIntentOp2 !== void 0 && _this$paymentIntentOp2.setup_future_usage) { - options.setup_future_usage = this.paymentIntentOptions.setup_future_usage; - } - - if (this !== null && this !== void 0 && (_this$paymentIntentOp3 = this.paymentIntentOptions) !== null && _this$paymentIntentOp3 !== void 0 && _this$paymentIntentOp3.payment_method_types) { - options.payment_method_types = this.paymentIntentOptions.payment_method_types; - } - - return options; - } - /** - * Get payment session status - * statuses. - * @param {PaymentSessionData} paymentData - the data stored with the payment session - * @return {Promise} the status of the order - */ - - }, { - key: "getStatus", - value: function () { - var _getStatus = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(paymentData) { - var id, paymentIntent; - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - id = paymentData.id; - _context.next = 3; - return this.stripe_.paymentIntents.retrieve(id); - - case 3: - paymentIntent = _context.sent; - _context.t0 = paymentIntent.status; - _context.next = _context.t0 === "requires_payment_method" ? 7 : _context.t0 === "requires_confirmation" ? 7 : _context.t0 === "processing" ? 7 : _context.t0 === "requires_action" ? 8 : _context.t0 === "canceled" ? 9 : _context.t0 === "requires_capture" ? 10 : _context.t0 === "succeeded" ? 10 : 11; - break; - - case 7: - return _context.abrupt("return", _dist.PaymentSessionStatus.PENDING); - - case 8: - return _context.abrupt("return", _dist.PaymentSessionStatus.REQUIRES_MORE); - - case 9: - return _context.abrupt("return", _dist.PaymentSessionStatus.CANCELED); - - case 10: - return _context.abrupt("return", _dist.PaymentSessionStatus.AUTHORIZED); - - case 11: - return _context.abrupt("return", _dist.PaymentSessionStatus.PENDING); - - case 12: - case "end": - return _context.stop(); - } - } - }, _callee, this); - })); - - function getStatus(_x) { - return _getStatus.apply(this, arguments); - } - - return getStatus; - }() - /** - * Fetches a customers saved payment methods if registered in Stripe. - * @param {Customer} customer - customer to fetch saved cards for - * @return {Promise} saved payments methods - */ - - }, { - key: "retrieveSavedMethods", - value: function () { - var _retrieveSavedMethods = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(customer) { - var methods; - return _regeneratorRuntime().wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - if (!(customer.metadata && customer.metadata.stripe_id)) { - _context2.next = 5; - break; - } - - _context2.next = 3; - return this.stripe_.paymentMethods.list({ - customer: customer.metadata.stripe_id, - type: "card" - }); - - case 3: - methods = _context2.sent; - return _context2.abrupt("return", methods.data); - - case 5: - return _context2.abrupt("return", []); - - case 6: - case "end": - return _context2.stop(); - } - } - }, _callee2, this); - })); - - function retrieveSavedMethods(_x2) { - return _retrieveSavedMethods.apply(this, arguments); - } - - return retrieveSavedMethods; - }() - /** - * Fetches a Stripe customer - * @param {string} customerId - Stripe customer id - * @return {Promise} Stripe customer - */ - - }, { - key: "retrieveCustomer", - value: function () { - var _retrieveCustomer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(customerId) { - return _regeneratorRuntime().wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - if (customerId) { - _context3.next = 2; - break; - } - - return _context3.abrupt("return"); - - case 2: - _context3.next = 4; - return this.stripe_.customers.retrieve(customerId); - - case 4: - return _context3.abrupt("return", _context3.sent); - - case 5: - case "end": - return _context3.stop(); - } - } - }, _callee3, this); - })); - - function retrieveCustomer(_x3) { - return _retrieveCustomer.apply(this, arguments); - } - - return retrieveCustomer; - }() - /** - * Creates a Stripe payment intent. - * If customer is not registered in Stripe, we do so. - * @param {Cart & PaymentContext} context - context to use to create a payment for - * @return {Promise} Stripe payment intent - */ - - }, { - key: "createPayment", - value: function () { - var _createPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(context) { - var _cart_context$payment, _this$options_, _this$options_2, _customer$metadata, _customer$metadata3; - - var intentRequestData, cart_id, email, cart_context, currency_code, amount, resource_id, customer, intentRequest, _customer$metadata2, stripeCustomer, session_data; - - return _regeneratorRuntime().wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - intentRequestData = this.getPaymentIntentOptions(); - cart_id = context.id, email = context.email, cart_context = context.context, currency_code = context.currency_code, amount = context.amount, resource_id = context.resource_id, customer = context.customer; - intentRequest = _objectSpread({ - description: (_cart_context$payment = cart_context.payment_description) !== null && _cart_context$payment !== void 0 ? _cart_context$payment : (_this$options_ = this.options_) === null || _this$options_ === void 0 ? void 0 : _this$options_.payment_description, - amount: Math.round(amount), - currency: currency_code, - metadata: { - cart_id: cart_id, - resource_id: resource_id - }, - capture_method: this.options_.capture ? "automatic" : "manual" - }, intentRequestData); - - if ((_this$options_2 = this.options_) !== null && _this$options_2 !== void 0 && _this$options_2.automatic_payment_methods) { - intentRequest.automatic_payment_methods = { - enabled: true - }; - } - - if (!(customer !== null && customer !== void 0 && (_customer$metadata = customer.metadata) !== null && _customer$metadata !== void 0 && _customer$metadata.stripe_id)) { - _context4.next = 8; - break; - } - - intentRequest.customer = customer === null || customer === void 0 ? void 0 : (_customer$metadata2 = customer.metadata) === null || _customer$metadata2 === void 0 ? void 0 : _customer$metadata2.stripe_id; - _context4.next = 12; - break; - - case 8: - _context4.next = 10; - return this.stripe_.customers.create({ - email: email - }); - - case 10: - stripeCustomer = _context4.sent; - intentRequest.customer = stripeCustomer.id; - - case 12: - _context4.next = 14; - return this.stripe_.paymentIntents.create(intentRequest); - - case 14: - session_data = _context4.sent; - return _context4.abrupt("return", { - session_data: session_data, - update_requests: customer !== null && customer !== void 0 && (_customer$metadata3 = customer.metadata) !== null && _customer$metadata3 !== void 0 && _customer$metadata3.stripe_id ? undefined : { - customer_metadata: { - stripe_id: intentRequest.customer - } - } - }); - - case 16: - case "end": - return _context4.stop(); - } - } - }, _callee4, this); - })); - - function createPayment(_x4) { - return _createPayment.apply(this, arguments); - } - - return createPayment; - }() - /** - * Retrieves Stripe payment intent. - * @param {PaymentData} data - the data of the payment to retrieve - * @return {Promise} Stripe payment intent - */ - - }, { - key: "retrievePayment", - value: function () { - var _retrievePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(data) { - return _regeneratorRuntime().wrap(function _callee5$(_context5) { - while (1) { - switch (_context5.prev = _context5.next) { - case 0: - _context5.next = 2; - return this.stripe_.paymentIntents.retrieve(data.id); - - case 2: - return _context5.abrupt("return", _context5.sent); - - case 3: - case "end": - return _context5.stop(); - } - } - }, _callee5, this); - })); - - function retrievePayment(_x5) { - return _retrievePayment.apply(this, arguments); - } - - return retrievePayment; - }() - /** - * Gets a Stripe payment intent and returns it. - * @param {PaymentSession} paymentSession - the data of the payment to retrieve - * @return {Promise} Stripe payment intent - */ - - }, { - key: "getPaymentData", - value: function () { - var _getPaymentData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(paymentSession) { - return _regeneratorRuntime().wrap(function _callee6$(_context6) { - while (1) { - switch (_context6.prev = _context6.next) { - case 0: - _context6.next = 2; - return this.stripe_.paymentIntents.retrieve(paymentSession.data.id); - - case 2: - return _context6.abrupt("return", _context6.sent); - - case 3: - case "end": - return _context6.stop(); - } - } - }, _callee6, this); - })); - - function getPaymentData(_x6) { - return _getPaymentData.apply(this, arguments); - } - - return getPaymentData; - }() - /** - * Authorizes Stripe payment intent by simply returning - * the status for the payment intent in use. - * @param {PaymentSession} paymentSession - payment session data - * @param {Data} context - properties relevant to current context - * @return {Promise<{ data: PaymentSessionData; status: PaymentSessionStatus }>} result with data and status - */ - - }, { - key: "authorizePayment", - value: function () { - var _authorizePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(paymentSession) { - var context, - stat, - _args7 = arguments; - return _regeneratorRuntime().wrap(function _callee7$(_context7) { - while (1) { - switch (_context7.prev = _context7.next) { - case 0: - context = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {}; - _context7.next = 3; - return this.getStatus(paymentSession.data); - - case 3: - stat = _context7.sent; - return _context7.abrupt("return", { - data: paymentSession.data, - status: stat - }); - - case 5: - case "end": - return _context7.stop(); - } - } - }, _callee7, this); - })); - - function authorizePayment(_x7) { - return _authorizePayment.apply(this, arguments); - } - - return authorizePayment; - }() - }, { - key: "updatePaymentData", - value: function () { - var _updatePaymentData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(sessionData, update) { - return _regeneratorRuntime().wrap(function _callee8$(_context8) { - while (1) { - switch (_context8.prev = _context8.next) { - case 0: - _context8.next = 2; - return this.stripe_.paymentIntents.update(sessionData.id, _objectSpread({}, update.data)); - - case 2: - return _context8.abrupt("return", _context8.sent); - - case 3: - case "end": - return _context8.stop(); - } - } - }, _callee8, this); - })); - - function updatePaymentData(_x8, _x9) { - return _updatePaymentData.apply(this, arguments); - } - - return updatePaymentData; - }() - /** - * Updates Stripe payment intent. - * @param {PaymentSessionData} paymentSessionData - payment session data. - * @param {Cart & PaymentContext} context - * @return {Promise} Stripe payment intent - */ - - }, { - key: "updatePayment", - value: function () { - var _updatePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(paymentSessionData, context) { - var _customer$metadata4; - - var amount, customer, stripeId; - return _regeneratorRuntime().wrap(function _callee9$(_context9) { - while (1) { - switch (_context9.prev = _context9.next) { - case 0: - amount = context.amount, customer = context.customer; - stripeId = (customer === null || customer === void 0 ? void 0 : (_customer$metadata4 = customer.metadata) === null || _customer$metadata4 === void 0 ? void 0 : _customer$metadata4.stripe_id) || undefined; - - if (!(stripeId !== paymentSessionData.customer)) { - _context9.next = 8; - break; - } - - _context9.next = 5; - return this.createPayment(context); - - case 5: - return _context9.abrupt("return", _context9.sent); - - case 8: - if (!(amount && paymentSessionData.amount === Math.round(amount))) { - _context9.next = 10; - break; - } - - return _context9.abrupt("return", paymentSessionData); - - case 10: - _context9.next = 12; - return this.stripe_.paymentIntents.update(paymentSessionData.id, { - amount: Math.round(amount) - }); - - case 12: - return _context9.abrupt("return", _context9.sent); - - case 13: - case "end": - return _context9.stop(); - } - } - }, _callee9, this); - })); - - function updatePayment(_x10, _x11) { - return _updatePayment.apply(this, arguments); - } - - return updatePayment; - }() - }, { - key: "deletePayment", - value: function () { - var _deletePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(payment) { - var id; - return _regeneratorRuntime().wrap(function _callee10$(_context10) { - while (1) { - switch (_context10.prev = _context10.next) { - case 0: - id = payment.data.id; - return _context10.abrupt("return", this.stripe_.paymentIntents.cancel(id)["catch"](function (err) { - if (err.statusCode === 400) { - return; - } - - throw err; - })); - - case 2: - case "end": - return _context10.stop(); - } - } - }, _callee10, this); - })); - - function deletePayment(_x12) { - return _deletePayment.apply(this, arguments); - } - - return deletePayment; - }() - /** - * Updates customer of Stripe payment intent. - * @param {string} paymentIntentId - id of payment intent to update - * @param {string} customerId - id of \ Stripe customer - * @return {object} Stripe payment intent - */ - - }, { - key: "updatePaymentIntentCustomer", - value: function () { - var _updatePaymentIntentCustomer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(paymentIntentId, customerId) { - return _regeneratorRuntime().wrap(function _callee11$(_context11) { - while (1) { - switch (_context11.prev = _context11.next) { - case 0: - _context11.next = 2; - return this.stripe_.paymentIntents.update(paymentIntentId, { - customer: customerId - }); - - case 2: - return _context11.abrupt("return", _context11.sent); - - case 3: - case "end": - return _context11.stop(); - } - } - }, _callee11, this); - })); - - function updatePaymentIntentCustomer(_x13, _x14) { - return _updatePaymentIntentCustomer.apply(this, arguments); - } - - return updatePaymentIntentCustomer; - }() - /** - * Captures payment for Stripe payment intent. - * @param {Payment} payment - payment method data from cart - * @return {Promise} Stripe payment intent - */ - - }, { - key: "capturePayment", - value: function () { - var _capturePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee12(payment) { - var id, intent; - return _regeneratorRuntime().wrap(function _callee12$(_context12) { - while (1) { - switch (_context12.prev = _context12.next) { - case 0: - id = payment.data.id; - _context12.prev = 1; - _context12.next = 4; - return this.stripe_.paymentIntents.capture(id); - - case 4: - intent = _context12.sent; - return _context12.abrupt("return", intent); - - case 8: - _context12.prev = 8; - _context12.t0 = _context12["catch"](1); - - if (!(_context12.t0.code === "payment_intent_unexpected_state")) { - _context12.next = 13; - break; - } - - if (!(_context12.t0.payment_intent.status === "succeeded")) { - _context12.next = 13; - break; - } - - return _context12.abrupt("return", _context12.t0.payment_intent); - - case 13: - throw _context12.t0; - - case 14: - case "end": - return _context12.stop(); - } - } - }, _callee12, this, [[1, 8]]); - })); - - function capturePayment(_x15) { - return _capturePayment.apply(this, arguments); - } - - return capturePayment; - }() - /** - * Refunds payment for Stripe payment intent. - * @param {Payment} payment - payment method data from cart - * @param {number} refundAmount - amount to refund - * @return {Promise} refunded payment intent - */ - - }, { - key: "refundPayment", - value: function () { - var _refundPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee13(payment, amountToRefund) { - var id; - return _regeneratorRuntime().wrap(function _callee13$(_context13) { - while (1) { - switch (_context13.prev = _context13.next) { - case 0: - id = payment.data.id; - _context13.next = 3; - return this.stripe_.refunds.create({ - amount: Math.round(amountToRefund), - payment_intent: id - }); - - case 3: - return _context13.abrupt("return", payment.data); - - case 4: - case "end": - return _context13.stop(); - } - } - }, _callee13, this); - })); - - function refundPayment(_x16, _x17) { - return _refundPayment.apply(this, arguments); - } - - return refundPayment; - }() - /** - * Cancels payment for Stripe payment intent. - * @param {Payment} payment - payment method data from cart - * @return {Promise} canceled payment intent - */ - - }, { - key: "cancelPayment", - value: function () { - var _cancelPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee14(payment) { - var id; - return _regeneratorRuntime().wrap(function _callee14$(_context14) { - while (1) { - switch (_context14.prev = _context14.next) { - case 0: - id = payment.data.id; - _context14.prev = 1; - _context14.next = 4; - return this.stripe_.paymentIntents.cancel(id); - - case 4: - return _context14.abrupt("return", _context14.sent); - - case 7: - _context14.prev = 7; - _context14.t0 = _context14["catch"](1); - - if (!(_context14.t0.payment_intent.status === "canceled")) { - _context14.next = 11; - break; - } - - return _context14.abrupt("return", _context14.t0.payment_intent); - - case 11: - throw _context14.t0; - - case 12: - case "end": - return _context14.stop(); - } - } - }, _callee14, this, [[1, 7]]); - })); - - function cancelPayment(_x18) { - return _cancelPayment.apply(this, arguments); - } - - return cancelPayment; - }() - /** - * Constructs Stripe Webhook event - * @param {object} data - the data of the webhook request: req.body - * @param {object} signature - the Stripe signature on the event, that - * ensures integrity of the webhook event - * @return {object} Stripe Webhook event - */ - - }, { - key: "constructWebhookEvent", - value: function constructWebhookEvent(data, signature) { - return this.stripe_.webhooks.constructEvent(data, signature, this.options_.webhook_secret); - } - }]); - - return StripeBase; -}(_medusa.AbstractPaymentService); - -_defineProperty(StripeBase, "identifier", null); - -var _default = StripeBase; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js b/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js deleted file mode 100644 index 9f58040cea0db..0000000000000 --- a/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js +++ /dev/null @@ -1,63 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.StripeProviderServiceMock = void 0; - -var _medusaTestUtils = require("medusa-test-utils"); - -var StripeProviderServiceMock = { - retrievePayment: jest.fn().mockImplementation(function (payData) { - if (payData.id === "pi_123456789") { - return Promise.resolve({ - id: "pi", - customer: "cus_123456789" - }); - } - - if (payData.id === "pi_no") { - return Promise.resolve({ - id: "pi_no" - }); - } - - return Promise.resolve(undefined); - }), - cancelPayment: jest.fn().mockImplementation(function (cart) { - return Promise.resolve(); - }), - updatePaymentIntentCustomer: jest.fn().mockImplementation(function (cart) { - return Promise.resolve(); - }), - retrieveCustomer: jest.fn().mockImplementation(function (customerId) { - if (customerId === "cus_123456789_new") { - return Promise.resolve({ - id: "cus_123456789_new" - }); - } - - return Promise.resolve(undefined); - }), - createCustomer: jest.fn().mockImplementation(function (customer) { - if (customer._id === _medusaTestUtils.IdMap.getId("vvd")) { - return Promise.resolve({ - id: "cus_123456789_new_vvd" - }); - } - - return Promise.resolve(undefined); - }), - createPayment: jest.fn().mockImplementation(function (cart) { - return Promise.resolve({ - id: "pi_new", - customer: "cus_123456789_new" - }); - }) -}; -exports.StripeProviderServiceMock = StripeProviderServiceMock; -var mock = jest.fn().mockImplementation(function () { - return StripeProviderServiceMock; -}); -var _default = mock; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-bancontact.js b/packages/medusa-payment-stripe/services/stripe-bancontact.js deleted file mode 100644 index 1fef577f0fa3c..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-bancontact.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var BancontactProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(BancontactProviderService, _StripeBase); - - var _super = _createSuper(BancontactProviderService); - - function BancontactProviderService(_, options) { - _classCallCheck(this, BancontactProviderService); - - return _super.call(this, _, options); - } - - _createClass(BancontactProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return { - payment_method_types: ["bancontact"], - capture_method: "automatic" - }; - } - }]); - - return BancontactProviderService; -}(_stripeBase["default"]); - -_defineProperty(BancontactProviderService, "identifier", "stripe-bancontact"); - -var _default = BancontactProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-blik.js b/packages/medusa-payment-stripe/services/stripe-blik.js deleted file mode 100644 index 0b05d94eb0b4c..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-blik.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var BlikProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(BlikProviderService, _StripeBase); - - var _super = _createSuper(BlikProviderService); - - function BlikProviderService(_, options) { - _classCallCheck(this, BlikProviderService); - - return _super.call(this, _, options); - } - - _createClass(BlikProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return { - payment_method_types: ["blik"], - capture_method: "automatic" - }; - } - }]); - - return BlikProviderService; -}(_stripeBase["default"]); - -_defineProperty(BlikProviderService, "identifier", "stripe-blik"); - -var _default = BlikProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-giropay.js b/packages/medusa-payment-stripe/services/stripe-giropay.js deleted file mode 100644 index 8c7cb1587b923..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-giropay.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var GiropayProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(GiropayProviderService, _StripeBase); - - var _super = _createSuper(GiropayProviderService); - - function GiropayProviderService(_, options) { - _classCallCheck(this, GiropayProviderService); - - return _super.call(this, _, options); - } - - _createClass(GiropayProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return { - payment_method_types: ["giropay"], - capture_method: "automatic" - }; - } - }]); - - return GiropayProviderService; -}(_stripeBase["default"]); - -_defineProperty(GiropayProviderService, "identifier", "stripe-giropay"); - -var _default = GiropayProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-ideal.js b/packages/medusa-payment-stripe/services/stripe-ideal.js deleted file mode 100644 index ced727f5fc289..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-ideal.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var IdealProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(IdealProviderService, _StripeBase); - - var _super = _createSuper(IdealProviderService); - - function IdealProviderService(_, options) { - _classCallCheck(this, IdealProviderService); - - return _super.call(this, _, options); - } - - _createClass(IdealProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return { - payment_method_types: ["ideal"], - capture_method: "automatic" - }; - } - }]); - - return IdealProviderService; -}(_stripeBase["default"]); - -_defineProperty(IdealProviderService, "identifier", "stripe-ideal"); - -var _default = IdealProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-provider.js b/packages/medusa-payment-stripe/services/stripe-provider.js deleted file mode 100644 index f201e497afbf7..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-provider.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var StripeProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(StripeProviderService, _StripeBase); - - var _super = _createSuper(StripeProviderService); - - function StripeProviderService(_, options) { - _classCallCheck(this, StripeProviderService); - - return _super.call(this, _, options); - } - - _createClass(StripeProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return {}; - } - }]); - - return StripeProviderService; -}(_stripeBase["default"]); - -_defineProperty(StripeProviderService, "identifier", "stripe"); - -var _default = StripeProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-przelewy24.js b/packages/medusa-payment-stripe/services/stripe-przelewy24.js deleted file mode 100644 index 00bb7df48c610..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-przelewy24.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var Przelewy24ProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(Przelewy24ProviderService, _StripeBase); - - var _super = _createSuper(Przelewy24ProviderService); - - function Przelewy24ProviderService(_, options) { - _classCallCheck(this, Przelewy24ProviderService); - - return _super.call(this, _, options); - } - - _createClass(Przelewy24ProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return { - payment_method_types: ["p24"], - capture_method: "automatic" - }; - } - }]); - - return Przelewy24ProviderService; -}(_stripeBase["default"]); - -_defineProperty(Przelewy24ProviderService, "identifier", "stripe-przelewy24"); - -var _default = Przelewy24ProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/subscribers/cart.js b/packages/medusa-payment-stripe/subscribers/cart.js deleted file mode 100644 index 23d641c870710..0000000000000 --- a/packages/medusa-payment-stripe/subscribers/cart.js +++ /dev/null @@ -1,125 +0,0 @@ -"use strict"; - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } - -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } - -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -var CartSubscriber = /*#__PURE__*/function () { - function CartSubscriber(_ref) { - var _this = this; - - var cartService = _ref.cartService, - customerService = _ref.customerService, - paymentProviderService = _ref.paymentProviderService, - eventBusService = _ref.eventBusService; - - _classCallCheck(this, CartSubscriber); - - this.cartService_ = cartService; - this.customerService_ = customerService; - this.paymentProviderService_ = paymentProviderService; - this.eventBus_ = eventBusService; - this.eventBus_.subscribe("cart.customer_updated", /*#__PURE__*/function () { - var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(cart) { - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return _this.onCustomerUpdated(cart); - - case 2: - case "end": - return _context.stop(); - } - } - }, _callee); - })); - - return function (_x) { - return _ref2.apply(this, arguments); - }; - }()); - } - - _createClass(CartSubscriber, [{ - key: "onCustomerUpdated", - value: function () { - var _onCustomerUpdated = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(cartId) { - var _cart$payment_session; - - var cart, session; - return _regeneratorRuntime().wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - _context2.next = 2; - return this.cartService_.retrieve(cartId, { - select: ["subtotal", "tax_total", "shipping_total", "discount_total", "total"], - relations: ["items", "billing_address", "shipping_address", "region", "region.payment_providers", "items", "items.adjustments", "payment_sessions", "customer"] - }); - - case 2: - cart = _context2.sent; - - if ((_cart$payment_session = cart.payment_sessions) !== null && _cart$payment_session !== void 0 && _cart$payment_session.length) { - _context2.next = 5; - break; - } - - return _context2.abrupt("return", Promise.resolve()); - - case 5: - session = cart.payment_sessions.find(function (ps) { - return ps.provider_id === "stripe"; - }); - - if (!session) { - _context2.next = 10; - break; - } - - _context2.next = 9; - return this.paymentProviderService_.updateSession(session, cart); - - case 9: - return _context2.abrupt("return", _context2.sent); - - case 10: - case "end": - return _context2.stop(); - } - } - }, _callee2, this); - })); - - function onCustomerUpdated(_x2) { - return _onCustomerUpdated.apply(this, arguments); - } - - return onCustomerUpdated; - }() - }]); - - return CartSubscriber; -}(); - -var _default = CartSubscriber; -exports["default"] = _default; \ No newline at end of file From 48bfafe9647b61968ab71476c0b41755ab6796f3 Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Mon, 27 Feb 2023 15:16:05 +0100 Subject: [PATCH 29/36] Create eleven-cycles-mate.md --- .changeset/eleven-cycles-mate.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/eleven-cycles-mate.md diff --git a/.changeset/eleven-cycles-mate.md b/.changeset/eleven-cycles-mate.md new file mode 100644 index 0000000000000..78c001e057042 --- /dev/null +++ b/.changeset/eleven-cycles-mate.md @@ -0,0 +1,7 @@ +--- +"medusa-payment-paypal": patch +"medusa-payment-stripe": patch +"@medusajs/medusa": patch +--- + +feat(medusa-payment-stripe): Implement payment processor API on stripe plugin and fix web hook issues From 409e89971aeaf873feeefbbeaa163defbc330496 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Mon, 27 Feb 2023 16:27:00 +0100 Subject: [PATCH 30/36] cealnup 1/2 --- .../medusa-payment-stripe/__mocks__/cart.js | 195 +++++ .../__mocks__/customer.js | 45 + .../__mocks__/eventbus.js | 16 + .../medusa-payment-stripe/__mocks__/stripe.js | 98 +++ .../medusa-payment-stripe/__mocks__/totals.js | 15 + packages/medusa-payment-stripe/api/index.js | 20 + .../api/middlewares/await-middleware.js | 14 + .../api/middlewares/index.js | 15 + .../api/routes/hooks/index.js | 27 + .../api/routes/hooks/stripe.js | 348 ++++++++ .../helpers/stripe-base.js | 772 ++++++++++++++++++ .../services/__mocks__/stripe-provider.js | 63 ++ .../services/stripe-bancontact.js | 65 ++ .../services/stripe-blik.js | 65 ++ .../services/stripe-giropay.js | 65 ++ .../services/stripe-ideal.js | 65 ++ .../services/stripe-provider.js | 62 ++ .../services/stripe-przelewy24.js | 65 ++ .../src/services/stripe-bancontact.ts | 4 +- .../src/services/stripe-blik.ts | 4 +- .../src/services/stripe-giropay.ts | 4 +- .../src/services/stripe-ideal.ts | 4 +- .../src/services/stripe-provider.ts | 4 +- .../src/services/stripe-przelewy24.ts | 4 +- packages/medusa-payment-stripe/src/types.ts | 9 + .../medusa-payment-stripe/subscribers/cart.js | 125 +++ packages/medusa/src/api/middlewares/index.ts | 2 +- .../medusa/src/loaders/helpers/plugins.ts | 10 +- 28 files changed, 2165 insertions(+), 20 deletions(-) create mode 100644 packages/medusa-payment-stripe/__mocks__/cart.js create mode 100644 packages/medusa-payment-stripe/__mocks__/customer.js create mode 100644 packages/medusa-payment-stripe/__mocks__/eventbus.js create mode 100644 packages/medusa-payment-stripe/__mocks__/stripe.js create mode 100644 packages/medusa-payment-stripe/__mocks__/totals.js create mode 100644 packages/medusa-payment-stripe/api/index.js create mode 100644 packages/medusa-payment-stripe/api/middlewares/await-middleware.js create mode 100644 packages/medusa-payment-stripe/api/middlewares/index.js create mode 100644 packages/medusa-payment-stripe/api/routes/hooks/index.js create mode 100644 packages/medusa-payment-stripe/api/routes/hooks/stripe.js create mode 100644 packages/medusa-payment-stripe/helpers/stripe-base.js create mode 100644 packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js create mode 100644 packages/medusa-payment-stripe/services/stripe-bancontact.js create mode 100644 packages/medusa-payment-stripe/services/stripe-blik.js create mode 100644 packages/medusa-payment-stripe/services/stripe-giropay.js create mode 100644 packages/medusa-payment-stripe/services/stripe-ideal.js create mode 100644 packages/medusa-payment-stripe/services/stripe-provider.js create mode 100644 packages/medusa-payment-stripe/services/stripe-przelewy24.js create mode 100644 packages/medusa-payment-stripe/subscribers/cart.js diff --git a/packages/medusa-payment-stripe/__mocks__/cart.js b/packages/medusa-payment-stripe/__mocks__/cart.js new file mode 100644 index 0000000000000..eebabc2ef0bd5 --- /dev/null +++ b/packages/medusa-payment-stripe/__mocks__/cart.js @@ -0,0 +1,195 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.carts = exports.CartServiceMock = void 0; + +var _medusaTestUtils = require("medusa-test-utils"); + +var carts = { + emptyCart: { + id: _medusaTestUtils.IdMap.getId("emptyCart"), + items: [], + region_id: _medusaTestUtils.IdMap.getId("testRegion"), + customer_id: "test-customer", + payment_sessions: [], + shipping_options: [{ + id: _medusaTestUtils.IdMap.getId("freeShipping"), + profile_id: "default_profile", + data: { + some_data: "yes" + } + }] + }, + frCart: { + id: _medusaTestUtils.IdMap.getId("fr-cart"), + email: "lebron@james.com", + title: "test", + region_id: _medusaTestUtils.IdMap.getId("region-france"), + items: [{ + id: _medusaTestUtils.IdMap.getId("line"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + unit_price: 8, + variant: { + id: _medusaTestUtils.IdMap.getId("eur-8-us-10") + }, + product: { + id: _medusaTestUtils.IdMap.getId("product") + }, + // { + // unit_price: 10, + // variant: { + // id: IdMap.getId("eur-10-us-12"), + // }, + // product: { + // id: IdMap.getId("product"), + // }, + // quantity: 1, + // }, + quantity: 10 + }, { + id: _medusaTestUtils.IdMap.getId("existingLine"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + unit_price: 10, + variant: { + id: _medusaTestUtils.IdMap.getId("eur-10-us-12") + }, + product: { + id: _medusaTestUtils.IdMap.getId("product") + }, + quantity: 1 + }], + shipping_methods: [{ + id: _medusaTestUtils.IdMap.getId("freeShipping"), + profile_id: "default_profile" + }], + shipping_options: [{ + id: _medusaTestUtils.IdMap.getId("freeShipping"), + profile_id: "default_profile" + }], + payment_sessions: [{ + provider_id: "stripe", + data: { + id: "pi_123456789", + customer: _medusaTestUtils.IdMap.getId("not-lebron") + } + }], + payment_method: { + provider_id: "stripe", + data: { + id: "pi_123456789", + customer: _medusaTestUtils.IdMap.getId("not-lebron") + } + }, + shipping_address: {}, + billing_address: {}, + discounts: [], + customer_id: _medusaTestUtils.IdMap.getId("lebron"), + context: {} + }, + frCartNoStripeCustomer: { + id: _medusaTestUtils.IdMap.getId("fr-cart-no-customer"), + title: "test", + region_id: _medusaTestUtils.IdMap.getId("region-france"), + items: [{ + id: _medusaTestUtils.IdMap.getId("line"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + content: [{ + unit_price: 8, + variant: { + id: _medusaTestUtils.IdMap.getId("eur-8-us-10") + }, + product: { + id: _medusaTestUtils.IdMap.getId("product") + }, + quantity: 1 + }, { + unit_price: 10, + variant: { + id: _medusaTestUtils.IdMap.getId("eur-10-us-12") + }, + product: { + id: _medusaTestUtils.IdMap.getId("product") + }, + quantity: 1 + }], + quantity: 10 + }, { + id: _medusaTestUtils.IdMap.getId("existingLine"), + title: "merge line", + description: "This is a new line", + thumbnail: "test-img-yeah.com/thumb", + content: { + unit_price: 10, + variant: { + id: _medusaTestUtils.IdMap.getId("eur-10-us-12") + }, + product: { + id: _medusaTestUtils.IdMap.getId("product") + }, + quantity: 1 + }, + quantity: 10 + }], + shipping_methods: [{ + id: _medusaTestUtils.IdMap.getId("freeShipping"), + profile_id: "default_profile" + }], + shipping_options: [{ + id: _medusaTestUtils.IdMap.getId("freeShipping"), + profile_id: "default_profile" + }], + payment_sessions: [{ + provider_id: "stripe", + data: { + id: "pi_no", + customer: _medusaTestUtils.IdMap.getId("not-lebron") + } + }], + payment_method: { + provider_id: "stripe", + data: { + id: "pi_no", + customer: _medusaTestUtils.IdMap.getId("not-lebron") + } + }, + shipping_address: {}, + billing_address: {}, + discounts: [], + customer_id: _medusaTestUtils.IdMap.getId("vvd") + } +}; +exports.carts = carts; +var CartServiceMock = { + retrieve: jest.fn().mockImplementation(function (cartId) { + if (cartId === _medusaTestUtils.IdMap.getId("fr-cart")) { + return Promise.resolve(carts.frCart); + } + + if (cartId === _medusaTestUtils.IdMap.getId("fr-cart-no-customer")) { + return Promise.resolve(carts.frCartNoStripeCustomer); + } + + if (cartId === _medusaTestUtils.IdMap.getId("emptyCart")) { + return Promise.resolve(carts.emptyCart); + } + + return Promise.resolve(undefined); + }), + updatePaymentSession: jest.fn().mockImplementation(function (cartId, stripe, paymentIntent) { + return Promise.resolve(); + }) +}; +exports.CartServiceMock = CartServiceMock; +var mock = jest.fn().mockImplementation(function () { + return CartServiceMock; +}); +var _default = mock; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/customer.js b/packages/medusa-payment-stripe/__mocks__/customer.js new file mode 100644 index 0000000000000..72cd299080511 --- /dev/null +++ b/packages/medusa-payment-stripe/__mocks__/customer.js @@ -0,0 +1,45 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.CustomerServiceMock = void 0; + +var _medusaTestUtils = require("medusa-test-utils"); + +var CustomerServiceMock = { + retrieve: jest.fn().mockImplementation(function (id) { + if (id === _medusaTestUtils.IdMap.getId("lebron")) { + return Promise.resolve({ + _id: _medusaTestUtils.IdMap.getId("lebron"), + first_name: "LeBron", + last_name: "James", + email: "lebron@james.com", + password_hash: "1234", + metadata: { + stripe_id: "cus_123456789_new" + } + }); + } + + if (id === _medusaTestUtils.IdMap.getId("vvd")) { + return Promise.resolve({ + _id: _medusaTestUtils.IdMap.getId("vvd"), + first_name: "Virgil", + last_name: "Van Dijk", + email: "virg@vvd.com", + password_hash: "1234", + metadata: {} + }); + } + + return Promise.resolve(undefined); + }), + setMetadata: jest.fn().mockReturnValue(Promise.resolve()) +}; +exports.CustomerServiceMock = CustomerServiceMock; +var mock = jest.fn().mockImplementation(function () { + return CustomerServiceMock; +}); +var _default = mock; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/eventbus.js b/packages/medusa-payment-stripe/__mocks__/eventbus.js new file mode 100644 index 0000000000000..b445554189888 --- /dev/null +++ b/packages/medusa-payment-stripe/__mocks__/eventbus.js @@ -0,0 +1,16 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.EventBusServiceMock = void 0; +var EventBusServiceMock = { + emit: jest.fn(), + subscribe: jest.fn() +}; +exports.EventBusServiceMock = EventBusServiceMock; +var mock = jest.fn().mockImplementation(function () { + return EventBusServiceMock; +}); +var _default = mock; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/stripe.js b/packages/medusa-payment-stripe/__mocks__/stripe.js new file mode 100644 index 0000000000000..df9dbbb98c267 --- /dev/null +++ b/packages/medusa-payment-stripe/__mocks__/stripe.js @@ -0,0 +1,98 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.StripeMock = void 0; +var StripeMock = { + customers: { + create: jest.fn().mockImplementation(function (data) { + if (data.email === "virg@vvd.com") { + return Promise.resolve({ + id: "cus_vvd", + email: "virg@vvd.com" + }); + } + + if (data.email === "lebron@james.com") { + return Promise.resolve({ + id: "cus_lebron", + email: "lebron@james.com" + }); + } + }) + }, + paymentIntents: { + create: jest.fn().mockImplementation(function (data) { + if (data.customer === "cus_123456789_new") { + return Promise.resolve({ + id: "pi_lebron", + amount: 100, + customer: "cus_123456789_new", + description: data === null || data === void 0 ? void 0 : data.description + }); + } + + if (data.customer === "cus_lebron") { + return Promise.resolve({ + id: "pi_lebron", + amount: 100, + customer: "cus_lebron", + description: data === null || data === void 0 ? void 0 : data.description + }); + } + }), + retrieve: jest.fn().mockImplementation(function (data) { + return Promise.resolve({ + id: "pi_lebron", + customer: "cus_lebron" + }); + }), + update: jest.fn().mockImplementation(function (pi, data) { + if (data.customer === "cus_lebron_2") { + return Promise.resolve({ + id: "pi_lebron", + customer: "cus_lebron_2", + amount: 1000 + }); + } + + return Promise.resolve({ + id: "pi_lebron", + customer: "cus_lebron", + amount: 1000 + }); + }), + capture: jest.fn().mockImplementation(function (data) { + return Promise.resolve({ + id: "pi_lebron", + customer: "cus_lebron", + amount: 1000, + status: "succeeded" + }); + }), + cancel: jest.fn().mockImplementation(function (data) { + return Promise.resolve({ + id: "pi_lebron", + customer: "cus_lebron", + status: "cancelled" + }); + }) + }, + refunds: { + create: jest.fn().mockImplementation(function (data) { + return Promise.resolve({ + id: "re_123", + payment_intent: "pi_lebron", + amount: 1000, + status: "succeeded" + }); + }) + } +}; +exports.StripeMock = StripeMock; +var stripe = jest.fn(function () { + return StripeMock; +}); +var _default = stripe; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/totals.js b/packages/medusa-payment-stripe/__mocks__/totals.js new file mode 100644 index 0000000000000..576d1231e94a1 --- /dev/null +++ b/packages/medusa-payment-stripe/__mocks__/totals.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.TotalsServiceMock = void 0; +var TotalsServiceMock = { + getTotal: jest.fn() +}; +exports.TotalsServiceMock = TotalsServiceMock; +var mock = jest.fn().mockImplementation(function () { + return TotalsServiceMock; +}); +var _default = mock; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/index.js b/packages/medusa-payment-stripe/api/index.js new file mode 100644 index 0000000000000..20411274f2adc --- /dev/null +++ b/packages/medusa-payment-stripe/api/index.js @@ -0,0 +1,20 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _express = require("express"); + +var _hooks = _interopRequireDefault(require("./routes/hooks")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +var _default = function _default(container) { + var app = (0, _express.Router)(); + (0, _hooks["default"])(app); + return app; +}; + +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/middlewares/await-middleware.js b/packages/medusa-payment-stripe/api/middlewares/await-middleware.js new file mode 100644 index 0000000000000..36ee66cf7eb15 --- /dev/null +++ b/packages/medusa-payment-stripe/api/middlewares/await-middleware.js @@ -0,0 +1,14 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _default = function _default(fn) { + return function () { + return fn.apply(void 0, arguments)["catch"](arguments.length <= 2 ? undefined : arguments[2]); + }; +}; + +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/middlewares/index.js b/packages/medusa-payment-stripe/api/middlewares/index.js new file mode 100644 index 0000000000000..1d5f479eb7e89 --- /dev/null +++ b/packages/medusa-payment-stripe/api/middlewares/index.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _awaitMiddleware = _interopRequireDefault(require("./await-middleware")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +var _default = { + wrap: _awaitMiddleware["default"] +}; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/routes/hooks/index.js b/packages/medusa-payment-stripe/api/routes/hooks/index.js new file mode 100644 index 0000000000000..d18bf49c71547 --- /dev/null +++ b/packages/medusa-payment-stripe/api/routes/hooks/index.js @@ -0,0 +1,27 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _express = require("express"); + +var _bodyParser = _interopRequireDefault(require("body-parser")); + +var _middlewares = _interopRequireDefault(require("../../middlewares")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +var route = (0, _express.Router)(); + +var _default = function _default(app) { + app.use("/stripe", route); + route.post("/hooks", // stripe constructEvent fails without body-parser + _bodyParser["default"].raw({ + type: "application/json" + }), _middlewares["default"].wrap(require("./stripe")["default"])); + return app; +}; + +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/routes/hooks/stripe.js b/packages/medusa-payment-stripe/api/routes/hooks/stripe.js new file mode 100644 index 0000000000000..2b0b08b4dde27 --- /dev/null +++ b/packages/medusa-payment-stripe/api/routes/hooks/stripe.js @@ -0,0 +1,348 @@ +"use strict"; + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _utils = require("@medusajs/medusa/dist/utils"); + +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +var _default = /*#__PURE__*/function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(req, res) { + var signature, event, stripeProviderService, isPaymentCollection, handleCartPayments, _handleCartPayments, handlePaymentCollection, _handlePaymentCollection, paymentIntent, cartId, resourceId; + + return _regeneratorRuntime().wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + _handlePaymentCollection = function _handlePaymentCollect2() { + _handlePaymentCollection = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(event, req, res, id, paymentIntentId) { + var _paycol$payments; + + var manager, paymentCollectionService, paycol, payment; + return _regeneratorRuntime().wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + manager = req.scope.resolve("manager"); + paymentCollectionService = req.scope.resolve("paymentCollectionService"); + _context5.next = 4; + return paymentCollectionService.retrieve(id, { + relations: ["payments"] + })["catch"](function () { + return undefined; + }); + + case 4: + paycol = _context5.sent; + + if (!(paycol !== null && paycol !== void 0 && (_paycol$payments = paycol.payments) !== null && _paycol$payments !== void 0 && _paycol$payments.length)) { + _context5.next = 13; + break; + } + + if (!(event.type === "payment_intent.succeeded")) { + _context5.next = 13; + break; + } + + payment = paycol.payments.find(function (pay) { + return pay.data.id === paymentIntentId; + }); + + if (!(payment && !payment.captured_at)) { + _context5.next = 11; + break; + } + + _context5.next = 11; + return manager.transaction( /*#__PURE__*/function () { + var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(manager) { + return _regeneratorRuntime().wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return paymentCollectionService.withTransaction(manager).capture(payment.id); + + case 2: + case "end": + return _context4.stop(); + } + } + }, _callee4); + })); + + return function (_x14) { + return _ref4.apply(this, arguments); + }; + }()); + + case 11: + res.sendStatus(200); + return _context5.abrupt("return"); + + case 13: + res.sendStatus(204); + + case 14: + case "end": + return _context5.stop(); + } + } + }, _callee5); + })); + return _handlePaymentCollection.apply(this, arguments); + }; + + handlePaymentCollection = function _handlePaymentCollect(_x7, _x8, _x9, _x10, _x11) { + return _handlePaymentCollection.apply(this, arguments); + }; + + _handleCartPayments = function _handleCartPayments3() { + _handleCartPayments = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(event, req, res, cartId) { + var manager, orderService, order, _err$detail, message, _err$detail2; + + return _regeneratorRuntime().wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + manager = req.scope.resolve("manager"); + orderService = req.scope.resolve("orderService"); + _context3.next = 4; + return orderService.retrieveByCartId(cartId)["catch"](function () { + return undefined; + }); + + case 4: + order = _context3.sent; + _context3.t0 = event.type; + _context3.next = _context3.t0 === "payment_intent.succeeded" ? 8 : _context3.t0 === "payment_intent.amount_capturable_updated" ? 19 : 31; + break; + + case 8: + if (!order) { + _context3.next = 17; + break; + } + + if (!(order.payment_status !== "captured")) { + _context3.next = 14; + break; + } + + _context3.next = 12; + return manager.transaction( /*#__PURE__*/function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(manager) { + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return orderService.withTransaction(manager).capturePayment(order.id); + + case 2: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + + return function (_x12) { + return _ref2.apply(this, arguments); + }; + }()); + + case 12: + _context3.next = 15; + break; + + case 14: + return _context3.abrupt("return", res.sendStatus(200)); + + case 15: + _context3.next = 18; + break; + + case 17: + return _context3.abrupt("return", res.sendStatus(404)); + + case 18: + return _context3.abrupt("break", 33); + + case 19: + _context3.prev = 19; + _context3.next = 22; + return manager.transaction( /*#__PURE__*/function () { + var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(manager) { + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return paymentIntentAmountCapturableEventHandler({ + order: order, + cartId: cartId, + container: req.scope, + transactionManager: manager + }); + + case 2: + case "end": + return _context2.stop(); + } + } + }, _callee2); + })); + + return function (_x13) { + return _ref3.apply(this, arguments); + }; + }()); + + case 22: + _context3.next = 30; + break; + + case 24: + _context3.prev = 24; + _context3.t1 = _context3["catch"](19); + message = "Stripe webhook ".concat(event, " handling failed\n").concat((_err$detail = _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.detail) !== null && _err$detail !== void 0 ? _err$detail : _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.message); + + if ((_context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.code) === _utils.PostgresError.SERIALIZATION_FAILURE) { + message = "Stripe webhook ".concat(event, " handle failed. This can happen when this webhook is triggered during a cart completion and can be ignored. This event should be retried automatically.\n").concat((_err$detail2 = _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.detail) !== null && _err$detail2 !== void 0 ? _err$detail2 : _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.message); + } + + this.logger_.warn(message); + return _context3.abrupt("return", res.sendStatus(409)); + + case 30: + return _context3.abrupt("break", 33); + + case 31: + res.sendStatus(204); + return _context3.abrupt("return"); + + case 33: + res.sendStatus(200); + + case 34: + case "end": + return _context3.stop(); + } + } + }, _callee3, this, [[19, 24]]); + })); + return _handleCartPayments.apply(this, arguments); + }; + + handleCartPayments = function _handleCartPayments2(_x3, _x4, _x5, _x6) { + return _handleCartPayments.apply(this, arguments); + }; + + isPaymentCollection = function _isPaymentCollection(id) { + return id && id.startsWith("paycol"); + }; + + signature = req.headers["stripe-signature"]; + _context6.prev = 6; + stripeProviderService = req.scope.resolve("pp_stripe"); + event = stripeProviderService.constructWebhookEvent(req.body, signature); + _context6.next = 15; + break; + + case 11: + _context6.prev = 11; + _context6.t0 = _context6["catch"](6); + res.status(400).send("Webhook Error: ".concat(_context6.t0.message)); + return _context6.abrupt("return"); + + case 15: + paymentIntent = event.data.object; + cartId = paymentIntent.metadata.cart_id; // Backward compatibility + + resourceId = paymentIntent.metadata.resource_id; + + if (!isPaymentCollection(resourceId)) { + _context6.next = 23; + break; + } + + _context6.next = 21; + return handlePaymentCollection(event, req, res, resourceId, paymentIntent.id); + + case 21: + _context6.next = 25; + break; + + case 23: + _context6.next = 25; + return handleCartPayments(event, req, res, cartId !== null && cartId !== void 0 ? cartId : resourceId); + + case 25: + case "end": + return _context6.stop(); + } + } + }, _callee6, null, [[6, 11]]); + })); + + return function (_x, _x2) { + return _ref.apply(this, arguments); + }; +}(); + +exports["default"] = _default; + +function paymentIntentAmountCapturableEventHandler(_x15) { + return _paymentIntentAmountCapturableEventHandler.apply(this, arguments); +} + +function _paymentIntentAmountCapturableEventHandler() { + _paymentIntentAmountCapturableEventHandler = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(_ref5) { + var order, cartId, container, transactionManager, cartService, orderService, cartServiceTx; + return _regeneratorRuntime().wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + order = _ref5.order, cartId = _ref5.cartId, container = _ref5.container, transactionManager = _ref5.transactionManager; + + if (order) { + _context7.next = 11; + break; + } + + cartService = container.resolve("cartService"); + orderService = container.resolve("orderService"); + cartServiceTx = cartService.withTransaction(transactionManager); + _context7.next = 7; + return cartServiceTx.setPaymentSession(cartId, "stripe"); + + case 7: + _context7.next = 9; + return cartServiceTx.authorizePayment(cartId); + + case 9: + _context7.next = 11; + return orderService.withTransaction(transactionManager).createFromCart(cartId); + + case 11: + case "end": + return _context7.stop(); + } + } + }, _callee7); + })); + return _paymentIntentAmountCapturableEventHandler.apply(this, arguments); +} \ No newline at end of file diff --git a/packages/medusa-payment-stripe/helpers/stripe-base.js b/packages/medusa-payment-stripe/helpers/stripe-base.js new file mode 100644 index 0000000000000..21e89b544f4c6 --- /dev/null +++ b/packages/medusa-payment-stripe/helpers/stripe-base.js @@ -0,0 +1,772 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _medusa = require("@medusajs/medusa"); + +var _stripe = _interopRequireDefault(require("stripe")); + +var _dist = require("@medusajs/medusa/dist"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var StripeBase = /*#__PURE__*/function (_AbstractPaymentServi) { + _inherits(StripeBase, _AbstractPaymentServi); + + var _super = _createSuper(StripeBase); + + function StripeBase(_, options) { + var _this; + + _classCallCheck(this, StripeBase); + + _this = _super.call(this, _, options); + /** + * Required Stripe options: + * { + * api_key: "stripe_secret_key", REQUIRED + * webhook_secret: "stripe_webhook_secret", REQUIRED + * // Use this flag to capture payment immediately (default is false) + * capture: true + * } + */ + + _this.options_ = options; + /** @private @const {Stripe} */ + + _this.stripe_ = (0, _stripe["default"])(options.api_key); + return _this; + } + + _createClass(StripeBase, [{ + key: "getPaymentIntentOptions", + value: function getPaymentIntentOptions() { + var _this$paymentIntentOp, _this$paymentIntentOp2, _this$paymentIntentOp3; + + var options = {}; + + if (this !== null && this !== void 0 && (_this$paymentIntentOp = this.paymentIntentOptions) !== null && _this$paymentIntentOp !== void 0 && _this$paymentIntentOp.capture_method) { + options.capture_method = this.paymentIntentOptions.capture_method; + } + + if (this !== null && this !== void 0 && (_this$paymentIntentOp2 = this.paymentIntentOptions) !== null && _this$paymentIntentOp2 !== void 0 && _this$paymentIntentOp2.setup_future_usage) { + options.setup_future_usage = this.paymentIntentOptions.setup_future_usage; + } + + if (this !== null && this !== void 0 && (_this$paymentIntentOp3 = this.paymentIntentOptions) !== null && _this$paymentIntentOp3 !== void 0 && _this$paymentIntentOp3.payment_method_types) { + options.payment_method_types = this.paymentIntentOptions.payment_method_types; + } + + return options; + } + /** + * Get payment session status + * statuses. + * @param {PaymentSessionData} paymentData - the data stored with the payment session + * @return {Promise} the status of the order + */ + + }, { + key: "getStatus", + value: function () { + var _getStatus = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(paymentData) { + var id, paymentIntent; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + id = paymentData.id; + _context.next = 3; + return this.stripe_.paymentIntents.retrieve(id); + + case 3: + paymentIntent = _context.sent; + _context.t0 = paymentIntent.status; + _context.next = _context.t0 === "requires_payment_method" ? 7 : _context.t0 === "requires_confirmation" ? 7 : _context.t0 === "processing" ? 7 : _context.t0 === "requires_action" ? 8 : _context.t0 === "canceled" ? 9 : _context.t0 === "requires_capture" ? 10 : _context.t0 === "succeeded" ? 10 : 11; + break; + + case 7: + return _context.abrupt("return", _dist.PaymentSessionStatus.PENDING); + + case 8: + return _context.abrupt("return", _dist.PaymentSessionStatus.REQUIRES_MORE); + + case 9: + return _context.abrupt("return", _dist.PaymentSessionStatus.CANCELED); + + case 10: + return _context.abrupt("return", _dist.PaymentSessionStatus.AUTHORIZED); + + case 11: + return _context.abrupt("return", _dist.PaymentSessionStatus.PENDING); + + case 12: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function getStatus(_x) { + return _getStatus.apply(this, arguments); + } + + return getStatus; + }() + /** + * Fetches a customers saved payment methods if registered in Stripe. + * @param {Customer} customer - customer to fetch saved cards for + * @return {Promise} saved payments methods + */ + + }, { + key: "retrieveSavedMethods", + value: function () { + var _retrieveSavedMethods = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(customer) { + var methods; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (!(customer.metadata && customer.metadata.stripe_id)) { + _context2.next = 5; + break; + } + + _context2.next = 3; + return this.stripe_.paymentMethods.list({ + customer: customer.metadata.stripe_id, + type: "card" + }); + + case 3: + methods = _context2.sent; + return _context2.abrupt("return", methods.data); + + case 5: + return _context2.abrupt("return", []); + + case 6: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function retrieveSavedMethods(_x2) { + return _retrieveSavedMethods.apply(this, arguments); + } + + return retrieveSavedMethods; + }() + /** + * Fetches a Stripe customer + * @param {string} customerId - Stripe customer id + * @return {Promise} Stripe customer + */ + + }, { + key: "retrieveCustomer", + value: function () { + var _retrieveCustomer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(customerId) { + return _regeneratorRuntime().wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + if (customerId) { + _context3.next = 2; + break; + } + + return _context3.abrupt("return"); + + case 2: + _context3.next = 4; + return this.stripe_.customers.retrieve(customerId); + + case 4: + return _context3.abrupt("return", _context3.sent); + + case 5: + case "end": + return _context3.stop(); + } + } + }, _callee3, this); + })); + + function retrieveCustomer(_x3) { + return _retrieveCustomer.apply(this, arguments); + } + + return retrieveCustomer; + }() + /** + * Creates a Stripe payment intent. + * If customer is not registered in Stripe, we do so. + * @param {Cart & PaymentContext} context - context to use to create a payment for + * @return {Promise} Stripe payment intent + */ + + }, { + key: "createPayment", + value: function () { + var _createPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(context) { + var _cart_context$payment, _this$options_, _this$options_2, _customer$metadata, _customer$metadata3; + + var intentRequestData, cart_id, email, cart_context, currency_code, amount, resource_id, customer, intentRequest, _customer$metadata2, stripeCustomer, session_data; + + return _regeneratorRuntime().wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + intentRequestData = this.getPaymentIntentOptions(); + cart_id = context.id, email = context.email, cart_context = context.context, currency_code = context.currency_code, amount = context.amount, resource_id = context.resource_id, customer = context.customer; + intentRequest = _objectSpread({ + description: (_cart_context$payment = cart_context.payment_description) !== null && _cart_context$payment !== void 0 ? _cart_context$payment : (_this$options_ = this.options_) === null || _this$options_ === void 0 ? void 0 : _this$options_.payment_description, + amount: Math.round(amount), + currency: currency_code, + metadata: { + cart_id: cart_id, + resource_id: resource_id + }, + capture_method: this.options_.capture ? "automatic" : "manual" + }, intentRequestData); + + if ((_this$options_2 = this.options_) !== null && _this$options_2 !== void 0 && _this$options_2.automatic_payment_methods) { + intentRequest.automatic_payment_methods = { + enabled: true + }; + } + + if (!(customer !== null && customer !== void 0 && (_customer$metadata = customer.metadata) !== null && _customer$metadata !== void 0 && _customer$metadata.stripe_id)) { + _context4.next = 8; + break; + } + + intentRequest.customer = customer === null || customer === void 0 ? void 0 : (_customer$metadata2 = customer.metadata) === null || _customer$metadata2 === void 0 ? void 0 : _customer$metadata2.stripe_id; + _context4.next = 12; + break; + + case 8: + _context4.next = 10; + return this.stripe_.customers.create({ + email: email + }); + + case 10: + stripeCustomer = _context4.sent; + intentRequest.customer = stripeCustomer.id; + + case 12: + _context4.next = 14; + return this.stripe_.paymentIntents.create(intentRequest); + + case 14: + session_data = _context4.sent; + return _context4.abrupt("return", { + session_data: session_data, + update_requests: customer !== null && customer !== void 0 && (_customer$metadata3 = customer.metadata) !== null && _customer$metadata3 !== void 0 && _customer$metadata3.stripe_id ? undefined : { + customer_metadata: { + stripe_id: intentRequest.customer + } + } + }); + + case 16: + case "end": + return _context4.stop(); + } + } + }, _callee4, this); + })); + + function createPayment(_x4) { + return _createPayment.apply(this, arguments); + } + + return createPayment; + }() + /** + * Retrieves Stripe payment intent. + * @param {PaymentData} data - the data of the payment to retrieve + * @return {Promise} Stripe payment intent + */ + + }, { + key: "retrievePayment", + value: function () { + var _retrievePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(data) { + return _regeneratorRuntime().wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + _context5.next = 2; + return this.stripe_.paymentIntents.retrieve(data.id); + + case 2: + return _context5.abrupt("return", _context5.sent); + + case 3: + case "end": + return _context5.stop(); + } + } + }, _callee5, this); + })); + + function retrievePayment(_x5) { + return _retrievePayment.apply(this, arguments); + } + + return retrievePayment; + }() + /** + * Gets a Stripe payment intent and returns it. + * @param {PaymentSession} paymentSession - the data of the payment to retrieve + * @return {Promise} Stripe payment intent + */ + + }, { + key: "getPaymentData", + value: function () { + var _getPaymentData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(paymentSession) { + return _regeneratorRuntime().wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + _context6.next = 2; + return this.stripe_.paymentIntents.retrieve(paymentSession.data.id); + + case 2: + return _context6.abrupt("return", _context6.sent); + + case 3: + case "end": + return _context6.stop(); + } + } + }, _callee6, this); + })); + + function getPaymentData(_x6) { + return _getPaymentData.apply(this, arguments); + } + + return getPaymentData; + }() + /** + * Authorizes Stripe payment intent by simply returning + * the status for the payment intent in use. + * @param {PaymentSession} paymentSession - payment session data + * @param {Data} context - properties relevant to current context + * @return {Promise<{ data: PaymentSessionData; status: PaymentSessionStatus }>} result with data and status + */ + + }, { + key: "authorizePayment", + value: function () { + var _authorizePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(paymentSession) { + var context, + stat, + _args7 = arguments; + return _regeneratorRuntime().wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + context = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {}; + _context7.next = 3; + return this.getStatus(paymentSession.data); + + case 3: + stat = _context7.sent; + return _context7.abrupt("return", { + data: paymentSession.data, + status: stat + }); + + case 5: + case "end": + return _context7.stop(); + } + } + }, _callee7, this); + })); + + function authorizePayment(_x7) { + return _authorizePayment.apply(this, arguments); + } + + return authorizePayment; + }() + }, { + key: "updatePaymentData", + value: function () { + var _updatePaymentData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(sessionData, update) { + return _regeneratorRuntime().wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + _context8.next = 2; + return this.stripe_.paymentIntents.update(sessionData.id, _objectSpread({}, update.data)); + + case 2: + return _context8.abrupt("return", _context8.sent); + + case 3: + case "end": + return _context8.stop(); + } + } + }, _callee8, this); + })); + + function updatePaymentData(_x8, _x9) { + return _updatePaymentData.apply(this, arguments); + } + + return updatePaymentData; + }() + /** + * Updates Stripe payment intent. + * @param {PaymentSessionData} paymentSessionData - payment session data. + * @param {Cart & PaymentContext} context + * @return {Promise} Stripe payment intent + */ + + }, { + key: "updatePayment", + value: function () { + var _updatePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(paymentSessionData, context) { + var _customer$metadata4; + + var amount, customer, stripeId; + return _regeneratorRuntime().wrap(function _callee9$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + amount = context.amount, customer = context.customer; + stripeId = (customer === null || customer === void 0 ? void 0 : (_customer$metadata4 = customer.metadata) === null || _customer$metadata4 === void 0 ? void 0 : _customer$metadata4.stripe_id) || undefined; + + if (!(stripeId !== paymentSessionData.customer)) { + _context9.next = 8; + break; + } + + _context9.next = 5; + return this.createPayment(context); + + case 5: + return _context9.abrupt("return", _context9.sent); + + case 8: + if (!(amount && paymentSessionData.amount === Math.round(amount))) { + _context9.next = 10; + break; + } + + return _context9.abrupt("return", paymentSessionData); + + case 10: + _context9.next = 12; + return this.stripe_.paymentIntents.update(paymentSessionData.id, { + amount: Math.round(amount) + }); + + case 12: + return _context9.abrupt("return", _context9.sent); + + case 13: + case "end": + return _context9.stop(); + } + } + }, _callee9, this); + })); + + function updatePayment(_x10, _x11) { + return _updatePayment.apply(this, arguments); + } + + return updatePayment; + }() + }, { + key: "deletePayment", + value: function () { + var _deletePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(payment) { + var id; + return _regeneratorRuntime().wrap(function _callee10$(_context10) { + while (1) { + switch (_context10.prev = _context10.next) { + case 0: + id = payment.data.id; + return _context10.abrupt("return", this.stripe_.paymentIntents.cancel(id)["catch"](function (err) { + if (err.statusCode === 400) { + return; + } + + throw err; + })); + + case 2: + case "end": + return _context10.stop(); + } + } + }, _callee10, this); + })); + + function deletePayment(_x12) { + return _deletePayment.apply(this, arguments); + } + + return deletePayment; + }() + /** + * Updates customer of Stripe payment intent. + * @param {string} paymentIntentId - id of payment intent to update + * @param {string} customerId - id of \ Stripe customer + * @return {object} Stripe payment intent + */ + + }, { + key: "updatePaymentIntentCustomer", + value: function () { + var _updatePaymentIntentCustomer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(paymentIntentId, customerId) { + return _regeneratorRuntime().wrap(function _callee11$(_context11) { + while (1) { + switch (_context11.prev = _context11.next) { + case 0: + _context11.next = 2; + return this.stripe_.paymentIntents.update(paymentIntentId, { + customer: customerId + }); + + case 2: + return _context11.abrupt("return", _context11.sent); + + case 3: + case "end": + return _context11.stop(); + } + } + }, _callee11, this); + })); + + function updatePaymentIntentCustomer(_x13, _x14) { + return _updatePaymentIntentCustomer.apply(this, arguments); + } + + return updatePaymentIntentCustomer; + }() + /** + * Captures payment for Stripe payment intent. + * @param {Payment} payment - payment method data from cart + * @return {Promise} Stripe payment intent + */ + + }, { + key: "capturePayment", + value: function () { + var _capturePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee12(payment) { + var id, intent; + return _regeneratorRuntime().wrap(function _callee12$(_context12) { + while (1) { + switch (_context12.prev = _context12.next) { + case 0: + id = payment.data.id; + _context12.prev = 1; + _context12.next = 4; + return this.stripe_.paymentIntents.capture(id); + + case 4: + intent = _context12.sent; + return _context12.abrupt("return", intent); + + case 8: + _context12.prev = 8; + _context12.t0 = _context12["catch"](1); + + if (!(_context12.t0.code === "payment_intent_unexpected_state")) { + _context12.next = 13; + break; + } + + if (!(_context12.t0.payment_intent.status === "succeeded")) { + _context12.next = 13; + break; + } + + return _context12.abrupt("return", _context12.t0.payment_intent); + + case 13: + throw _context12.t0; + + case 14: + case "end": + return _context12.stop(); + } + } + }, _callee12, this, [[1, 8]]); + })); + + function capturePayment(_x15) { + return _capturePayment.apply(this, arguments); + } + + return capturePayment; + }() + /** + * Refunds payment for Stripe payment intent. + * @param {Payment} payment - payment method data from cart + * @param {number} refundAmount - amount to refund + * @return {Promise} refunded payment intent + */ + + }, { + key: "refundPayment", + value: function () { + var _refundPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee13(payment, amountToRefund) { + var id; + return _regeneratorRuntime().wrap(function _callee13$(_context13) { + while (1) { + switch (_context13.prev = _context13.next) { + case 0: + id = payment.data.id; + _context13.next = 3; + return this.stripe_.refunds.create({ + amount: Math.round(amountToRefund), + payment_intent: id + }); + + case 3: + return _context13.abrupt("return", payment.data); + + case 4: + case "end": + return _context13.stop(); + } + } + }, _callee13, this); + })); + + function refundPayment(_x16, _x17) { + return _refundPayment.apply(this, arguments); + } + + return refundPayment; + }() + /** + * Cancels payment for Stripe payment intent. + * @param {Payment} payment - payment method data from cart + * @return {Promise} canceled payment intent + */ + + }, { + key: "cancelPayment", + value: function () { + var _cancelPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee14(payment) { + var id; + return _regeneratorRuntime().wrap(function _callee14$(_context14) { + while (1) { + switch (_context14.prev = _context14.next) { + case 0: + id = payment.data.id; + _context14.prev = 1; + _context14.next = 4; + return this.stripe_.paymentIntents.cancel(id); + + case 4: + return _context14.abrupt("return", _context14.sent); + + case 7: + _context14.prev = 7; + _context14.t0 = _context14["catch"](1); + + if (!(_context14.t0.payment_intent.status === "canceled")) { + _context14.next = 11; + break; + } + + return _context14.abrupt("return", _context14.t0.payment_intent); + + case 11: + throw _context14.t0; + + case 12: + case "end": + return _context14.stop(); + } + } + }, _callee14, this, [[1, 7]]); + })); + + function cancelPayment(_x18) { + return _cancelPayment.apply(this, arguments); + } + + return cancelPayment; + }() + /** + * Constructs Stripe Webhook event + * @param {object} data - the data of the webhook request: req.body + * @param {object} signature - the Stripe signature on the event, that + * ensures integrity of the webhook event + * @return {object} Stripe Webhook event + */ + + }, { + key: "constructWebhookEvent", + value: function constructWebhookEvent(data, signature) { + return this.stripe_.webhooks.constructEvent(data, signature, this.options_.webhook_secret); + } + }]); + + return StripeBase; +}(_medusa.AbstractPaymentService); + +_defineProperty(StripeBase, "identifier", null); + +var _default = StripeBase; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js b/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js new file mode 100644 index 0000000000000..9f58040cea0db --- /dev/null +++ b/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js @@ -0,0 +1,63 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.StripeProviderServiceMock = void 0; + +var _medusaTestUtils = require("medusa-test-utils"); + +var StripeProviderServiceMock = { + retrievePayment: jest.fn().mockImplementation(function (payData) { + if (payData.id === "pi_123456789") { + return Promise.resolve({ + id: "pi", + customer: "cus_123456789" + }); + } + + if (payData.id === "pi_no") { + return Promise.resolve({ + id: "pi_no" + }); + } + + return Promise.resolve(undefined); + }), + cancelPayment: jest.fn().mockImplementation(function (cart) { + return Promise.resolve(); + }), + updatePaymentIntentCustomer: jest.fn().mockImplementation(function (cart) { + return Promise.resolve(); + }), + retrieveCustomer: jest.fn().mockImplementation(function (customerId) { + if (customerId === "cus_123456789_new") { + return Promise.resolve({ + id: "cus_123456789_new" + }); + } + + return Promise.resolve(undefined); + }), + createCustomer: jest.fn().mockImplementation(function (customer) { + if (customer._id === _medusaTestUtils.IdMap.getId("vvd")) { + return Promise.resolve({ + id: "cus_123456789_new_vvd" + }); + } + + return Promise.resolve(undefined); + }), + createPayment: jest.fn().mockImplementation(function (cart) { + return Promise.resolve({ + id: "pi_new", + customer: "cus_123456789_new" + }); + }) +}; +exports.StripeProviderServiceMock = StripeProviderServiceMock; +var mock = jest.fn().mockImplementation(function () { + return StripeProviderServiceMock; +}); +var _default = mock; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-bancontact.js b/packages/medusa-payment-stripe/services/stripe-bancontact.js new file mode 100644 index 0000000000000..1fef577f0fa3c --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-bancontact.js @@ -0,0 +1,65 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var BancontactProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(BancontactProviderService, _StripeBase); + + var _super = _createSuper(BancontactProviderService); + + function BancontactProviderService(_, options) { + _classCallCheck(this, BancontactProviderService); + + return _super.call(this, _, options); + } + + _createClass(BancontactProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return { + payment_method_types: ["bancontact"], + capture_method: "automatic" + }; + } + }]); + + return BancontactProviderService; +}(_stripeBase["default"]); + +_defineProperty(BancontactProviderService, "identifier", "stripe-bancontact"); + +var _default = BancontactProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-blik.js b/packages/medusa-payment-stripe/services/stripe-blik.js new file mode 100644 index 0000000000000..0b05d94eb0b4c --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-blik.js @@ -0,0 +1,65 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var BlikProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(BlikProviderService, _StripeBase); + + var _super = _createSuper(BlikProviderService); + + function BlikProviderService(_, options) { + _classCallCheck(this, BlikProviderService); + + return _super.call(this, _, options); + } + + _createClass(BlikProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return { + payment_method_types: ["blik"], + capture_method: "automatic" + }; + } + }]); + + return BlikProviderService; +}(_stripeBase["default"]); + +_defineProperty(BlikProviderService, "identifier", "stripe-blik"); + +var _default = BlikProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-giropay.js b/packages/medusa-payment-stripe/services/stripe-giropay.js new file mode 100644 index 0000000000000..8c7cb1587b923 --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-giropay.js @@ -0,0 +1,65 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var GiropayProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(GiropayProviderService, _StripeBase); + + var _super = _createSuper(GiropayProviderService); + + function GiropayProviderService(_, options) { + _classCallCheck(this, GiropayProviderService); + + return _super.call(this, _, options); + } + + _createClass(GiropayProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return { + payment_method_types: ["giropay"], + capture_method: "automatic" + }; + } + }]); + + return GiropayProviderService; +}(_stripeBase["default"]); + +_defineProperty(GiropayProviderService, "identifier", "stripe-giropay"); + +var _default = GiropayProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-ideal.js b/packages/medusa-payment-stripe/services/stripe-ideal.js new file mode 100644 index 0000000000000..ced727f5fc289 --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-ideal.js @@ -0,0 +1,65 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var IdealProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(IdealProviderService, _StripeBase); + + var _super = _createSuper(IdealProviderService); + + function IdealProviderService(_, options) { + _classCallCheck(this, IdealProviderService); + + return _super.call(this, _, options); + } + + _createClass(IdealProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return { + payment_method_types: ["ideal"], + capture_method: "automatic" + }; + } + }]); + + return IdealProviderService; +}(_stripeBase["default"]); + +_defineProperty(IdealProviderService, "identifier", "stripe-ideal"); + +var _default = IdealProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-provider.js b/packages/medusa-payment-stripe/services/stripe-provider.js new file mode 100644 index 0000000000000..f201e497afbf7 --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-provider.js @@ -0,0 +1,62 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var StripeProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(StripeProviderService, _StripeBase); + + var _super = _createSuper(StripeProviderService); + + function StripeProviderService(_, options) { + _classCallCheck(this, StripeProviderService); + + return _super.call(this, _, options); + } + + _createClass(StripeProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return {}; + } + }]); + + return StripeProviderService; +}(_stripeBase["default"]); + +_defineProperty(StripeProviderService, "identifier", "stripe"); + +var _default = StripeProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-przelewy24.js b/packages/medusa-payment-stripe/services/stripe-przelewy24.js new file mode 100644 index 0000000000000..00bb7df48c610 --- /dev/null +++ b/packages/medusa-payment-stripe/services/stripe-przelewy24.js @@ -0,0 +1,65 @@ +"use strict"; + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var Przelewy24ProviderService = /*#__PURE__*/function (_StripeBase) { + _inherits(Przelewy24ProviderService, _StripeBase); + + var _super = _createSuper(Przelewy24ProviderService); + + function Przelewy24ProviderService(_, options) { + _classCallCheck(this, Przelewy24ProviderService); + + return _super.call(this, _, options); + } + + _createClass(Przelewy24ProviderService, [{ + key: "paymentIntentOptions", + get: function get() { + return { + payment_method_types: ["p24"], + capture_method: "automatic" + }; + } + }]); + + return Przelewy24ProviderService; +}(_stripeBase["default"]); + +_defineProperty(Przelewy24ProviderService, "identifier", "stripe-przelewy24"); + +var _default = Przelewy24ProviderService; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/src/services/stripe-bancontact.ts b/packages/medusa-payment-stripe/src/services/stripe-bancontact.ts index 970e04d64ab2b..72f4d3224913f 100644 --- a/packages/medusa-payment-stripe/src/services/stripe-bancontact.ts +++ b/packages/medusa-payment-stripe/src/services/stripe-bancontact.ts @@ -1,8 +1,8 @@ import StripeBase from "../core/stripe-base" -import { PaymentIntentOptions } from "../types" +import { PaymentIntentOptions, PaymentProviderKeys } from "../types" class BancontactProviderService extends StripeBase { - static identifier = "stripe-bancontact" + static identifier = PaymentProviderKeys.BAN_CONTACT constructor(_, options) { super(_, options) diff --git a/packages/medusa-payment-stripe/src/services/stripe-blik.ts b/packages/medusa-payment-stripe/src/services/stripe-blik.ts index 895003e6fd356..c53d7b78d3a40 100644 --- a/packages/medusa-payment-stripe/src/services/stripe-blik.ts +++ b/packages/medusa-payment-stripe/src/services/stripe-blik.ts @@ -1,8 +1,8 @@ import StripeBase from "../core/stripe-base" -import { PaymentIntentOptions } from "../types" +import { PaymentIntentOptions, PaymentProviderKeys } from "../types" class BlikProviderService extends StripeBase { - static identifier = "stripe-blik" + static identifier = PaymentProviderKeys.BLIK constructor(_, options) { super(_, options) diff --git a/packages/medusa-payment-stripe/src/services/stripe-giropay.ts b/packages/medusa-payment-stripe/src/services/stripe-giropay.ts index c486e5dbe2697..22d07c886730d 100644 --- a/packages/medusa-payment-stripe/src/services/stripe-giropay.ts +++ b/packages/medusa-payment-stripe/src/services/stripe-giropay.ts @@ -1,8 +1,8 @@ import StripeBase from "../core/stripe-base" -import { PaymentIntentOptions } from "../types" +import { PaymentIntentOptions, PaymentProviderKeys } from "../types" class GiropayProviderService extends StripeBase { - static identifier = "stripe-giropay" + static identifier = PaymentProviderKeys.GIROPAY constructor(_, options) { super(_, options) diff --git a/packages/medusa-payment-stripe/src/services/stripe-ideal.ts b/packages/medusa-payment-stripe/src/services/stripe-ideal.ts index 336b9c698e45a..6fafbb6a3c4b7 100644 --- a/packages/medusa-payment-stripe/src/services/stripe-ideal.ts +++ b/packages/medusa-payment-stripe/src/services/stripe-ideal.ts @@ -1,8 +1,8 @@ import StripeBase from "../core/stripe-base" -import { PaymentIntentOptions } from "../types" +import { PaymentIntentOptions, PaymentProviderKeys } from "../types" class IdealProviderService extends StripeBase { - static identifier = "stripe-ideal" + static identifier = PaymentProviderKeys.IDEAL constructor(_, options) { super(_, options) diff --git a/packages/medusa-payment-stripe/src/services/stripe-provider.ts b/packages/medusa-payment-stripe/src/services/stripe-provider.ts index 547f2dd72ee01..9188e4e889a72 100644 --- a/packages/medusa-payment-stripe/src/services/stripe-provider.ts +++ b/packages/medusa-payment-stripe/src/services/stripe-provider.ts @@ -1,8 +1,8 @@ import StripeBase from "../core/stripe-base" -import { PaymentIntentOptions } from "../types" +import { PaymentIntentOptions, PaymentProviderKeys } from "../types" class StripeProviderService extends StripeBase { - static identifier = "stripe" + static identifier = PaymentProviderKeys.STRIPE constructor(_, options) { super(_, options) diff --git a/packages/medusa-payment-stripe/src/services/stripe-przelewy24.ts b/packages/medusa-payment-stripe/src/services/stripe-przelewy24.ts index 62daf61b1b457..0050772d9d0ce 100644 --- a/packages/medusa-payment-stripe/src/services/stripe-przelewy24.ts +++ b/packages/medusa-payment-stripe/src/services/stripe-przelewy24.ts @@ -1,8 +1,8 @@ import StripeBase from "../core/stripe-base" -import { PaymentIntentOptions } from "../types" +import { PaymentIntentOptions, PaymentProviderKeys } from "../types" class Przelewy24ProviderService extends StripeBase { - static identifier = "stripe-przelewy24" + static identifier = PaymentProviderKeys.PRWELEWY_24 constructor(_, options) { super(_, options) diff --git a/packages/medusa-payment-stripe/src/types.ts b/packages/medusa-payment-stripe/src/types.ts index 3b73d513605f8..08eb005c8863e 100644 --- a/packages/medusa-payment-stripe/src/types.ts +++ b/packages/medusa-payment-stripe/src/types.ts @@ -29,3 +29,12 @@ export const ErrorIntentStatus = { SUCCEEDED: "succeeded", CANCELED: "canceled", } + +export const PaymentProviderKeys = { + STRIPE: "stripe", + BAN_CONTACT: "stripe-bancontact", + BLIK: "stripe-blik", + GIROPAY: "stripe-giropay", + IDEAL: "stripe-ideal", + PRWELEWY_24: "stripe-przelewy24", +} diff --git a/packages/medusa-payment-stripe/subscribers/cart.js b/packages/medusa-payment-stripe/subscribers/cart.js new file mode 100644 index 0000000000000..23d641c870710 --- /dev/null +++ b/packages/medusa-payment-stripe/subscribers/cart.js @@ -0,0 +1,125 @@ +"use strict"; + +function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } + +function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +var CartSubscriber = /*#__PURE__*/function () { + function CartSubscriber(_ref) { + var _this = this; + + var cartService = _ref.cartService, + customerService = _ref.customerService, + paymentProviderService = _ref.paymentProviderService, + eventBusService = _ref.eventBusService; + + _classCallCheck(this, CartSubscriber); + + this.cartService_ = cartService; + this.customerService_ = customerService; + this.paymentProviderService_ = paymentProviderService; + this.eventBus_ = eventBusService; + this.eventBus_.subscribe("cart.customer_updated", /*#__PURE__*/function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(cart) { + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return _this.onCustomerUpdated(cart); + + case 2: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + + return function (_x) { + return _ref2.apply(this, arguments); + }; + }()); + } + + _createClass(CartSubscriber, [{ + key: "onCustomerUpdated", + value: function () { + var _onCustomerUpdated = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(cartId) { + var _cart$payment_session; + + var cart, session; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return this.cartService_.retrieve(cartId, { + select: ["subtotal", "tax_total", "shipping_total", "discount_total", "total"], + relations: ["items", "billing_address", "shipping_address", "region", "region.payment_providers", "items", "items.adjustments", "payment_sessions", "customer"] + }); + + case 2: + cart = _context2.sent; + + if ((_cart$payment_session = cart.payment_sessions) !== null && _cart$payment_session !== void 0 && _cart$payment_session.length) { + _context2.next = 5; + break; + } + + return _context2.abrupt("return", Promise.resolve()); + + case 5: + session = cart.payment_sessions.find(function (ps) { + return ps.provider_id === "stripe"; + }); + + if (!session) { + _context2.next = 10; + break; + } + + _context2.next = 9; + return this.paymentProviderService_.updateSession(session, cart); + + case 9: + return _context2.abrupt("return", _context2.sent); + + case 10: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function onCustomerUpdated(_x2) { + return _onCustomerUpdated.apply(this, arguments); + } + + return onCustomerUpdated; + }() + }]); + + return CartSubscriber; +}(); + +var _default = CartSubscriber; +exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa/src/api/middlewares/index.ts b/packages/medusa/src/api/middlewares/index.ts index c85cf54a2bb9b..3036cb488db4a 100644 --- a/packages/medusa/src/api/middlewares/index.ts +++ b/packages/medusa/src/api/middlewares/index.ts @@ -18,7 +18,7 @@ export { default as requireCustomerAuthentication } from "./require-customer-aut /** * @deprecated you can now import the middlewares directly without passing by the default export - * e.g `import { wrapHandler } from "@medusajs/medusa" + * e.g `import { authenticate } from "@medusajs/medusa" */ export default { authenticate, diff --git a/packages/medusa/src/loaders/helpers/plugins.ts b/packages/medusa/src/loaders/helpers/plugins.ts index 6f13a8a28c3b0..539b1d412faf2 100644 --- a/packages/medusa/src/loaders/helpers/plugins.ts +++ b/packages/medusa/src/loaders/helpers/plugins.ts @@ -5,7 +5,7 @@ import { isPaymentProcessor, isPaymentService, } from "../../interfaces" -import { aliasTo, asFunction, Lifetime } from "awilix" +import { aliasTo, asFunction } from "awilix" type Context = { container: MedusaContainer @@ -25,9 +25,7 @@ export function registerPaymentServiceFromClass( container.registerAdd( "paymentProviders", - asFunction((cradle) => new klass(cradle, pluginDetails.options), { - lifetime: Lifetime.SINGLETON, - }) + asFunction((cradle) => new klass(cradle, pluginDetails.options)) ) container.register({ @@ -51,9 +49,7 @@ export function registerPaymentProcessorFromClass( container.registerAdd( "paymentProviders", - asFunction((cradle) => new klass(cradle, pluginDetails.options), { - lifetime: Lifetime.SINGLETON, - }) + asFunction((cradle) => new klass(cradle, pluginDetails.options)) ) container.register({ From 24574a9d0452492bd3878d9711ec30e3bba5673c Mon Sep 17 00:00:00 2001 From: adrien2p Date: Tue, 28 Feb 2023 11:35:04 +0100 Subject: [PATCH 31/36] cleanup web hook and add tests --- .changeset/eleven-cycles-mate.md | 6 +- packages/medusa-payment-stripe/.gitignore | 8 +- .../medusa-payment-stripe/__mocks__/cart.js | 195 ----- .../__mocks__/customer.js | 45 - .../__mocks__/eventbus.js | 16 - .../medusa-payment-stripe/__mocks__/stripe.js | 98 --- .../medusa-payment-stripe/__mocks__/totals.js | 15 - packages/medusa-payment-stripe/api/index.js | 20 - .../api/middlewares/await-middleware.js | 14 - .../api/middlewares/index.js | 15 - .../api/routes/hooks/index.js | 27 - .../api/routes/hooks/stripe.js | 348 -------- .../helpers/stripe-base.js | 772 ------------------ packages/medusa-payment-stripe/package.json | 3 +- .../services/__mocks__/stripe-provider.js | 63 -- .../services/stripe-bancontact.js | 65 -- .../services/stripe-blik.js | 65 -- .../services/stripe-giropay.js | 65 -- .../services/stripe-ideal.js | 65 -- .../services/stripe-provider.js | 62 -- .../services/stripe-przelewy24.js | 65 -- .../src/api/hooks/stripe.ts | 7 +- .../src/api/utils/utils.ts | 110 ++- .../src/core/__tests__/stripe-base.spec.ts | 18 +- .../src/core/stripe-base.ts | 24 +- .../medusa-payment-stripe/subscribers/cart.js | 125 --- .../medusa/src/services/idempotency-key.ts | 45 +- packages/modules-sdk/package.json | 3 +- 28 files changed, 131 insertions(+), 2233 deletions(-) delete mode 100644 packages/medusa-payment-stripe/__mocks__/cart.js delete mode 100644 packages/medusa-payment-stripe/__mocks__/customer.js delete mode 100644 packages/medusa-payment-stripe/__mocks__/eventbus.js delete mode 100644 packages/medusa-payment-stripe/__mocks__/stripe.js delete mode 100644 packages/medusa-payment-stripe/__mocks__/totals.js delete mode 100644 packages/medusa-payment-stripe/api/index.js delete mode 100644 packages/medusa-payment-stripe/api/middlewares/await-middleware.js delete mode 100644 packages/medusa-payment-stripe/api/middlewares/index.js delete mode 100644 packages/medusa-payment-stripe/api/routes/hooks/index.js delete mode 100644 packages/medusa-payment-stripe/api/routes/hooks/stripe.js delete mode 100644 packages/medusa-payment-stripe/helpers/stripe-base.js delete mode 100644 packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-bancontact.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-blik.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-giropay.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-ideal.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-provider.js delete mode 100644 packages/medusa-payment-stripe/services/stripe-przelewy24.js delete mode 100644 packages/medusa-payment-stripe/subscribers/cart.js diff --git a/.changeset/eleven-cycles-mate.md b/.changeset/eleven-cycles-mate.md index 78c001e057042..71c01eaad2496 100644 --- a/.changeset/eleven-cycles-mate.md +++ b/.changeset/eleven-cycles-mate.md @@ -1,7 +1,7 @@ --- -"medusa-payment-paypal": patch -"medusa-payment-stripe": patch -"@medusajs/medusa": patch +"medusa-payment-paypal": minor +"medusa-payment-stripe": minor +"@medusajs/medusa": minor --- feat(medusa-payment-stripe): Implement payment processor API on stripe plugin and fix web hook issues diff --git a/packages/medusa-payment-stripe/.gitignore b/packages/medusa-payment-stripe/.gitignore index 384d378f948ba..ae519965e204f 100644 --- a/packages/medusa-payment-stripe/.gitignore +++ b/packages/medusa-payment-stripe/.gitignore @@ -1,4 +1,10 @@ dist node_modules .DS_store -yarn.lock \ No newline at end of file +yarn.lock + +services +core +api +__mocks__ +subscribers \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/cart.js b/packages/medusa-payment-stripe/__mocks__/cart.js deleted file mode 100644 index eebabc2ef0bd5..0000000000000 --- a/packages/medusa-payment-stripe/__mocks__/cart.js +++ /dev/null @@ -1,195 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.carts = exports.CartServiceMock = void 0; - -var _medusaTestUtils = require("medusa-test-utils"); - -var carts = { - emptyCart: { - id: _medusaTestUtils.IdMap.getId("emptyCart"), - items: [], - region_id: _medusaTestUtils.IdMap.getId("testRegion"), - customer_id: "test-customer", - payment_sessions: [], - shipping_options: [{ - id: _medusaTestUtils.IdMap.getId("freeShipping"), - profile_id: "default_profile", - data: { - some_data: "yes" - } - }] - }, - frCart: { - id: _medusaTestUtils.IdMap.getId("fr-cart"), - email: "lebron@james.com", - title: "test", - region_id: _medusaTestUtils.IdMap.getId("region-france"), - items: [{ - id: _medusaTestUtils.IdMap.getId("line"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - unit_price: 8, - variant: { - id: _medusaTestUtils.IdMap.getId("eur-8-us-10") - }, - product: { - id: _medusaTestUtils.IdMap.getId("product") - }, - // { - // unit_price: 10, - // variant: { - // id: IdMap.getId("eur-10-us-12"), - // }, - // product: { - // id: IdMap.getId("product"), - // }, - // quantity: 1, - // }, - quantity: 10 - }, { - id: _medusaTestUtils.IdMap.getId("existingLine"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - unit_price: 10, - variant: { - id: _medusaTestUtils.IdMap.getId("eur-10-us-12") - }, - product: { - id: _medusaTestUtils.IdMap.getId("product") - }, - quantity: 1 - }], - shipping_methods: [{ - id: _medusaTestUtils.IdMap.getId("freeShipping"), - profile_id: "default_profile" - }], - shipping_options: [{ - id: _medusaTestUtils.IdMap.getId("freeShipping"), - profile_id: "default_profile" - }], - payment_sessions: [{ - provider_id: "stripe", - data: { - id: "pi_123456789", - customer: _medusaTestUtils.IdMap.getId("not-lebron") - } - }], - payment_method: { - provider_id: "stripe", - data: { - id: "pi_123456789", - customer: _medusaTestUtils.IdMap.getId("not-lebron") - } - }, - shipping_address: {}, - billing_address: {}, - discounts: [], - customer_id: _medusaTestUtils.IdMap.getId("lebron"), - context: {} - }, - frCartNoStripeCustomer: { - id: _medusaTestUtils.IdMap.getId("fr-cart-no-customer"), - title: "test", - region_id: _medusaTestUtils.IdMap.getId("region-france"), - items: [{ - id: _medusaTestUtils.IdMap.getId("line"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - content: [{ - unit_price: 8, - variant: { - id: _medusaTestUtils.IdMap.getId("eur-8-us-10") - }, - product: { - id: _medusaTestUtils.IdMap.getId("product") - }, - quantity: 1 - }, { - unit_price: 10, - variant: { - id: _medusaTestUtils.IdMap.getId("eur-10-us-12") - }, - product: { - id: _medusaTestUtils.IdMap.getId("product") - }, - quantity: 1 - }], - quantity: 10 - }, { - id: _medusaTestUtils.IdMap.getId("existingLine"), - title: "merge line", - description: "This is a new line", - thumbnail: "test-img-yeah.com/thumb", - content: { - unit_price: 10, - variant: { - id: _medusaTestUtils.IdMap.getId("eur-10-us-12") - }, - product: { - id: _medusaTestUtils.IdMap.getId("product") - }, - quantity: 1 - }, - quantity: 10 - }], - shipping_methods: [{ - id: _medusaTestUtils.IdMap.getId("freeShipping"), - profile_id: "default_profile" - }], - shipping_options: [{ - id: _medusaTestUtils.IdMap.getId("freeShipping"), - profile_id: "default_profile" - }], - payment_sessions: [{ - provider_id: "stripe", - data: { - id: "pi_no", - customer: _medusaTestUtils.IdMap.getId("not-lebron") - } - }], - payment_method: { - provider_id: "stripe", - data: { - id: "pi_no", - customer: _medusaTestUtils.IdMap.getId("not-lebron") - } - }, - shipping_address: {}, - billing_address: {}, - discounts: [], - customer_id: _medusaTestUtils.IdMap.getId("vvd") - } -}; -exports.carts = carts; -var CartServiceMock = { - retrieve: jest.fn().mockImplementation(function (cartId) { - if (cartId === _medusaTestUtils.IdMap.getId("fr-cart")) { - return Promise.resolve(carts.frCart); - } - - if (cartId === _medusaTestUtils.IdMap.getId("fr-cart-no-customer")) { - return Promise.resolve(carts.frCartNoStripeCustomer); - } - - if (cartId === _medusaTestUtils.IdMap.getId("emptyCart")) { - return Promise.resolve(carts.emptyCart); - } - - return Promise.resolve(undefined); - }), - updatePaymentSession: jest.fn().mockImplementation(function (cartId, stripe, paymentIntent) { - return Promise.resolve(); - }) -}; -exports.CartServiceMock = CartServiceMock; -var mock = jest.fn().mockImplementation(function () { - return CartServiceMock; -}); -var _default = mock; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/customer.js b/packages/medusa-payment-stripe/__mocks__/customer.js deleted file mode 100644 index 72cd299080511..0000000000000 --- a/packages/medusa-payment-stripe/__mocks__/customer.js +++ /dev/null @@ -1,45 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.CustomerServiceMock = void 0; - -var _medusaTestUtils = require("medusa-test-utils"); - -var CustomerServiceMock = { - retrieve: jest.fn().mockImplementation(function (id) { - if (id === _medusaTestUtils.IdMap.getId("lebron")) { - return Promise.resolve({ - _id: _medusaTestUtils.IdMap.getId("lebron"), - first_name: "LeBron", - last_name: "James", - email: "lebron@james.com", - password_hash: "1234", - metadata: { - stripe_id: "cus_123456789_new" - } - }); - } - - if (id === _medusaTestUtils.IdMap.getId("vvd")) { - return Promise.resolve({ - _id: _medusaTestUtils.IdMap.getId("vvd"), - first_name: "Virgil", - last_name: "Van Dijk", - email: "virg@vvd.com", - password_hash: "1234", - metadata: {} - }); - } - - return Promise.resolve(undefined); - }), - setMetadata: jest.fn().mockReturnValue(Promise.resolve()) -}; -exports.CustomerServiceMock = CustomerServiceMock; -var mock = jest.fn().mockImplementation(function () { - return CustomerServiceMock; -}); -var _default = mock; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/eventbus.js b/packages/medusa-payment-stripe/__mocks__/eventbus.js deleted file mode 100644 index b445554189888..0000000000000 --- a/packages/medusa-payment-stripe/__mocks__/eventbus.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.EventBusServiceMock = void 0; -var EventBusServiceMock = { - emit: jest.fn(), - subscribe: jest.fn() -}; -exports.EventBusServiceMock = EventBusServiceMock; -var mock = jest.fn().mockImplementation(function () { - return EventBusServiceMock; -}); -var _default = mock; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/stripe.js b/packages/medusa-payment-stripe/__mocks__/stripe.js deleted file mode 100644 index df9dbbb98c267..0000000000000 --- a/packages/medusa-payment-stripe/__mocks__/stripe.js +++ /dev/null @@ -1,98 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.StripeMock = void 0; -var StripeMock = { - customers: { - create: jest.fn().mockImplementation(function (data) { - if (data.email === "virg@vvd.com") { - return Promise.resolve({ - id: "cus_vvd", - email: "virg@vvd.com" - }); - } - - if (data.email === "lebron@james.com") { - return Promise.resolve({ - id: "cus_lebron", - email: "lebron@james.com" - }); - } - }) - }, - paymentIntents: { - create: jest.fn().mockImplementation(function (data) { - if (data.customer === "cus_123456789_new") { - return Promise.resolve({ - id: "pi_lebron", - amount: 100, - customer: "cus_123456789_new", - description: data === null || data === void 0 ? void 0 : data.description - }); - } - - if (data.customer === "cus_lebron") { - return Promise.resolve({ - id: "pi_lebron", - amount: 100, - customer: "cus_lebron", - description: data === null || data === void 0 ? void 0 : data.description - }); - } - }), - retrieve: jest.fn().mockImplementation(function (data) { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron" - }); - }), - update: jest.fn().mockImplementation(function (pi, data) { - if (data.customer === "cus_lebron_2") { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron_2", - amount: 1000 - }); - } - - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000 - }); - }), - capture: jest.fn().mockImplementation(function (data) { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron", - amount: 1000, - status: "succeeded" - }); - }), - cancel: jest.fn().mockImplementation(function (data) { - return Promise.resolve({ - id: "pi_lebron", - customer: "cus_lebron", - status: "cancelled" - }); - }) - }, - refunds: { - create: jest.fn().mockImplementation(function (data) { - return Promise.resolve({ - id: "re_123", - payment_intent: "pi_lebron", - amount: 1000, - status: "succeeded" - }); - }) - } -}; -exports.StripeMock = StripeMock; -var stripe = jest.fn(function () { - return StripeMock; -}); -var _default = stripe; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/__mocks__/totals.js b/packages/medusa-payment-stripe/__mocks__/totals.js deleted file mode 100644 index 576d1231e94a1..0000000000000 --- a/packages/medusa-payment-stripe/__mocks__/totals.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.TotalsServiceMock = void 0; -var TotalsServiceMock = { - getTotal: jest.fn() -}; -exports.TotalsServiceMock = TotalsServiceMock; -var mock = jest.fn().mockImplementation(function () { - return TotalsServiceMock; -}); -var _default = mock; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/index.js b/packages/medusa-payment-stripe/api/index.js deleted file mode 100644 index 20411274f2adc..0000000000000 --- a/packages/medusa-payment-stripe/api/index.js +++ /dev/null @@ -1,20 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _express = require("express"); - -var _hooks = _interopRequireDefault(require("./routes/hooks")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -var _default = function _default(container) { - var app = (0, _express.Router)(); - (0, _hooks["default"])(app); - return app; -}; - -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/middlewares/await-middleware.js b/packages/medusa-payment-stripe/api/middlewares/await-middleware.js deleted file mode 100644 index 36ee66cf7eb15..0000000000000 --- a/packages/medusa-payment-stripe/api/middlewares/await-middleware.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _default = function _default(fn) { - return function () { - return fn.apply(void 0, arguments)["catch"](arguments.length <= 2 ? undefined : arguments[2]); - }; -}; - -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/middlewares/index.js b/packages/medusa-payment-stripe/api/middlewares/index.js deleted file mode 100644 index 1d5f479eb7e89..0000000000000 --- a/packages/medusa-payment-stripe/api/middlewares/index.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _awaitMiddleware = _interopRequireDefault(require("./await-middleware")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -var _default = { - wrap: _awaitMiddleware["default"] -}; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/routes/hooks/index.js b/packages/medusa-payment-stripe/api/routes/hooks/index.js deleted file mode 100644 index d18bf49c71547..0000000000000 --- a/packages/medusa-payment-stripe/api/routes/hooks/index.js +++ /dev/null @@ -1,27 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _express = require("express"); - -var _bodyParser = _interopRequireDefault(require("body-parser")); - -var _middlewares = _interopRequireDefault(require("../../middlewares")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -var route = (0, _express.Router)(); - -var _default = function _default(app) { - app.use("/stripe", route); - route.post("/hooks", // stripe constructEvent fails without body-parser - _bodyParser["default"].raw({ - type: "application/json" - }), _middlewares["default"].wrap(require("./stripe")["default"])); - return app; -}; - -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/api/routes/hooks/stripe.js b/packages/medusa-payment-stripe/api/routes/hooks/stripe.js deleted file mode 100644 index 2b0b08b4dde27..0000000000000 --- a/packages/medusa-payment-stripe/api/routes/hooks/stripe.js +++ /dev/null @@ -1,348 +0,0 @@ -"use strict"; - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _utils = require("@medusajs/medusa/dist/utils"); - -function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } - -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } - -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } - -var _default = /*#__PURE__*/function () { - var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(req, res) { - var signature, event, stripeProviderService, isPaymentCollection, handleCartPayments, _handleCartPayments, handlePaymentCollection, _handlePaymentCollection, paymentIntent, cartId, resourceId; - - return _regeneratorRuntime().wrap(function _callee6$(_context6) { - while (1) { - switch (_context6.prev = _context6.next) { - case 0: - _handlePaymentCollection = function _handlePaymentCollect2() { - _handlePaymentCollection = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(event, req, res, id, paymentIntentId) { - var _paycol$payments; - - var manager, paymentCollectionService, paycol, payment; - return _regeneratorRuntime().wrap(function _callee5$(_context5) { - while (1) { - switch (_context5.prev = _context5.next) { - case 0: - manager = req.scope.resolve("manager"); - paymentCollectionService = req.scope.resolve("paymentCollectionService"); - _context5.next = 4; - return paymentCollectionService.retrieve(id, { - relations: ["payments"] - })["catch"](function () { - return undefined; - }); - - case 4: - paycol = _context5.sent; - - if (!(paycol !== null && paycol !== void 0 && (_paycol$payments = paycol.payments) !== null && _paycol$payments !== void 0 && _paycol$payments.length)) { - _context5.next = 13; - break; - } - - if (!(event.type === "payment_intent.succeeded")) { - _context5.next = 13; - break; - } - - payment = paycol.payments.find(function (pay) { - return pay.data.id === paymentIntentId; - }); - - if (!(payment && !payment.captured_at)) { - _context5.next = 11; - break; - } - - _context5.next = 11; - return manager.transaction( /*#__PURE__*/function () { - var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(manager) { - return _regeneratorRuntime().wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - _context4.next = 2; - return paymentCollectionService.withTransaction(manager).capture(payment.id); - - case 2: - case "end": - return _context4.stop(); - } - } - }, _callee4); - })); - - return function (_x14) { - return _ref4.apply(this, arguments); - }; - }()); - - case 11: - res.sendStatus(200); - return _context5.abrupt("return"); - - case 13: - res.sendStatus(204); - - case 14: - case "end": - return _context5.stop(); - } - } - }, _callee5); - })); - return _handlePaymentCollection.apply(this, arguments); - }; - - handlePaymentCollection = function _handlePaymentCollect(_x7, _x8, _x9, _x10, _x11) { - return _handlePaymentCollection.apply(this, arguments); - }; - - _handleCartPayments = function _handleCartPayments3() { - _handleCartPayments = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(event, req, res, cartId) { - var manager, orderService, order, _err$detail, message, _err$detail2; - - return _regeneratorRuntime().wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - manager = req.scope.resolve("manager"); - orderService = req.scope.resolve("orderService"); - _context3.next = 4; - return orderService.retrieveByCartId(cartId)["catch"](function () { - return undefined; - }); - - case 4: - order = _context3.sent; - _context3.t0 = event.type; - _context3.next = _context3.t0 === "payment_intent.succeeded" ? 8 : _context3.t0 === "payment_intent.amount_capturable_updated" ? 19 : 31; - break; - - case 8: - if (!order) { - _context3.next = 17; - break; - } - - if (!(order.payment_status !== "captured")) { - _context3.next = 14; - break; - } - - _context3.next = 12; - return manager.transaction( /*#__PURE__*/function () { - var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(manager) { - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return orderService.withTransaction(manager).capturePayment(order.id); - - case 2: - case "end": - return _context.stop(); - } - } - }, _callee); - })); - - return function (_x12) { - return _ref2.apply(this, arguments); - }; - }()); - - case 12: - _context3.next = 15; - break; - - case 14: - return _context3.abrupt("return", res.sendStatus(200)); - - case 15: - _context3.next = 18; - break; - - case 17: - return _context3.abrupt("return", res.sendStatus(404)); - - case 18: - return _context3.abrupt("break", 33); - - case 19: - _context3.prev = 19; - _context3.next = 22; - return manager.transaction( /*#__PURE__*/function () { - var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(manager) { - return _regeneratorRuntime().wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - _context2.next = 2; - return paymentIntentAmountCapturableEventHandler({ - order: order, - cartId: cartId, - container: req.scope, - transactionManager: manager - }); - - case 2: - case "end": - return _context2.stop(); - } - } - }, _callee2); - })); - - return function (_x13) { - return _ref3.apply(this, arguments); - }; - }()); - - case 22: - _context3.next = 30; - break; - - case 24: - _context3.prev = 24; - _context3.t1 = _context3["catch"](19); - message = "Stripe webhook ".concat(event, " handling failed\n").concat((_err$detail = _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.detail) !== null && _err$detail !== void 0 ? _err$detail : _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.message); - - if ((_context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.code) === _utils.PostgresError.SERIALIZATION_FAILURE) { - message = "Stripe webhook ".concat(event, " handle failed. This can happen when this webhook is triggered during a cart completion and can be ignored. This event should be retried automatically.\n").concat((_err$detail2 = _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.detail) !== null && _err$detail2 !== void 0 ? _err$detail2 : _context3.t1 === null || _context3.t1 === void 0 ? void 0 : _context3.t1.message); - } - - this.logger_.warn(message); - return _context3.abrupt("return", res.sendStatus(409)); - - case 30: - return _context3.abrupt("break", 33); - - case 31: - res.sendStatus(204); - return _context3.abrupt("return"); - - case 33: - res.sendStatus(200); - - case 34: - case "end": - return _context3.stop(); - } - } - }, _callee3, this, [[19, 24]]); - })); - return _handleCartPayments.apply(this, arguments); - }; - - handleCartPayments = function _handleCartPayments2(_x3, _x4, _x5, _x6) { - return _handleCartPayments.apply(this, arguments); - }; - - isPaymentCollection = function _isPaymentCollection(id) { - return id && id.startsWith("paycol"); - }; - - signature = req.headers["stripe-signature"]; - _context6.prev = 6; - stripeProviderService = req.scope.resolve("pp_stripe"); - event = stripeProviderService.constructWebhookEvent(req.body, signature); - _context6.next = 15; - break; - - case 11: - _context6.prev = 11; - _context6.t0 = _context6["catch"](6); - res.status(400).send("Webhook Error: ".concat(_context6.t0.message)); - return _context6.abrupt("return"); - - case 15: - paymentIntent = event.data.object; - cartId = paymentIntent.metadata.cart_id; // Backward compatibility - - resourceId = paymentIntent.metadata.resource_id; - - if (!isPaymentCollection(resourceId)) { - _context6.next = 23; - break; - } - - _context6.next = 21; - return handlePaymentCollection(event, req, res, resourceId, paymentIntent.id); - - case 21: - _context6.next = 25; - break; - - case 23: - _context6.next = 25; - return handleCartPayments(event, req, res, cartId !== null && cartId !== void 0 ? cartId : resourceId); - - case 25: - case "end": - return _context6.stop(); - } - } - }, _callee6, null, [[6, 11]]); - })); - - return function (_x, _x2) { - return _ref.apply(this, arguments); - }; -}(); - -exports["default"] = _default; - -function paymentIntentAmountCapturableEventHandler(_x15) { - return _paymentIntentAmountCapturableEventHandler.apply(this, arguments); -} - -function _paymentIntentAmountCapturableEventHandler() { - _paymentIntentAmountCapturableEventHandler = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(_ref5) { - var order, cartId, container, transactionManager, cartService, orderService, cartServiceTx; - return _regeneratorRuntime().wrap(function _callee7$(_context7) { - while (1) { - switch (_context7.prev = _context7.next) { - case 0: - order = _ref5.order, cartId = _ref5.cartId, container = _ref5.container, transactionManager = _ref5.transactionManager; - - if (order) { - _context7.next = 11; - break; - } - - cartService = container.resolve("cartService"); - orderService = container.resolve("orderService"); - cartServiceTx = cartService.withTransaction(transactionManager); - _context7.next = 7; - return cartServiceTx.setPaymentSession(cartId, "stripe"); - - case 7: - _context7.next = 9; - return cartServiceTx.authorizePayment(cartId); - - case 9: - _context7.next = 11; - return orderService.withTransaction(transactionManager).createFromCart(cartId); - - case 11: - case "end": - return _context7.stop(); - } - } - }, _callee7); - })); - return _paymentIntentAmountCapturableEventHandler.apply(this, arguments); -} \ No newline at end of file diff --git a/packages/medusa-payment-stripe/helpers/stripe-base.js b/packages/medusa-payment-stripe/helpers/stripe-base.js deleted file mode 100644 index 21e89b544f4c6..0000000000000 --- a/packages/medusa-payment-stripe/helpers/stripe-base.js +++ /dev/null @@ -1,772 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _medusa = require("@medusajs/medusa"); - -var _stripe = _interopRequireDefault(require("stripe")); - -var _dist = require("@medusajs/medusa/dist"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } - -function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } - -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } - -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var StripeBase = /*#__PURE__*/function (_AbstractPaymentServi) { - _inherits(StripeBase, _AbstractPaymentServi); - - var _super = _createSuper(StripeBase); - - function StripeBase(_, options) { - var _this; - - _classCallCheck(this, StripeBase); - - _this = _super.call(this, _, options); - /** - * Required Stripe options: - * { - * api_key: "stripe_secret_key", REQUIRED - * webhook_secret: "stripe_webhook_secret", REQUIRED - * // Use this flag to capture payment immediately (default is false) - * capture: true - * } - */ - - _this.options_ = options; - /** @private @const {Stripe} */ - - _this.stripe_ = (0, _stripe["default"])(options.api_key); - return _this; - } - - _createClass(StripeBase, [{ - key: "getPaymentIntentOptions", - value: function getPaymentIntentOptions() { - var _this$paymentIntentOp, _this$paymentIntentOp2, _this$paymentIntentOp3; - - var options = {}; - - if (this !== null && this !== void 0 && (_this$paymentIntentOp = this.paymentIntentOptions) !== null && _this$paymentIntentOp !== void 0 && _this$paymentIntentOp.capture_method) { - options.capture_method = this.paymentIntentOptions.capture_method; - } - - if (this !== null && this !== void 0 && (_this$paymentIntentOp2 = this.paymentIntentOptions) !== null && _this$paymentIntentOp2 !== void 0 && _this$paymentIntentOp2.setup_future_usage) { - options.setup_future_usage = this.paymentIntentOptions.setup_future_usage; - } - - if (this !== null && this !== void 0 && (_this$paymentIntentOp3 = this.paymentIntentOptions) !== null && _this$paymentIntentOp3 !== void 0 && _this$paymentIntentOp3.payment_method_types) { - options.payment_method_types = this.paymentIntentOptions.payment_method_types; - } - - return options; - } - /** - * Get payment session status - * statuses. - * @param {PaymentSessionData} paymentData - the data stored with the payment session - * @return {Promise} the status of the order - */ - - }, { - key: "getStatus", - value: function () { - var _getStatus = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(paymentData) { - var id, paymentIntent; - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - id = paymentData.id; - _context.next = 3; - return this.stripe_.paymentIntents.retrieve(id); - - case 3: - paymentIntent = _context.sent; - _context.t0 = paymentIntent.status; - _context.next = _context.t0 === "requires_payment_method" ? 7 : _context.t0 === "requires_confirmation" ? 7 : _context.t0 === "processing" ? 7 : _context.t0 === "requires_action" ? 8 : _context.t0 === "canceled" ? 9 : _context.t0 === "requires_capture" ? 10 : _context.t0 === "succeeded" ? 10 : 11; - break; - - case 7: - return _context.abrupt("return", _dist.PaymentSessionStatus.PENDING); - - case 8: - return _context.abrupt("return", _dist.PaymentSessionStatus.REQUIRES_MORE); - - case 9: - return _context.abrupt("return", _dist.PaymentSessionStatus.CANCELED); - - case 10: - return _context.abrupt("return", _dist.PaymentSessionStatus.AUTHORIZED); - - case 11: - return _context.abrupt("return", _dist.PaymentSessionStatus.PENDING); - - case 12: - case "end": - return _context.stop(); - } - } - }, _callee, this); - })); - - function getStatus(_x) { - return _getStatus.apply(this, arguments); - } - - return getStatus; - }() - /** - * Fetches a customers saved payment methods if registered in Stripe. - * @param {Customer} customer - customer to fetch saved cards for - * @return {Promise} saved payments methods - */ - - }, { - key: "retrieveSavedMethods", - value: function () { - var _retrieveSavedMethods = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(customer) { - var methods; - return _regeneratorRuntime().wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - if (!(customer.metadata && customer.metadata.stripe_id)) { - _context2.next = 5; - break; - } - - _context2.next = 3; - return this.stripe_.paymentMethods.list({ - customer: customer.metadata.stripe_id, - type: "card" - }); - - case 3: - methods = _context2.sent; - return _context2.abrupt("return", methods.data); - - case 5: - return _context2.abrupt("return", []); - - case 6: - case "end": - return _context2.stop(); - } - } - }, _callee2, this); - })); - - function retrieveSavedMethods(_x2) { - return _retrieveSavedMethods.apply(this, arguments); - } - - return retrieveSavedMethods; - }() - /** - * Fetches a Stripe customer - * @param {string} customerId - Stripe customer id - * @return {Promise} Stripe customer - */ - - }, { - key: "retrieveCustomer", - value: function () { - var _retrieveCustomer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(customerId) { - return _regeneratorRuntime().wrap(function _callee3$(_context3) { - while (1) { - switch (_context3.prev = _context3.next) { - case 0: - if (customerId) { - _context3.next = 2; - break; - } - - return _context3.abrupt("return"); - - case 2: - _context3.next = 4; - return this.stripe_.customers.retrieve(customerId); - - case 4: - return _context3.abrupt("return", _context3.sent); - - case 5: - case "end": - return _context3.stop(); - } - } - }, _callee3, this); - })); - - function retrieveCustomer(_x3) { - return _retrieveCustomer.apply(this, arguments); - } - - return retrieveCustomer; - }() - /** - * Creates a Stripe payment intent. - * If customer is not registered in Stripe, we do so. - * @param {Cart & PaymentContext} context - context to use to create a payment for - * @return {Promise} Stripe payment intent - */ - - }, { - key: "createPayment", - value: function () { - var _createPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(context) { - var _cart_context$payment, _this$options_, _this$options_2, _customer$metadata, _customer$metadata3; - - var intentRequestData, cart_id, email, cart_context, currency_code, amount, resource_id, customer, intentRequest, _customer$metadata2, stripeCustomer, session_data; - - return _regeneratorRuntime().wrap(function _callee4$(_context4) { - while (1) { - switch (_context4.prev = _context4.next) { - case 0: - intentRequestData = this.getPaymentIntentOptions(); - cart_id = context.id, email = context.email, cart_context = context.context, currency_code = context.currency_code, amount = context.amount, resource_id = context.resource_id, customer = context.customer; - intentRequest = _objectSpread({ - description: (_cart_context$payment = cart_context.payment_description) !== null && _cart_context$payment !== void 0 ? _cart_context$payment : (_this$options_ = this.options_) === null || _this$options_ === void 0 ? void 0 : _this$options_.payment_description, - amount: Math.round(amount), - currency: currency_code, - metadata: { - cart_id: cart_id, - resource_id: resource_id - }, - capture_method: this.options_.capture ? "automatic" : "manual" - }, intentRequestData); - - if ((_this$options_2 = this.options_) !== null && _this$options_2 !== void 0 && _this$options_2.automatic_payment_methods) { - intentRequest.automatic_payment_methods = { - enabled: true - }; - } - - if (!(customer !== null && customer !== void 0 && (_customer$metadata = customer.metadata) !== null && _customer$metadata !== void 0 && _customer$metadata.stripe_id)) { - _context4.next = 8; - break; - } - - intentRequest.customer = customer === null || customer === void 0 ? void 0 : (_customer$metadata2 = customer.metadata) === null || _customer$metadata2 === void 0 ? void 0 : _customer$metadata2.stripe_id; - _context4.next = 12; - break; - - case 8: - _context4.next = 10; - return this.stripe_.customers.create({ - email: email - }); - - case 10: - stripeCustomer = _context4.sent; - intentRequest.customer = stripeCustomer.id; - - case 12: - _context4.next = 14; - return this.stripe_.paymentIntents.create(intentRequest); - - case 14: - session_data = _context4.sent; - return _context4.abrupt("return", { - session_data: session_data, - update_requests: customer !== null && customer !== void 0 && (_customer$metadata3 = customer.metadata) !== null && _customer$metadata3 !== void 0 && _customer$metadata3.stripe_id ? undefined : { - customer_metadata: { - stripe_id: intentRequest.customer - } - } - }); - - case 16: - case "end": - return _context4.stop(); - } - } - }, _callee4, this); - })); - - function createPayment(_x4) { - return _createPayment.apply(this, arguments); - } - - return createPayment; - }() - /** - * Retrieves Stripe payment intent. - * @param {PaymentData} data - the data of the payment to retrieve - * @return {Promise} Stripe payment intent - */ - - }, { - key: "retrievePayment", - value: function () { - var _retrievePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(data) { - return _regeneratorRuntime().wrap(function _callee5$(_context5) { - while (1) { - switch (_context5.prev = _context5.next) { - case 0: - _context5.next = 2; - return this.stripe_.paymentIntents.retrieve(data.id); - - case 2: - return _context5.abrupt("return", _context5.sent); - - case 3: - case "end": - return _context5.stop(); - } - } - }, _callee5, this); - })); - - function retrievePayment(_x5) { - return _retrievePayment.apply(this, arguments); - } - - return retrievePayment; - }() - /** - * Gets a Stripe payment intent and returns it. - * @param {PaymentSession} paymentSession - the data of the payment to retrieve - * @return {Promise} Stripe payment intent - */ - - }, { - key: "getPaymentData", - value: function () { - var _getPaymentData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(paymentSession) { - return _regeneratorRuntime().wrap(function _callee6$(_context6) { - while (1) { - switch (_context6.prev = _context6.next) { - case 0: - _context6.next = 2; - return this.stripe_.paymentIntents.retrieve(paymentSession.data.id); - - case 2: - return _context6.abrupt("return", _context6.sent); - - case 3: - case "end": - return _context6.stop(); - } - } - }, _callee6, this); - })); - - function getPaymentData(_x6) { - return _getPaymentData.apply(this, arguments); - } - - return getPaymentData; - }() - /** - * Authorizes Stripe payment intent by simply returning - * the status for the payment intent in use. - * @param {PaymentSession} paymentSession - payment session data - * @param {Data} context - properties relevant to current context - * @return {Promise<{ data: PaymentSessionData; status: PaymentSessionStatus }>} result with data and status - */ - - }, { - key: "authorizePayment", - value: function () { - var _authorizePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(paymentSession) { - var context, - stat, - _args7 = arguments; - return _regeneratorRuntime().wrap(function _callee7$(_context7) { - while (1) { - switch (_context7.prev = _context7.next) { - case 0: - context = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {}; - _context7.next = 3; - return this.getStatus(paymentSession.data); - - case 3: - stat = _context7.sent; - return _context7.abrupt("return", { - data: paymentSession.data, - status: stat - }); - - case 5: - case "end": - return _context7.stop(); - } - } - }, _callee7, this); - })); - - function authorizePayment(_x7) { - return _authorizePayment.apply(this, arguments); - } - - return authorizePayment; - }() - }, { - key: "updatePaymentData", - value: function () { - var _updatePaymentData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(sessionData, update) { - return _regeneratorRuntime().wrap(function _callee8$(_context8) { - while (1) { - switch (_context8.prev = _context8.next) { - case 0: - _context8.next = 2; - return this.stripe_.paymentIntents.update(sessionData.id, _objectSpread({}, update.data)); - - case 2: - return _context8.abrupt("return", _context8.sent); - - case 3: - case "end": - return _context8.stop(); - } - } - }, _callee8, this); - })); - - function updatePaymentData(_x8, _x9) { - return _updatePaymentData.apply(this, arguments); - } - - return updatePaymentData; - }() - /** - * Updates Stripe payment intent. - * @param {PaymentSessionData} paymentSessionData - payment session data. - * @param {Cart & PaymentContext} context - * @return {Promise} Stripe payment intent - */ - - }, { - key: "updatePayment", - value: function () { - var _updatePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(paymentSessionData, context) { - var _customer$metadata4; - - var amount, customer, stripeId; - return _regeneratorRuntime().wrap(function _callee9$(_context9) { - while (1) { - switch (_context9.prev = _context9.next) { - case 0: - amount = context.amount, customer = context.customer; - stripeId = (customer === null || customer === void 0 ? void 0 : (_customer$metadata4 = customer.metadata) === null || _customer$metadata4 === void 0 ? void 0 : _customer$metadata4.stripe_id) || undefined; - - if (!(stripeId !== paymentSessionData.customer)) { - _context9.next = 8; - break; - } - - _context9.next = 5; - return this.createPayment(context); - - case 5: - return _context9.abrupt("return", _context9.sent); - - case 8: - if (!(amount && paymentSessionData.amount === Math.round(amount))) { - _context9.next = 10; - break; - } - - return _context9.abrupt("return", paymentSessionData); - - case 10: - _context9.next = 12; - return this.stripe_.paymentIntents.update(paymentSessionData.id, { - amount: Math.round(amount) - }); - - case 12: - return _context9.abrupt("return", _context9.sent); - - case 13: - case "end": - return _context9.stop(); - } - } - }, _callee9, this); - })); - - function updatePayment(_x10, _x11) { - return _updatePayment.apply(this, arguments); - } - - return updatePayment; - }() - }, { - key: "deletePayment", - value: function () { - var _deletePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(payment) { - var id; - return _regeneratorRuntime().wrap(function _callee10$(_context10) { - while (1) { - switch (_context10.prev = _context10.next) { - case 0: - id = payment.data.id; - return _context10.abrupt("return", this.stripe_.paymentIntents.cancel(id)["catch"](function (err) { - if (err.statusCode === 400) { - return; - } - - throw err; - })); - - case 2: - case "end": - return _context10.stop(); - } - } - }, _callee10, this); - })); - - function deletePayment(_x12) { - return _deletePayment.apply(this, arguments); - } - - return deletePayment; - }() - /** - * Updates customer of Stripe payment intent. - * @param {string} paymentIntentId - id of payment intent to update - * @param {string} customerId - id of \ Stripe customer - * @return {object} Stripe payment intent - */ - - }, { - key: "updatePaymentIntentCustomer", - value: function () { - var _updatePaymentIntentCustomer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(paymentIntentId, customerId) { - return _regeneratorRuntime().wrap(function _callee11$(_context11) { - while (1) { - switch (_context11.prev = _context11.next) { - case 0: - _context11.next = 2; - return this.stripe_.paymentIntents.update(paymentIntentId, { - customer: customerId - }); - - case 2: - return _context11.abrupt("return", _context11.sent); - - case 3: - case "end": - return _context11.stop(); - } - } - }, _callee11, this); - })); - - function updatePaymentIntentCustomer(_x13, _x14) { - return _updatePaymentIntentCustomer.apply(this, arguments); - } - - return updatePaymentIntentCustomer; - }() - /** - * Captures payment for Stripe payment intent. - * @param {Payment} payment - payment method data from cart - * @return {Promise} Stripe payment intent - */ - - }, { - key: "capturePayment", - value: function () { - var _capturePayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee12(payment) { - var id, intent; - return _regeneratorRuntime().wrap(function _callee12$(_context12) { - while (1) { - switch (_context12.prev = _context12.next) { - case 0: - id = payment.data.id; - _context12.prev = 1; - _context12.next = 4; - return this.stripe_.paymentIntents.capture(id); - - case 4: - intent = _context12.sent; - return _context12.abrupt("return", intent); - - case 8: - _context12.prev = 8; - _context12.t0 = _context12["catch"](1); - - if (!(_context12.t0.code === "payment_intent_unexpected_state")) { - _context12.next = 13; - break; - } - - if (!(_context12.t0.payment_intent.status === "succeeded")) { - _context12.next = 13; - break; - } - - return _context12.abrupt("return", _context12.t0.payment_intent); - - case 13: - throw _context12.t0; - - case 14: - case "end": - return _context12.stop(); - } - } - }, _callee12, this, [[1, 8]]); - })); - - function capturePayment(_x15) { - return _capturePayment.apply(this, arguments); - } - - return capturePayment; - }() - /** - * Refunds payment for Stripe payment intent. - * @param {Payment} payment - payment method data from cart - * @param {number} refundAmount - amount to refund - * @return {Promise} refunded payment intent - */ - - }, { - key: "refundPayment", - value: function () { - var _refundPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee13(payment, amountToRefund) { - var id; - return _regeneratorRuntime().wrap(function _callee13$(_context13) { - while (1) { - switch (_context13.prev = _context13.next) { - case 0: - id = payment.data.id; - _context13.next = 3; - return this.stripe_.refunds.create({ - amount: Math.round(amountToRefund), - payment_intent: id - }); - - case 3: - return _context13.abrupt("return", payment.data); - - case 4: - case "end": - return _context13.stop(); - } - } - }, _callee13, this); - })); - - function refundPayment(_x16, _x17) { - return _refundPayment.apply(this, arguments); - } - - return refundPayment; - }() - /** - * Cancels payment for Stripe payment intent. - * @param {Payment} payment - payment method data from cart - * @return {Promise} canceled payment intent - */ - - }, { - key: "cancelPayment", - value: function () { - var _cancelPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee14(payment) { - var id; - return _regeneratorRuntime().wrap(function _callee14$(_context14) { - while (1) { - switch (_context14.prev = _context14.next) { - case 0: - id = payment.data.id; - _context14.prev = 1; - _context14.next = 4; - return this.stripe_.paymentIntents.cancel(id); - - case 4: - return _context14.abrupt("return", _context14.sent); - - case 7: - _context14.prev = 7; - _context14.t0 = _context14["catch"](1); - - if (!(_context14.t0.payment_intent.status === "canceled")) { - _context14.next = 11; - break; - } - - return _context14.abrupt("return", _context14.t0.payment_intent); - - case 11: - throw _context14.t0; - - case 12: - case "end": - return _context14.stop(); - } - } - }, _callee14, this, [[1, 7]]); - })); - - function cancelPayment(_x18) { - return _cancelPayment.apply(this, arguments); - } - - return cancelPayment; - }() - /** - * Constructs Stripe Webhook event - * @param {object} data - the data of the webhook request: req.body - * @param {object} signature - the Stripe signature on the event, that - * ensures integrity of the webhook event - * @return {object} Stripe Webhook event - */ - - }, { - key: "constructWebhookEvent", - value: function constructWebhookEvent(data, signature) { - return this.stripe_.webhooks.constructEvent(data, signature, this.options_.webhook_secret); - } - }]); - - return StripeBase; -}(_medusa.AbstractPaymentService); - -_defineProperty(StripeBase, "identifier", null); - -var _default = StripeBase; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/package.json b/packages/medusa-payment-stripe/package.json index 8c7c645836521..9716e6548742b 100644 --- a/packages/medusa-payment-stripe/package.json +++ b/packages/medusa-payment-stripe/package.json @@ -23,7 +23,8 @@ "@medusajs/medusa": "^1.7.7", "@types/stripe": "^8.0.417", "cross-env": "^5.2.1", - "jest": "^25.5.4" + "jest": "^25.5.4", + "rewire": "^6.0.0" }, "peerDependencies": { "@medusajs/medusa": "^1.7.7" diff --git a/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js b/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js deleted file mode 100644 index 9f58040cea0db..0000000000000 --- a/packages/medusa-payment-stripe/services/__mocks__/stripe-provider.js +++ /dev/null @@ -1,63 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = exports.StripeProviderServiceMock = void 0; - -var _medusaTestUtils = require("medusa-test-utils"); - -var StripeProviderServiceMock = { - retrievePayment: jest.fn().mockImplementation(function (payData) { - if (payData.id === "pi_123456789") { - return Promise.resolve({ - id: "pi", - customer: "cus_123456789" - }); - } - - if (payData.id === "pi_no") { - return Promise.resolve({ - id: "pi_no" - }); - } - - return Promise.resolve(undefined); - }), - cancelPayment: jest.fn().mockImplementation(function (cart) { - return Promise.resolve(); - }), - updatePaymentIntentCustomer: jest.fn().mockImplementation(function (cart) { - return Promise.resolve(); - }), - retrieveCustomer: jest.fn().mockImplementation(function (customerId) { - if (customerId === "cus_123456789_new") { - return Promise.resolve({ - id: "cus_123456789_new" - }); - } - - return Promise.resolve(undefined); - }), - createCustomer: jest.fn().mockImplementation(function (customer) { - if (customer._id === _medusaTestUtils.IdMap.getId("vvd")) { - return Promise.resolve({ - id: "cus_123456789_new_vvd" - }); - } - - return Promise.resolve(undefined); - }), - createPayment: jest.fn().mockImplementation(function (cart) { - return Promise.resolve({ - id: "pi_new", - customer: "cus_123456789_new" - }); - }) -}; -exports.StripeProviderServiceMock = StripeProviderServiceMock; -var mock = jest.fn().mockImplementation(function () { - return StripeProviderServiceMock; -}); -var _default = mock; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-bancontact.js b/packages/medusa-payment-stripe/services/stripe-bancontact.js deleted file mode 100644 index 1fef577f0fa3c..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-bancontact.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var BancontactProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(BancontactProviderService, _StripeBase); - - var _super = _createSuper(BancontactProviderService); - - function BancontactProviderService(_, options) { - _classCallCheck(this, BancontactProviderService); - - return _super.call(this, _, options); - } - - _createClass(BancontactProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return { - payment_method_types: ["bancontact"], - capture_method: "automatic" - }; - } - }]); - - return BancontactProviderService; -}(_stripeBase["default"]); - -_defineProperty(BancontactProviderService, "identifier", "stripe-bancontact"); - -var _default = BancontactProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-blik.js b/packages/medusa-payment-stripe/services/stripe-blik.js deleted file mode 100644 index 0b05d94eb0b4c..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-blik.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var BlikProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(BlikProviderService, _StripeBase); - - var _super = _createSuper(BlikProviderService); - - function BlikProviderService(_, options) { - _classCallCheck(this, BlikProviderService); - - return _super.call(this, _, options); - } - - _createClass(BlikProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return { - payment_method_types: ["blik"], - capture_method: "automatic" - }; - } - }]); - - return BlikProviderService; -}(_stripeBase["default"]); - -_defineProperty(BlikProviderService, "identifier", "stripe-blik"); - -var _default = BlikProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-giropay.js b/packages/medusa-payment-stripe/services/stripe-giropay.js deleted file mode 100644 index 8c7cb1587b923..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-giropay.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var GiropayProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(GiropayProviderService, _StripeBase); - - var _super = _createSuper(GiropayProviderService); - - function GiropayProviderService(_, options) { - _classCallCheck(this, GiropayProviderService); - - return _super.call(this, _, options); - } - - _createClass(GiropayProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return { - payment_method_types: ["giropay"], - capture_method: "automatic" - }; - } - }]); - - return GiropayProviderService; -}(_stripeBase["default"]); - -_defineProperty(GiropayProviderService, "identifier", "stripe-giropay"); - -var _default = GiropayProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-ideal.js b/packages/medusa-payment-stripe/services/stripe-ideal.js deleted file mode 100644 index ced727f5fc289..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-ideal.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var IdealProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(IdealProviderService, _StripeBase); - - var _super = _createSuper(IdealProviderService); - - function IdealProviderService(_, options) { - _classCallCheck(this, IdealProviderService); - - return _super.call(this, _, options); - } - - _createClass(IdealProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return { - payment_method_types: ["ideal"], - capture_method: "automatic" - }; - } - }]); - - return IdealProviderService; -}(_stripeBase["default"]); - -_defineProperty(IdealProviderService, "identifier", "stripe-ideal"); - -var _default = IdealProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-provider.js b/packages/medusa-payment-stripe/services/stripe-provider.js deleted file mode 100644 index f201e497afbf7..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-provider.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var StripeProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(StripeProviderService, _StripeBase); - - var _super = _createSuper(StripeProviderService); - - function StripeProviderService(_, options) { - _classCallCheck(this, StripeProviderService); - - return _super.call(this, _, options); - } - - _createClass(StripeProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return {}; - } - }]); - - return StripeProviderService; -}(_stripeBase["default"]); - -_defineProperty(StripeProviderService, "identifier", "stripe"); - -var _default = StripeProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/services/stripe-przelewy24.js b/packages/medusa-payment-stripe/services/stripe-przelewy24.js deleted file mode 100644 index 00bb7df48c610..0000000000000 --- a/packages/medusa-payment-stripe/services/stripe-przelewy24.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -var _stripeBase = _interopRequireDefault(require("../helpers/stripe-base")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } - -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var Przelewy24ProviderService = /*#__PURE__*/function (_StripeBase) { - _inherits(Przelewy24ProviderService, _StripeBase); - - var _super = _createSuper(Przelewy24ProviderService); - - function Przelewy24ProviderService(_, options) { - _classCallCheck(this, Przelewy24ProviderService); - - return _super.call(this, _, options); - } - - _createClass(Przelewy24ProviderService, [{ - key: "paymentIntentOptions", - get: function get() { - return { - payment_method_types: ["p24"], - capture_method: "automatic" - }; - } - }]); - - return Przelewy24ProviderService; -}(_stripeBase["default"]); - -_defineProperty(Przelewy24ProviderService, "identifier", "stripe-przelewy24"); - -var _default = Przelewy24ProviderService; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa-payment-stripe/src/api/hooks/stripe.ts b/packages/medusa-payment-stripe/src/api/hooks/stripe.ts index 37b6670846184..cb66a17e91b58 100644 --- a/packages/medusa-payment-stripe/src/api/hooks/stripe.ts +++ b/packages/medusa-payment-stripe/src/api/hooks/stripe.ts @@ -16,5 +16,10 @@ export default async (req: Request, res: Response) => { const paymentIntent = event.data.object - await handlePaymentHook(event, req, res, paymentIntent) + const { statusCode } = await handlePaymentHook({ + event, + container: req.scope, + paymentIntent, + }) + res.sendStatus(statusCode) } diff --git a/packages/medusa-payment-stripe/src/api/utils/utils.ts b/packages/medusa-payment-stripe/src/api/utils/utils.ts index 046025c0932bf..931d4877c6f88 100644 --- a/packages/medusa-payment-stripe/src/api/utils/utils.ts +++ b/packages/medusa-payment-stripe/src/api/utils/utils.ts @@ -29,16 +29,16 @@ export function isPaymentCollection(id) { } export function buildError(event: string, err: Stripe.StripeRawError): string { - let message = `Stripe webhook ${event} handling failed\n${ + let message = `Stripe webhook ${event} handling failed${EOL}${ err?.detail ?? err?.message }` if (err?.code === PostgresError.SERIALIZATION_FAILURE) { - message = `Stripe webhook ${event} handle failed. This can happen when this webhook is triggered during a cart completion and can be ignored. This event should be retried automatically.\n${ + message = `Stripe webhook ${event} handle failed. This can happen when this webhook is triggered during a cart completion and can be ignored. This event should be retried automatically.${EOL}${ err?.detail ?? err?.message }` } if (err?.code === "409") { - message = `Stripe webhook ${event} handle failed.\n${ + message = `Stripe webhook ${event} handle failed.${EOL}${ err?.detail ?? err?.message }` } @@ -46,10 +46,23 @@ export function buildError(event: string, err: Stripe.StripeRawError): string { return message } -export async function handlePaymentHook(event, req, res, paymentIntent) { - const logger = req.scope.resolve("logger") +export async function handlePaymentHook({ + event, + container, + paymentIntent, +}: { + event: { type: string } + container: AwilixContainer + paymentIntent: { + id: string + metadata: { cart_id?: string; resource_id?: string } + last_payment_error?: { message: string } + } +}): Promise<{ statusCode: number }> { + const logger = container.resolve("logger") - const cartId = paymentIntent.metadata.cart_id // Backward compatibility + const cartId = + paymentIntent.metadata.cart_id ?? paymentIntent.metadata.resource_id // Backward compatibility const resourceId = paymentIntent.metadata.resource_id switch (event.type) { @@ -60,12 +73,12 @@ export async function handlePaymentHook(event, req, res, paymentIntent) { cartId, resourceId, isPaymentCollection: isPaymentCollection(resourceId), - container: req.scope, + container, }) } catch (err) { - const message = buildError(event, err) + const message = buildError(event.type, err) logger.warn(message) - return res.sendStatus(409) + return { statusCode: 409 } } break @@ -74,30 +87,29 @@ export async function handlePaymentHook(event, req, res, paymentIntent) { await onPaymentAmountCapturableUpdate({ paymentIntent, cartId, - container: req.scope, + container, }) } catch (err) { - const message = buildError(event, err) + const message = buildError(event.type, err) logger.warn(message) - return res.sendStatus(409) + return { statusCode: 409 } } break case "payment_intent.payment_failed": { - const intent = event.data.object const message = - intent.last_payment_error && intent.last_payment_error.message + paymentIntent.last_payment_error && + paymentIntent.last_payment_error.message logger.error( - `The payment of the payment intent ${intent.id} has failed${EOL}${message}` + `The payment of the payment intent ${paymentIntent.id} has failed${EOL}${message}` ) break } default: - res.sendStatus(204) - return + return { statusCode: 204 } } - res.sendStatus(200) + return { statusCode: 200 } } async function onPaymentIntentSucceeded({ @@ -110,13 +122,6 @@ async function onPaymentIntentSucceeded({ const manager = container.resolve("manager") await manager.transaction(async (transactionManager) => { - await completeCartIfNecessary({ - paymentIntent, - cartId, - container, - transactionManager, - }) - if (isPaymentCollection) { await capturePaymenCollectiontIfNecessary({ paymentIntent, @@ -124,6 +129,13 @@ async function onPaymentIntentSucceeded({ container, }) } else { + await completeCartIfNecessary({ + paymentIntent, + cartId, + container, + transactionManager, + }) + await capturePaymentIfNecessary({ cartId, transactionManager, @@ -187,8 +199,7 @@ async function capturePaymentIfNecessary({ .retrieveByCartId(cartId) .catch(() => undefined) - if (order.payment_status !== "captured") { - const orderService = container.resolve("orderService") + if (order?.payment_status !== "captured") { await orderService .withTransaction(transactionManager) .capturePayment(order.id) @@ -215,24 +226,33 @@ async function completeCartIfNecessary({ "idempotencyKeyService" ) - let idempotencyKey - try { - idempotencyKey = await idempotencyKeyService - .withTransaction(transactionManager) - .create({ - request_method: "post", - request_path: "/stripe/hooks", - request_params: { - cart_id: cartId, - payment_intent_id: paymentIntent.id, - }, - }) - } catch (error) { - throw new MedusaError( - MedusaError.Types.UNEXPECTED_STATE, - "Failed to create idempotency key", - "400" - ) + const idempotencyConstraints = { + request_method: "post", + request_path: "/stripe/hooks", + request_params: { + cart_id: cartId, + payment_intent_id: paymentIntent.id, + }, + } + + const idempotencyKeyServiceTx = + idempotencyKeyService.withTransaction(transactionManager) + let idempotencyKey = await idempotencyKeyServiceTx.retrieve( + idempotencyConstraints + ) + + if (!idempotencyKey) { + try { + idempotencyKey = await idempotencyKeyService + .withTransaction(transactionManager) + .create(idempotencyConstraints) + } catch (error) { + throw new MedusaError( + MedusaError.Types.UNEXPECTED_STATE, + "Failed to create idempotency key", + "400" + ) + } } const cart = await cartService diff --git a/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts b/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts index e400b3891b1bd..276aec919e838 100644 --- a/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts +++ b/packages/medusa-payment-stripe/src/core/__tests__/stripe-base.spec.ts @@ -185,7 +185,7 @@ describe("StripeTest", () => { expect(result).toEqual({ error: - "An error occurred in InitiatePayment during the creation of the stripe customer", + "An error occurred in initiatePayment when creating a Stripe customer", code: "", detail: "Error", }) @@ -287,8 +287,7 @@ describe("StripeTest", () => { const result = await stripeTest.cancelPayment(cancelPaymentFailData) expect(result).toEqual({ - error: - "An error occurred in cancelPayment during the cancellation of the payment", + error: "An error occurred in cancelPayment", code: "", detail: "Error", }) @@ -335,8 +334,7 @@ describe("StripeTest", () => { ) expect(result).toEqual({ - error: - "An error occurred in deletePayment during the capture of the payment", + error: "An error occurred in deletePayment", code: "", detail: "Error", }) @@ -379,8 +377,7 @@ describe("StripeTest", () => { const result = await stripeTest.cancelPayment(deletePaymentFailData) expect(result).toEqual({ - error: - "An error occurred in cancelPayment during the cancellation of the payment", + error: "An error occurred in cancelPayment", code: "", detail: "Error", }) @@ -419,7 +416,7 @@ describe("StripeTest", () => { ) expect(result).toEqual({ - error: "An error occurred in refundPayment during the refundPayment", + error: "An error occurred in refundPayment", code: "", detail: "Error", }) @@ -526,7 +523,7 @@ describe("StripeTest", () => { "An error occurred in updatePayment during the initiate of the new payment for the new customer", code: "", detail: - "An error occurred in InitiatePayment during the creation of the stripe customer" + + "An error occurred in initiatePayment when creating a Stripe customer" + EOL + "Error", }) @@ -576,8 +573,7 @@ describe("StripeTest", () => { ) expect(result).toEqual({ - error: - "An error occurred in updatePayment during the update of the payment", + error: "An error occurred in updatePayment", code: "", detail: "Error", }) diff --git a/packages/medusa-payment-stripe/src/core/stripe-base.ts b/packages/medusa-payment-stripe/src/core/stripe-base.ts index 89ec3b25149be..2f6f7089bb3b0 100644 --- a/packages/medusa-payment-stripe/src/core/stripe-base.ts +++ b/packages/medusa-payment-stripe/src/core/stripe-base.ts @@ -29,7 +29,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { this.init() } - init(): void { + protected init(): void { this.stripe_ = this.stripe_ || new Stripe(this.options_.api_key, { @@ -120,7 +120,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { }) } catch (e) { return this.buildError( - "An error occurred in InitiatePayment during the creation of the stripe customer", + "An error occurred in initiatePayment when creating a Stripe customer", e ) } @@ -181,10 +181,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { return error.payment_intent } - return this.buildError( - "An error occurred in cancelPayment during the cancellation of the payment", - error - ) + return this.buildError("An error occurred in cancelPayment", error) } } @@ -204,10 +201,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { } } - return this.buildError( - "An error occurred in deletePayment during the capture of the payment", - error - ) + return this.buildError("An error occurred in deletePayment", error) } } @@ -233,10 +227,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { payment_intent: id as string, }) } catch (e) { - return this.buildError( - "An error occurred in refundPayment during the refundPayment", - e - ) + return this.buildError("An error occurred in refundPayment", e) } return paymentSessionData @@ -285,10 +276,7 @@ abstract class StripeBase extends AbstractPaymentProcessor { return { session_data: sessionData } } catch (e) { - return this.buildError( - "An error occurred in updatePayment during the update of the payment", - e - ) + return this.buildError("An error occurred in updatePayment", e) } } } diff --git a/packages/medusa-payment-stripe/subscribers/cart.js b/packages/medusa-payment-stripe/subscribers/cart.js deleted file mode 100644 index 23d641c870710..0000000000000 --- a/packages/medusa-payment-stripe/subscribers/cart.js +++ /dev/null @@ -1,125 +0,0 @@ -"use strict"; - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = void 0; - -function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && _instanceof(outerFn.prototype, Generator) ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } - -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } - -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } - -function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - -var CartSubscriber = /*#__PURE__*/function () { - function CartSubscriber(_ref) { - var _this = this; - - var cartService = _ref.cartService, - customerService = _ref.customerService, - paymentProviderService = _ref.paymentProviderService, - eventBusService = _ref.eventBusService; - - _classCallCheck(this, CartSubscriber); - - this.cartService_ = cartService; - this.customerService_ = customerService; - this.paymentProviderService_ = paymentProviderService; - this.eventBus_ = eventBusService; - this.eventBus_.subscribe("cart.customer_updated", /*#__PURE__*/function () { - var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(cart) { - return _regeneratorRuntime().wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return _this.onCustomerUpdated(cart); - - case 2: - case "end": - return _context.stop(); - } - } - }, _callee); - })); - - return function (_x) { - return _ref2.apply(this, arguments); - }; - }()); - } - - _createClass(CartSubscriber, [{ - key: "onCustomerUpdated", - value: function () { - var _onCustomerUpdated = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(cartId) { - var _cart$payment_session; - - var cart, session; - return _regeneratorRuntime().wrap(function _callee2$(_context2) { - while (1) { - switch (_context2.prev = _context2.next) { - case 0: - _context2.next = 2; - return this.cartService_.retrieve(cartId, { - select: ["subtotal", "tax_total", "shipping_total", "discount_total", "total"], - relations: ["items", "billing_address", "shipping_address", "region", "region.payment_providers", "items", "items.adjustments", "payment_sessions", "customer"] - }); - - case 2: - cart = _context2.sent; - - if ((_cart$payment_session = cart.payment_sessions) !== null && _cart$payment_session !== void 0 && _cart$payment_session.length) { - _context2.next = 5; - break; - } - - return _context2.abrupt("return", Promise.resolve()); - - case 5: - session = cart.payment_sessions.find(function (ps) { - return ps.provider_id === "stripe"; - }); - - if (!session) { - _context2.next = 10; - break; - } - - _context2.next = 9; - return this.paymentProviderService_.updateSession(session, cart); - - case 9: - return _context2.abrupt("return", _context2.sent); - - case 10: - case "end": - return _context2.stop(); - } - } - }, _callee2, this); - })); - - function onCustomerUpdated(_x2) { - return _onCustomerUpdated.apply(this, arguments); - } - - return onCustomerUpdated; - }() - }]); - - return CartSubscriber; -}(); - -var _default = CartSubscriber; -exports["default"] = _default; \ No newline at end of file diff --git a/packages/medusa/src/services/idempotency-key.ts b/packages/medusa/src/services/idempotency-key.ts index 490626990849a..04e3180132cbd 100644 --- a/packages/medusa/src/services/idempotency-key.ts +++ b/packages/medusa/src/services/idempotency-key.ts @@ -8,6 +8,8 @@ import { CreateIdempotencyKeyInput, IdempotencyCallbackResult, } from "../types/idempotency-key" +import { Selector } from "../types/common" +import { buildQuery, isString } from "../utils" const KEY_LOCKED_TIMEOUT = 1000 @@ -75,14 +77,16 @@ class IdempotencyKeyService extends TransactionBaseService { /** * Retrieves an idempotency key - * @param idempotencyKey - key to retrieve + * @param idempotencyKeyOrSelector - key or selector to retrieve * @return idempotency key */ - async retrieve(idempotencyKey: string): Promise { - if (!isDefined(idempotencyKey)) { + async retrieve( + idempotencyKeyOrSelector: string | Selector + ): Promise { + if (!isDefined(idempotencyKeyOrSelector)) { throw new MedusaError( MedusaError.Types.NOT_FOUND, - `"idempotencyKey" must be defined` + `"idempotencyKeyOrSelector" must be defined` ) } @@ -90,17 +94,36 @@ class IdempotencyKeyService extends TransactionBaseService { this.idempotencyKeyRepository_ ) - const iKey = await idempotencyKeyRepo.findOne({ - where: { idempotency_key: idempotencyKey }, - }) + const queryConfig = isString(idempotencyKeyOrSelector) + ? { where: { idempotency_key: idempotencyKeyOrSelector } } + : idempotencyKeyOrSelector + const query = buildQuery(queryConfig) - if (!iKey) { - throw new MedusaError( - MedusaError.Types.NOT_FOUND, - `Idempotency key ${idempotencyKey} was not found` + const iKeys = await idempotencyKeyRepo.find(query) + + if (iKeys.length > 1) { + throw new Error( + `The provided constraints ${JSON.stringify( + idempotencyKeyOrSelector + )} result in multiple idempotency key found. There should only be one idempotency key found.` ) } + const iKey = iKeys[0] + + if (!iKey) { + let message + if (isString(idempotencyKeyOrSelector)) { + message = `Idempotency key ${idempotencyKeyOrSelector} was not found` + } else { + message = `Idempotency key with constraint ${JSON.stringify( + idempotencyKeyOrSelector + )} was not found` + } + + throw new MedusaError(MedusaError.Types.NOT_FOUND, message) + } + return iKey } diff --git a/packages/modules-sdk/package.json b/packages/modules-sdk/package.json index da41257d040e2..3fa52def4d31b 100644 --- a/packages/modules-sdk/package.json +++ b/packages/modules-sdk/package.json @@ -32,6 +32,5 @@ "build": "tsc --build", "test": "jest", "test:unit": "jest" - }, - "peerDependencies": {} + } } From 73145d488188f82509f60f530beb01b4c63b340a Mon Sep 17 00:00:00 2001 From: adrien2p Date: Tue, 28 Feb 2023 11:37:49 +0100 Subject: [PATCH 32/36] remove unnecessary deps and cleanup completion --- packages/medusa-payment-stripe/package.json | 3 +-- .../medusa-payment-stripe/src/api/utils/utils.ts | 14 +++----------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/packages/medusa-payment-stripe/package.json b/packages/medusa-payment-stripe/package.json index 9716e6548742b..8c7c645836521 100644 --- a/packages/medusa-payment-stripe/package.json +++ b/packages/medusa-payment-stripe/package.json @@ -23,8 +23,7 @@ "@medusajs/medusa": "^1.7.7", "@types/stripe": "^8.0.417", "cross-env": "^5.2.1", - "jest": "^25.5.4", - "rewire": "^6.0.0" + "jest": "^25.5.4" }, "peerDependencies": { "@medusajs/medusa": "^1.7.7" diff --git a/packages/medusa-payment-stripe/src/api/utils/utils.ts b/packages/medusa-payment-stripe/src/api/utils/utils.ts index 931d4877c6f88..ee44b52f31de8 100644 --- a/packages/medusa-payment-stripe/src/api/utils/utils.ts +++ b/packages/medusa-payment-stripe/src/api/utils/utils.ts @@ -242,17 +242,9 @@ async function completeCartIfNecessary({ ) if (!idempotencyKey) { - try { - idempotencyKey = await idempotencyKeyService - .withTransaction(transactionManager) - .create(idempotencyConstraints) - } catch (error) { - throw new MedusaError( - MedusaError.Types.UNEXPECTED_STATE, - "Failed to create idempotency key", - "400" - ) - } + idempotencyKey = await idempotencyKeyService + .withTransaction(transactionManager) + .create(idempotencyConstraints) } const cart = await cartService From 1d850f8451e41a822e3f36b51a982201088f4f23 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Tue, 28 Feb 2023 11:41:43 +0100 Subject: [PATCH 33/36] push web hook tests --- packages/medusa-payment-stripe/.gitignore | 6 - .../src/api/utils/__fixtures__/container.ts | 139 +++++++ .../src/api/utils/__fixtures__/data.ts | 14 + .../src/api/utils/__tests__/utils.spec.ts | 361 ++++++++++++++++++ 4 files changed, 514 insertions(+), 6 deletions(-) create mode 100644 packages/medusa-payment-stripe/src/api/utils/__fixtures__/container.ts create mode 100644 packages/medusa-payment-stripe/src/api/utils/__fixtures__/data.ts create mode 100644 packages/medusa-payment-stripe/src/api/utils/__tests__/utils.spec.ts diff --git a/packages/medusa-payment-stripe/.gitignore b/packages/medusa-payment-stripe/.gitignore index ae519965e204f..83cb36a41ea17 100644 --- a/packages/medusa-payment-stripe/.gitignore +++ b/packages/medusa-payment-stripe/.gitignore @@ -2,9 +2,3 @@ dist node_modules .DS_store yarn.lock - -services -core -api -__mocks__ -subscribers \ No newline at end of file diff --git a/packages/medusa-payment-stripe/src/api/utils/__fixtures__/container.ts b/packages/medusa-payment-stripe/src/api/utils/__fixtures__/container.ts new file mode 100644 index 0000000000000..9a995d81a563f --- /dev/null +++ b/packages/medusa-payment-stripe/src/api/utils/__fixtures__/container.ts @@ -0,0 +1,139 @@ +import { asValue, createContainer } from "awilix" +import { + existingCartId, + existingCartIdWithCapturedStatus, + existingResourceId, + existingResourceNotCapturedId, + nonExistingCartId, + orderIdForExistingCartId, + paymentId, + paymentIntentId, + throwingCartId, +} from "./data" + +export const container = createContainer() +container.register( + "logger", + asValue({ + warn: jest.fn(), + error: jest.fn(), + }) +) + +container.register( + "manager", + asValue({ + transaction: function (cb) { + return cb(this) + }, + }) +) + +container.register( + "idempotencyKeyService", + asValue({ + withTransaction: function () { + return this + }, + retrieve: jest.fn().mockReturnValue(undefined), + create: jest.fn().mockReturnValue({}), + }) +) + +container.register( + "cartCompletionStrategy", + asValue({ + withTransaction: function () { + return this + }, + complete: jest.fn(), + }) +) + +container.register( + "cartService", + asValue({ + withTransaction: function () { + return this + }, + retrieve: jest.fn().mockReturnValue({ context: {} }), + }) +) + +container.register( + "orderService", + asValue({ + withTransaction: function () { + return this + }, + retrieveByCartId: jest.fn().mockImplementation(async (cartId) => { + if (cartId === existingCartId) { + return { + id: orderIdForExistingCartId, + payment_status: "pending", + } + } + + if (cartId === existingCartIdWithCapturedStatus) { + return { + id: "order-1", + payment_status: "captured", + } + } + + if (cartId === throwingCartId) { + throw new Error("Error") + } + + if (cartId === nonExistingCartId) { + return undefined + } + + return {} + }), + capturePayment: jest.fn(), + }) +) + +container.register( + "paymentCollectionService", + asValue({ + withTransaction: function () { + return this + }, + retrieve: jest.fn().mockImplementation(async (resourceId) => { + if (resourceId === existingResourceId) { + return { + id: existingResourceId, + payments: [ + { + id: paymentId, + data: { + id: paymentIntentId, + }, + captured_at: "date", + }, + ], + } + } + + if (resourceId === existingResourceNotCapturedId) { + return { + id: existingResourceNotCapturedId, + payments: [ + { + id: paymentId, + data: { + id: paymentIntentId, + }, + captured_at: null, + }, + ], + } + } + + return {} + }), + capture: jest.fn(), + }) +) diff --git a/packages/medusa-payment-stripe/src/api/utils/__fixtures__/data.ts b/packages/medusa-payment-stripe/src/api/utils/__fixtures__/data.ts new file mode 100644 index 0000000000000..9ccf6f0194504 --- /dev/null +++ b/packages/medusa-payment-stripe/src/api/utils/__fixtures__/data.ts @@ -0,0 +1,14 @@ +export const existingCartId = "existingCartId" +export const existingCartIdWithCapturedStatus = + "existingCartIdWithCapturedStatus" +export const nonExistingCartId = "nonExistingCartId" +export const throwingCartId = "throwingCartId" + +export const existingResourceId = "paycol_existing" +export const existingResourceNotCapturedId = "paycol_existing_not_aptured" + +export const orderIdForExistingCartId = "order-1" + +export const paymentIntentId = "paymentIntentId" + +export const paymentId = "paymentId" diff --git a/packages/medusa-payment-stripe/src/api/utils/__tests__/utils.spec.ts b/packages/medusa-payment-stripe/src/api/utils/__tests__/utils.spec.ts new file mode 100644 index 0000000000000..87028d1a6dc22 --- /dev/null +++ b/packages/medusa-payment-stripe/src/api/utils/__tests__/utils.spec.ts @@ -0,0 +1,361 @@ +import { PostgresError } from "@medusajs/medusa" +import Stripe from "stripe" +import { EOL } from "os" + +import { buildError, handlePaymentHook, isPaymentCollection } from "../utils" +import { container } from "../__fixtures__/container" +import { + existingCartId, + existingCartIdWithCapturedStatus, + existingResourceId, + existingResourceNotCapturedId, + nonExistingCartId, + orderIdForExistingCartId, + paymentId, + paymentIntentId, +} from "../__fixtures__/data" + +describe("Utils", () => { + afterEach(() => { + jest.clearAllMocks() + }) + + describe("isPaymentCollection", () => { + it("should return return true if starts with paycol otherwise return false", () => { + let result = isPaymentCollection("paycol_test") + expect(result).toBeTruthy() + + result = isPaymentCollection("nopaycol_test") + expect(result).toBeFalsy() + }) + }) + + describe("buildError", () => { + it("should return the appropriate error message", () => { + let event = "test_event" + let error = { + code: PostgresError.SERIALIZATION_FAILURE, + detail: "some details", + } as Stripe.StripeRawError + + let message = buildError(event, error) + expect(message).toBe( + `Stripe webhook ${event} handle failed. This can happen when this webhook is triggered during a cart completion and can be ignored. This event should be retried automatically.${EOL}${error.detail}` + ) + + event = "test_event" + error = { + code: "409", + detail: "some details", + } as Stripe.StripeRawError + + message = buildError(event, error) + expect(message).toBe( + `Stripe webhook ${event} handle failed.${EOL}${error.detail}` + ) + + event = "test_event" + error = { + code: "", + detail: "some details", + } as Stripe.StripeRawError + + message = buildError(event, error) + expect(message).toBe( + `Stripe webhook ${event} handling failed${EOL}${error.detail}` + ) + }) + }) + + describe("handlePaymentHook", () => { + describe("on event type payment_intent.succeeded", () => { + describe("in a payment context", () => { + it("should complete the cart on non existing order", async () => { + const event = { type: "payment_intent.succeeded" } + const paymentIntent = { + id: paymentIntentId, + metadata: { cart_id: nonExistingCartId }, + } + + await handlePaymentHook({ event, container, paymentIntent }) + + const orderService = container.resolve("orderService") + const cartCompletionStrategy = container.resolve( + "cartCompletionStrategy" + ) + const idempotencyKeyService = container.resolve( + "idempotencyKeyService" + ) + const cartService = container.resolve("cartService") + + expect(orderService.retrieveByCartId).toHaveBeenCalled() + expect(orderService.retrieveByCartId).toHaveBeenCalledWith( + paymentIntent.metadata.cart_id + ) + + expect(idempotencyKeyService.retrieve).toHaveBeenCalled() + expect(idempotencyKeyService.retrieve).toHaveBeenCalledWith({ + request_method: "post", + request_path: "/stripe/hooks", + request_params: { + cart_id: paymentIntent.metadata.cart_id, + payment_intent_id: paymentIntent.id, + }, + }) + + expect(idempotencyKeyService.create).toHaveBeenCalled() + expect(idempotencyKeyService.create).toHaveBeenCalledWith({ + request_method: "post", + request_path: "/stripe/hooks", + request_params: { + cart_id: paymentIntent.metadata.cart_id, + payment_intent_id: paymentIntent.id, + }, + }) + + expect(cartService.retrieve).toHaveBeenCalled() + expect(cartService.retrieve).toHaveBeenCalledWith( + paymentIntent.metadata.cart_id, + { select: ["context"] } + ) + + expect(cartCompletionStrategy.complete).toHaveBeenCalled() + expect(cartCompletionStrategy.complete).toHaveBeenCalledWith( + paymentIntent.metadata.cart_id, + {}, + { id: undefined } + ) + }) + + it("should not try to complete the cart on existing order", async () => { + const event = { type: "payment_intent.succeeded" } + const paymentIntent = { + id: paymentIntentId, + metadata: { cart_id: existingCartId }, + } + + await handlePaymentHook({ event, container, paymentIntent }) + + const orderService = container.resolve("orderService") + const cartCompletionStrategy = container.resolve( + "cartCompletionStrategy" + ) + const idempotencyKeyService = container.resolve( + "idempotencyKeyService" + ) + const cartService = container.resolve("cartService") + + expect(orderService.retrieveByCartId).toHaveBeenCalled() + expect(orderService.retrieveByCartId).toHaveBeenCalledWith( + paymentIntent.metadata.cart_id + ) + + expect(idempotencyKeyService.retrieve).not.toHaveBeenCalled() + + expect(idempotencyKeyService.create).not.toHaveBeenCalled() + + expect(cartService.retrieve).not.toHaveBeenCalled() + + expect(cartCompletionStrategy.complete).not.toHaveBeenCalled() + }) + + it("should capture the payment if not already captured", async () => { + const event = { type: "payment_intent.succeeded" } + const paymentIntent = { + id: paymentIntentId, + metadata: { cart_id: existingCartId }, + } + + await handlePaymentHook({ event, container, paymentIntent }) + + const orderService = container.resolve("orderService") + + expect(orderService.retrieveByCartId).toHaveBeenCalled() + expect(orderService.retrieveByCartId).toHaveBeenCalledWith( + paymentIntent.metadata.cart_id + ) + + expect(orderService.capturePayment).toHaveBeenCalled() + expect(orderService.capturePayment).toHaveBeenCalledWith( + orderIdForExistingCartId + ) + }) + + it("should not capture the payment if already captured", async () => { + const event = { type: "payment_intent.succeeded" } + const paymentIntent = { + id: paymentIntentId, + metadata: { cart_id: existingCartIdWithCapturedStatus }, + } + + await handlePaymentHook({ event, container, paymentIntent }) + + const orderService = container.resolve("orderService") + + expect(orderService.retrieveByCartId).toHaveBeenCalled() + expect(orderService.retrieveByCartId).toHaveBeenCalledWith( + paymentIntent.metadata.cart_id + ) + + expect(orderService.capturePayment).not.toHaveBeenCalled() + }) + }) + + describe("in a payment collection context", () => { + it("should capture the payment collection if not already captured", async () => { + const event = { type: "payment_intent.succeeded" } + const paymentIntent = { + id: paymentIntentId, + metadata: { resource_id: existingResourceNotCapturedId }, + } + + await handlePaymentHook({ event, container, paymentIntent }) + + const paymentCollectionService = container.resolve( + "paymentCollectionService" + ) + + expect(paymentCollectionService.retrieve).toHaveBeenCalled() + expect(paymentCollectionService.retrieve).toHaveBeenCalledWith( + paymentIntent.metadata.resource_id, + { relations: ["payments"] } + ) + + expect(paymentCollectionService.capture).toHaveBeenCalled() + expect(paymentCollectionService.capture).toHaveBeenCalledWith( + paymentId + ) + }) + + it("should not capture the payment collection if already captured", async () => { + const event = { type: "payment_intent.succeeded" } + const paymentIntent = { + id: paymentIntentId, + metadata: { resource_id: existingResourceId }, + } + + await handlePaymentHook({ event, container, paymentIntent }) + + const paymentCollectionService = container.resolve( + "paymentCollectionService" + ) + + expect(paymentCollectionService.retrieve).toHaveBeenCalled() + expect(paymentCollectionService.retrieve).toHaveBeenCalledWith( + paymentIntent.metadata.resource_id, + { relations: ["payments"] } + ) + + expect(paymentCollectionService.capture).not.toHaveBeenCalled() + }) + }) + }) + + describe("on event type payment_intent.amount_capturable_updated", () => { + it("should complete the cart on non existing order", async () => { + const event = { type: "payment_intent.amount_capturable_updated" } + const paymentIntent = { + id: paymentIntentId, + metadata: { cart_id: nonExistingCartId }, + } + + await handlePaymentHook({ event, container, paymentIntent }) + + const orderService = container.resolve("orderService") + const cartCompletionStrategy = container.resolve( + "cartCompletionStrategy" + ) + const idempotencyKeyService = container.resolve("idempotencyKeyService") + const cartService = container.resolve("cartService") + + expect(orderService.retrieveByCartId).toHaveBeenCalled() + expect(orderService.retrieveByCartId).toHaveBeenCalledWith( + paymentIntent.metadata.cart_id + ) + + expect(idempotencyKeyService.retrieve).toHaveBeenCalled() + expect(idempotencyKeyService.retrieve).toHaveBeenCalledWith({ + request_method: "post", + request_path: "/stripe/hooks", + request_params: { + cart_id: paymentIntent.metadata.cart_id, + payment_intent_id: paymentIntent.id, + }, + }) + + expect(idempotencyKeyService.create).toHaveBeenCalled() + expect(idempotencyKeyService.create).toHaveBeenCalledWith({ + request_method: "post", + request_path: "/stripe/hooks", + request_params: { + cart_id: paymentIntent.metadata.cart_id, + payment_intent_id: paymentIntent.id, + }, + }) + + expect(cartService.retrieve).toHaveBeenCalled() + expect(cartService.retrieve).toHaveBeenCalledWith( + paymentIntent.metadata.cart_id, + { select: ["context"] } + ) + + expect(cartCompletionStrategy.complete).toHaveBeenCalled() + expect(cartCompletionStrategy.complete).toHaveBeenCalledWith( + paymentIntent.metadata.cart_id, + {}, + { id: undefined } + ) + }) + + it("should not try to complete the cart on existing order", async () => { + const event = { type: "payment_intent.amount_capturable_updated" } + const paymentIntent = { + id: paymentIntentId, + metadata: { cart_id: existingCartId }, + } + + await handlePaymentHook({ event, container, paymentIntent }) + + const orderService = container.resolve("orderService") + const cartCompletionStrategy = container.resolve( + "cartCompletionStrategy" + ) + const idempotencyKeyService = container.resolve("idempotencyKeyService") + const cartService = container.resolve("cartService") + + expect(orderService.retrieveByCartId).toHaveBeenCalled() + expect(orderService.retrieveByCartId).toHaveBeenCalledWith( + paymentIntent.metadata.cart_id + ) + + expect(idempotencyKeyService.retrieve).not.toHaveBeenCalled() + + expect(idempotencyKeyService.create).not.toHaveBeenCalled() + + expect(cartService.retrieve).not.toHaveBeenCalled() + + expect(cartCompletionStrategy.complete).not.toHaveBeenCalled() + }) + }) + + describe("on event type payment_intent.payment_failed", () => { + it("should log the error", async () => { + const event = { type: "payment_intent.payment_failed" } + const paymentIntent = { + id: paymentIntentId, + metadata: { cart_id: nonExistingCartId }, + last_payment_error: { message: "error message" }, + } + + await handlePaymentHook({ event, container, paymentIntent }) + + const logger = container.resolve("logger") + + expect(logger.error).toHaveBeenCalled() + expect(logger.error).toHaveBeenCalledWith( + `The payment of the payment intent ${paymentIntent.id} has failed${EOL}${paymentIntent.last_payment_error.message}` + ) + }) + }) + }) +}) From 15778dd62441490ecbd0fc544cda92ed1f9c9502 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Tue, 28 Feb 2023 12:33:36 +0100 Subject: [PATCH 34/36] fix idempotency service --- packages/medusa/src/services/idempotency-key.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/medusa/src/services/idempotency-key.ts b/packages/medusa/src/services/idempotency-key.ts index 04e3180132cbd..8cb5a8e075ac4 100644 --- a/packages/medusa/src/services/idempotency-key.ts +++ b/packages/medusa/src/services/idempotency-key.ts @@ -94,10 +94,10 @@ class IdempotencyKeyService extends TransactionBaseService { this.idempotencyKeyRepository_ ) - const queryConfig = isString(idempotencyKeyOrSelector) - ? { where: { idempotency_key: idempotencyKeyOrSelector } } + const selector = isString(idempotencyKeyOrSelector) + ? { idempotency_key: idempotencyKeyOrSelector } : idempotencyKeyOrSelector - const query = buildQuery(queryConfig) + const query = buildQuery(selector) const iKeys = await idempotencyKeyRepo.find(query) From 4fe3fd5657545d3b700205a12752183668025173 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Tue, 28 Feb 2023 14:09:20 +0100 Subject: [PATCH 35/36] Use the event id in the idempotency key --- .../src/api/utils/__tests__/utils.spec.ts | 48 ++++++++----------- .../src/api/utils/utils.ts | 39 +++++++-------- packages/medusa/src/types/idempotency-key.ts | 6 +-- 3 files changed, 38 insertions(+), 55 deletions(-) diff --git a/packages/medusa-payment-stripe/src/api/utils/__tests__/utils.spec.ts b/packages/medusa-payment-stripe/src/api/utils/__tests__/utils.spec.ts index 87028d1a6dc22..0a46e2ff0c0e2 100644 --- a/packages/medusa-payment-stripe/src/api/utils/__tests__/utils.spec.ts +++ b/packages/medusa-payment-stripe/src/api/utils/__tests__/utils.spec.ts @@ -71,7 +71,7 @@ describe("Utils", () => { describe("on event type payment_intent.succeeded", () => { describe("in a payment context", () => { it("should complete the cart on non existing order", async () => { - const event = { type: "payment_intent.succeeded" } + const event = { id: "event", type: "payment_intent.succeeded" } const paymentIntent = { id: paymentIntentId, metadata: { cart_id: nonExistingCartId }, @@ -95,22 +95,14 @@ describe("Utils", () => { expect(idempotencyKeyService.retrieve).toHaveBeenCalled() expect(idempotencyKeyService.retrieve).toHaveBeenCalledWith({ - request_method: "post", request_path: "/stripe/hooks", - request_params: { - cart_id: paymentIntent.metadata.cart_id, - payment_intent_id: paymentIntent.id, - }, + idempotency_key: event.id, }) expect(idempotencyKeyService.create).toHaveBeenCalled() expect(idempotencyKeyService.create).toHaveBeenCalledWith({ - request_method: "post", request_path: "/stripe/hooks", - request_params: { - cart_id: paymentIntent.metadata.cart_id, - payment_intent_id: paymentIntent.id, - }, + idempotency_key: event.id, }) expect(cartService.retrieve).toHaveBeenCalled() @@ -128,7 +120,7 @@ describe("Utils", () => { }) it("should not try to complete the cart on existing order", async () => { - const event = { type: "payment_intent.succeeded" } + const event = { id: "event", type: "payment_intent.succeeded" } const paymentIntent = { id: paymentIntentId, metadata: { cart_id: existingCartId }, @@ -160,7 +152,7 @@ describe("Utils", () => { }) it("should capture the payment if not already captured", async () => { - const event = { type: "payment_intent.succeeded" } + const event = { id: "event", type: "payment_intent.succeeded" } const paymentIntent = { id: paymentIntentId, metadata: { cart_id: existingCartId }, @@ -182,7 +174,7 @@ describe("Utils", () => { }) it("should not capture the payment if already captured", async () => { - const event = { type: "payment_intent.succeeded" } + const event = { id: "event", type: "payment_intent.succeeded" } const paymentIntent = { id: paymentIntentId, metadata: { cart_id: existingCartIdWithCapturedStatus }, @@ -203,7 +195,7 @@ describe("Utils", () => { describe("in a payment collection context", () => { it("should capture the payment collection if not already captured", async () => { - const event = { type: "payment_intent.succeeded" } + const event = { id: "event", type: "payment_intent.succeeded" } const paymentIntent = { id: paymentIntentId, metadata: { resource_id: existingResourceNotCapturedId }, @@ -228,7 +220,7 @@ describe("Utils", () => { }) it("should not capture the payment collection if already captured", async () => { - const event = { type: "payment_intent.succeeded" } + const event = { id: "event", type: "payment_intent.succeeded" } const paymentIntent = { id: paymentIntentId, metadata: { resource_id: existingResourceId }, @@ -253,7 +245,10 @@ describe("Utils", () => { describe("on event type payment_intent.amount_capturable_updated", () => { it("should complete the cart on non existing order", async () => { - const event = { type: "payment_intent.amount_capturable_updated" } + const event = { + id: "event", + type: "payment_intent.amount_capturable_updated", + } const paymentIntent = { id: paymentIntentId, metadata: { cart_id: nonExistingCartId }, @@ -275,22 +270,14 @@ describe("Utils", () => { expect(idempotencyKeyService.retrieve).toHaveBeenCalled() expect(idempotencyKeyService.retrieve).toHaveBeenCalledWith({ - request_method: "post", request_path: "/stripe/hooks", - request_params: { - cart_id: paymentIntent.metadata.cart_id, - payment_intent_id: paymentIntent.id, - }, + idempotency_key: event.id, }) expect(idempotencyKeyService.create).toHaveBeenCalled() expect(idempotencyKeyService.create).toHaveBeenCalledWith({ - request_method: "post", request_path: "/stripe/hooks", - request_params: { - cart_id: paymentIntent.metadata.cart_id, - payment_intent_id: paymentIntent.id, - }, + idempotency_key: event.id, }) expect(cartService.retrieve).toHaveBeenCalled() @@ -308,7 +295,10 @@ describe("Utils", () => { }) it("should not try to complete the cart on existing order", async () => { - const event = { type: "payment_intent.amount_capturable_updated" } + const event = { + id: "event", + type: "payment_intent.amount_capturable_updated", + } const paymentIntent = { id: paymentIntentId, metadata: { cart_id: existingCartId }, @@ -340,7 +330,7 @@ describe("Utils", () => { describe("on event type payment_intent.payment_failed", () => { it("should log the error", async () => { - const event = { type: "payment_intent.payment_failed" } + const event = { id: "event", type: "payment_intent.payment_failed" } const paymentIntent = { id: paymentIntentId, metadata: { cart_id: nonExistingCartId }, diff --git a/packages/medusa-payment-stripe/src/api/utils/utils.ts b/packages/medusa-payment-stripe/src/api/utils/utils.ts index ee44b52f31de8..cb20ef5e23800 100644 --- a/packages/medusa-payment-stripe/src/api/utils/utils.ts +++ b/packages/medusa-payment-stripe/src/api/utils/utils.ts @@ -51,7 +51,7 @@ export async function handlePaymentHook({ container, paymentIntent, }: { - event: { type: string } + event: { type: string; id: string } container: AwilixContainer paymentIntent: { id: string @@ -69,6 +69,7 @@ export async function handlePaymentHook({ case "payment_intent.succeeded": try { await onPaymentIntentSucceeded({ + eventId: event.id, paymentIntent, cartId, resourceId, @@ -85,7 +86,7 @@ export async function handlePaymentHook({ case "payment_intent.amount_capturable_updated": try { await onPaymentAmountCapturableUpdate({ - paymentIntent, + eventId: event.id, cartId, container, }) @@ -113,6 +114,7 @@ export async function handlePaymentHook({ } async function onPaymentIntentSucceeded({ + eventId, paymentIntent, cartId, resourceId, @@ -130,7 +132,7 @@ async function onPaymentIntentSucceeded({ }) } else { await completeCartIfNecessary({ - paymentIntent, + eventId, cartId, container, transactionManager, @@ -145,16 +147,12 @@ async function onPaymentIntentSucceeded({ }) } -async function onPaymentAmountCapturableUpdate({ - paymentIntent, - cartId, - container, -}) { +async function onPaymentAmountCapturableUpdate({ eventId, cartId, container }) { const manager = container.resolve("manager") await manager.transaction(async (transactionManager) => { await completeCartIfNecessary({ - paymentIntent, + eventId, cartId, container, transactionManager, @@ -207,7 +205,7 @@ async function capturePaymentIfNecessary({ } async function completeCartIfNecessary({ - paymentIntent, + eventId, cartId, container, transactionManager, @@ -226,25 +224,20 @@ async function completeCartIfNecessary({ "idempotencyKeyService" ) - const idempotencyConstraints = { - request_method: "post", - request_path: "/stripe/hooks", - request_params: { - cart_id: cartId, - payment_intent_id: paymentIntent.id, - }, - } - const idempotencyKeyServiceTx = idempotencyKeyService.withTransaction(transactionManager) - let idempotencyKey = await idempotencyKeyServiceTx.retrieve( - idempotencyConstraints - ) + let idempotencyKey = await idempotencyKeyServiceTx.retrieve({ + request_path: "/stripe/hooks", + idempotency_key: eventId, + }) if (!idempotencyKey) { idempotencyKey = await idempotencyKeyService .withTransaction(transactionManager) - .create(idempotencyConstraints) + .create({ + request_path: "/stripe/hooks", + idempotency_key: eventId, + }) } const cart = await cartService diff --git a/packages/medusa/src/types/idempotency-key.ts b/packages/medusa/src/types/idempotency-key.ts index 1d885ee8c7d1b..ff20e9d0e1a42 100644 --- a/packages/medusa/src/types/idempotency-key.ts +++ b/packages/medusa/src/types/idempotency-key.ts @@ -1,7 +1,7 @@ export type CreateIdempotencyKeyInput = { - request_method: string - request_params: Record - request_path: string + request_method?: string + request_params?: Record + request_path?: string idempotency_key?: string } From e04dd01e202ccd8ac494df13fc407429d31d5c12 Mon Sep 17 00:00:00 2001 From: adrien2p Date: Tue, 28 Feb 2023 16:10:45 +0100 Subject: [PATCH 36/36] typos --- .../medusa-payment-stripe/src/services/stripe-przelewy24.ts | 2 +- packages/medusa-payment-stripe/src/types.ts | 2 +- packages/medusa/src/services/idempotency-key.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/medusa-payment-stripe/src/services/stripe-przelewy24.ts b/packages/medusa-payment-stripe/src/services/stripe-przelewy24.ts index 0050772d9d0ce..ae8a565680c75 100644 --- a/packages/medusa-payment-stripe/src/services/stripe-przelewy24.ts +++ b/packages/medusa-payment-stripe/src/services/stripe-przelewy24.ts @@ -2,7 +2,7 @@ import StripeBase from "../core/stripe-base" import { PaymentIntentOptions, PaymentProviderKeys } from "../types" class Przelewy24ProviderService extends StripeBase { - static identifier = PaymentProviderKeys.PRWELEWY_24 + static identifier = PaymentProviderKeys.PRZELEWY_24 constructor(_, options) { super(_, options) diff --git a/packages/medusa-payment-stripe/src/types.ts b/packages/medusa-payment-stripe/src/types.ts index 08eb005c8863e..724141272758a 100644 --- a/packages/medusa-payment-stripe/src/types.ts +++ b/packages/medusa-payment-stripe/src/types.ts @@ -36,5 +36,5 @@ export const PaymentProviderKeys = { BLIK: "stripe-blik", GIROPAY: "stripe-giropay", IDEAL: "stripe-ideal", - PRWELEWY_24: "stripe-przelewy24", + PRZELEWY_24: "stripe-przelewy24", } diff --git a/packages/medusa/src/services/idempotency-key.ts b/packages/medusa/src/services/idempotency-key.ts index 8cb5a8e075ac4..998ce8f70151f 100644 --- a/packages/medusa/src/services/idempotency-key.ts +++ b/packages/medusa/src/services/idempotency-key.ts @@ -103,9 +103,9 @@ class IdempotencyKeyService extends TransactionBaseService { if (iKeys.length > 1) { throw new Error( - `The provided constraints ${JSON.stringify( + `Multiple keys were found for constraints: ${JSON.stringify( idempotencyKeyOrSelector - )} result in multiple idempotency key found. There should only be one idempotency key found.` + )}. There should only be one.` ) } @@ -116,7 +116,7 @@ class IdempotencyKeyService extends TransactionBaseService { if (isString(idempotencyKeyOrSelector)) { message = `Idempotency key ${idempotencyKeyOrSelector} was not found` } else { - message = `Idempotency key with constraint ${JSON.stringify( + message = `Idempotency key with constraints ${JSON.stringify( idempotencyKeyOrSelector )} was not found` }