feat(medusa,medusa-payment-stripe): Move database mutation from plugin to core (#2743)
**what** The goal of that PR is to first refactor the payment provider and payment plugin to support the new API that removes the data mutation from within the plugin to be done by the core instead. In any case, this pr does not include the steps of the deeper refactoring. The last part will come in later pr. **How** - The payment plugin is now capable to handle both the deprecated and new API and the plugin works the same as it use to works. - The mutation made by the plugin have been moved into the core as well as the subscriber - The tests have been updated to reflect the changed - Remove all new methods introduced by the payment collections - Mutualise types - Update provider and payment collection services - cleanup around all those refactoring including cleanup of the payment collection - refactor stripe payment plugin FIXES CORE-887
This commit is contained in:
1 parent
8dcc805ccf
commit
c8724da503
87 files changed
+1138
-1429
No files matched your search
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"medusa-payment-stripe": patch
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat(medusa,medusa-payment-stripe): Move database mutation from plugin to core
|
||||||
@@ -8,8 +8,6 @@ packages/*
|
|||||||
# List of packages to Lint
|
# List of packages to Lint
|
||||||
!packages/medusa
|
!packages/medusa
|
||||||
|
|
||||||
integration-tests/*
|
|
||||||
#!integration-tests/api
|
|
||||||
|
|
||||||
|
|
||||||
**/models/*
|
**/models/*
|
||||||
@@ -18,6 +16,5 @@ integration-tests/*
|
|||||||
**/node_modules/*
|
**/node_modules/*
|
||||||
**/migrations/*
|
**/migrations/*
|
||||||
**/__mocks__/*
|
**/__mocks__/*
|
||||||
**/__tests__/*
|
|
||||||
|
|
||||||
.eslintrc.js
|
.eslintrc.js
|
||||||
@@ -149,37 +149,6 @@ Object {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`/admin/price-lists POST /admin/price-lists/:id updates price list prices (inser a new MA for a specific region) 1`] = `
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"amount": 101,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"currency_code": "eur",
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": Any<String>,
|
|
||||||
"max_quantity": null,
|
|
||||||
"min_quantity": null,
|
|
||||||
"price_list_id": "pl_with_some_ma",
|
|
||||||
"region_id": "region-pl",
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"variant_id": "test-variant",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"amount": 1001,
|
|
||||||
"created_at": Any<String>,
|
|
||||||
"currency_code": "usd",
|
|
||||||
"deleted_at": null,
|
|
||||||
"id": "ma_test_4",
|
|
||||||
"max_quantity": null,
|
|
||||||
"min_quantity": null,
|
|
||||||
"price_list_id": "pl_with_some_ma",
|
|
||||||
"region_id": null,
|
|
||||||
"updated_at": Any<String>,
|
|
||||||
"variant_id": "test-variant",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`/admin/price-lists POST /admin/price-lists/:id updates the amount and currency of a price in the price list 1`] = `
|
exports[`/admin/price-lists POST /admin/price-lists/:id updates the amount and currency of a price in the price list 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"amount": 250,
|
"amount": 250,
|
||||||
|
|||||||
@@ -638,32 +638,34 @@ describe("/admin/price-lists", () => {
|
|||||||
expect(response.status).toEqual(200)
|
expect(response.status).toEqual(200)
|
||||||
|
|
||||||
expect(response.data.price_list.prices.length).toEqual(2)
|
expect(response.data.price_list.prices.length).toEqual(2)
|
||||||
expect(response.data.price_list.prices).toMatchSnapshot([
|
expect(response.data.price_list.prices).toEqual(
|
||||||
{
|
expect.arrayContaining([
|
||||||
id: expect.any(String),
|
expect.objectContaining({
|
||||||
currency_code: "eur",
|
id: expect.any(String),
|
||||||
amount: 101,
|
currency_code: "eur",
|
||||||
min_quantity: null,
|
amount: 101,
|
||||||
max_quantity: null,
|
min_quantity: null,
|
||||||
price_list_id: "pl_with_some_ma",
|
max_quantity: null,
|
||||||
variant_id: "test-variant",
|
price_list_id: "pl_with_some_ma",
|
||||||
region_id: "region-pl",
|
variant_id: "test-variant",
|
||||||
created_at: expect.any(String),
|
region_id: "region-pl",
|
||||||
updated_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
deleted_at: null,
|
updated_at: expect.any(String),
|
||||||
},
|
deleted_at: null,
|
||||||
{
|
}),
|
||||||
id: "ma_test_4",
|
expect.objectContaining({
|
||||||
currency_code: "usd",
|
id: "ma_test_4",
|
||||||
amount: 1001,
|
currency_code: "usd",
|
||||||
price_list_id: "pl_with_some_ma",
|
amount: 1001,
|
||||||
variant_id: "test-variant",
|
price_list_id: "pl_with_some_ma",
|
||||||
region_id: null,
|
variant_id: "test-variant",
|
||||||
created_at: expect.any(String),
|
region_id: null,
|
||||||
updated_at: expect.any(String),
|
created_at: expect.any(String),
|
||||||
deleted_at: null,
|
updated_at: expect.any(String),
|
||||||
},
|
deleted_at: null,
|
||||||
])
|
}),
|
||||||
|
])
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ export { parseCorsOrigins } from "./parse-cors-origins"
|
|||||||
export { transformIdableFields } from "./transform-idable-fields"
|
export { transformIdableFields } from "./transform-idable-fields"
|
||||||
export { default as Validator } from "./validator"
|
export { default as Validator } from "./validator"
|
||||||
export { default as zeroDecimalCurrencies } from "./zero-decimal-currencies"
|
export { default as zeroDecimalCurrencies } from "./zero-decimal-currencies"
|
||||||
|
export * from "./is-defined"
|
||||||
|
|
||||||
File renamed without changes.
@@ -29,9 +29,9 @@
|
|||||||
"medusa-test-utils": "^1.1.37"
|
"medusa-test-utils": "^1.1.37"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "babel src -d . --ignore **/__tests__",
|
"build": "babel src -d . --ignore **/__tests__ --ignore **/__mocks__",
|
||||||
"prepare": "cross-env NODE_ENV=production yarn run build",
|
"prepare": "cross-env NODE_ENV=production yarn run build",
|
||||||
"watch": "babel -w src --out-dir . --ignore **/__tests__",
|
"watch": "babel -w src --out-dir . --ignore **/__tests__ --ignore **/__mocks__",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ export const carts = {
|
|||||||
customer: IdMap.getId("not-lebron"),
|
customer: IdMap.getId("not-lebron"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
region: { currency_code: "usd" },
|
||||||
|
total: 100,
|
||||||
shipping_address: {},
|
shipping_address: {},
|
||||||
billing_address: {},
|
billing_address: {},
|
||||||
discounts: [],
|
discounts: [],
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export const StripeMock = {
|
|||||||
if (data.customer === "cus_123456789_new") {
|
if (data.customer === "cus_123456789_new") {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
id: "pi_lebron",
|
id: "pi_lebron",
|
||||||
amount: 100,
|
amount: data.amount,
|
||||||
customer: "cus_123456789_new",
|
customer: "cus_123456789_new",
|
||||||
description: data?.description,
|
description: data?.description,
|
||||||
})
|
})
|
||||||
@@ -28,7 +28,7 @@ export const StripeMock = {
|
|||||||
if (data.customer === "cus_lebron") {
|
if (data.customer === "cus_lebron") {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
id: "pi_lebron",
|
id: "pi_lebron",
|
||||||
amount: 100,
|
amount: data.amount,
|
||||||
customer: "cus_lebron",
|
customer: "cus_lebron",
|
||||||
description: data?.description,
|
description: data?.description,
|
||||||
})
|
})
|
||||||
|
|||||||
+89
-103
@@ -1,58 +1,13 @@
|
|||||||
import { IdMap } from "medusa-test-utils"
|
|
||||||
import StripeProviderService from "../stripe-provider"
|
|
||||||
import { CustomerServiceMock } from "../../__mocks__/customer"
|
|
||||||
import { carts } from "../../__mocks__/cart"
|
import { carts } from "../../__mocks__/cart"
|
||||||
import { TotalsServiceMock } from "../../__mocks__/totals"
|
import StripeBase from "../stripe-base";
|
||||||
|
|
||||||
const RegionServiceMock = {
|
const fakeContainer = {}
|
||||||
withTransaction: function () {
|
|
||||||
return this
|
|
||||||
},
|
|
||||||
retrieve: jest.fn().mockReturnValue(Promise.resolve({})),
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("StripeProviderService", () => {
|
|
||||||
describe("createCustomer", () => {
|
|
||||||
let result
|
|
||||||
beforeAll(async () => {
|
|
||||||
jest.clearAllMocks()
|
|
||||||
const stripeProviderService = new StripeProviderService(
|
|
||||||
{
|
|
||||||
customerService: CustomerServiceMock,
|
|
||||||
regionService: RegionServiceMock,
|
|
||||||
totalsService: TotalsServiceMock,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
api_key: "test",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await stripeProviderService.createCustomer({
|
|
||||||
_id: IdMap.getId("vvd"),
|
|
||||||
first_name: "Virgil",
|
|
||||||
last_name: "Van Dijk",
|
|
||||||
email: "virg@vvd.com",
|
|
||||||
password_hash: "1234",
|
|
||||||
metadata: {},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it("returns created stripe customer", () => {
|
|
||||||
expect(result).toEqual({
|
|
||||||
id: "cus_vvd",
|
|
||||||
email: "virg@vvd.com",
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
|
describe("StripeBase", () => {
|
||||||
describe("createPayment", () => {
|
describe("createPayment", () => {
|
||||||
let result
|
let result
|
||||||
const stripeProviderService = new StripeProviderService(
|
const stripeBase = new StripeBase(
|
||||||
{
|
fakeContainer,
|
||||||
customerService: CustomerServiceMock,
|
|
||||||
regionService: RegionServiceMock,
|
|
||||||
totalsService: TotalsServiceMock,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
api_key: "test"
|
api_key: "test"
|
||||||
}
|
}
|
||||||
@@ -63,45 +18,88 @@ describe("StripeProviderService", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("returns created stripe payment intent for cart with existing customer", async () => {
|
it("returns created stripe payment intent for cart with existing customer", async () => {
|
||||||
result = await stripeProviderService.createPayment(carts.frCart)
|
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({
|
expect(result).toEqual({
|
||||||
id: "pi_lebron",
|
session_data: {
|
||||||
customer: "cus_123456789_new",
|
id: "pi_lebron",
|
||||||
amount: 100,
|
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 () => {
|
it("returns created stripe payment intent for cart with no customer", async () => {
|
||||||
carts.frCart.customer_id = ""
|
const cart = carts.frCart
|
||||||
carts.frCart.context.payment_description = 'some description'
|
const context = {
|
||||||
result = await stripeProviderService.createPayment(carts.frCart)
|
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({
|
expect(result).toEqual({
|
||||||
id: "pi_lebron",
|
session_data: {
|
||||||
customer: "cus_lebron",
|
id: "pi_lebron",
|
||||||
amount: 100,
|
customer: "cus_lebron",
|
||||||
description: 'some description',
|
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 () => {
|
it("returns created stripe payment intent for cart with no customer and the options default description", async () => {
|
||||||
const localStripeProviderService = new StripeProviderService({
|
const localStripeProviderService = new StripeBase(
|
||||||
customerService: CustomerServiceMock,
|
fakeContainer,
|
||||||
regionService: RegionServiceMock,
|
|
||||||
totalsService: TotalsServiceMock,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
api_key: "test",
|
api_key: "test",
|
||||||
payment_description: "test options description"
|
payment_description: "test options description"
|
||||||
})
|
})
|
||||||
|
|
||||||
carts.frCart.customer_id = ""
|
const cart = carts.frCart
|
||||||
carts.frCart.context.payment_description = null
|
const context = {
|
||||||
result = await localStripeProviderService.createPayment(carts.frCart)
|
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({
|
expect(result).toEqual({
|
||||||
id: "pi_lebron",
|
session_data: {
|
||||||
customer: "cus_lebron",
|
id: "pi_lebron",
|
||||||
amount: 100,
|
customer: "cus_lebron",
|
||||||
description: "test options description",
|
description: "test options description",
|
||||||
|
amount: 100,
|
||||||
|
},
|
||||||
|
update_requests: {
|
||||||
|
customer_metadata: {
|
||||||
|
stripe_id: "cus_lebron"
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -110,18 +108,14 @@ describe("StripeProviderService", () => {
|
|||||||
let result
|
let result
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
const stripeProviderService = new StripeProviderService(
|
const stripeBase = new StripeBase(
|
||||||
{
|
fakeContainer,
|
||||||
customerService: CustomerServiceMock,
|
|
||||||
regionService: RegionServiceMock,
|
|
||||||
totalsService: TotalsServiceMock,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
api_key: "test",
|
api_key: "test",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
result = await stripeProviderService.retrievePayment({
|
result = await stripeBase.retrievePayment({
|
||||||
payment_method: {
|
payment_method: {
|
||||||
data: {
|
data: {
|
||||||
id: "pi_lebron",
|
id: "pi_lebron",
|
||||||
@@ -142,18 +136,14 @@ describe("StripeProviderService", () => {
|
|||||||
let result
|
let result
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
const stripeProviderService = new StripeProviderService(
|
const stripeBase = new StripeBase(
|
||||||
{
|
fakeContainer,
|
||||||
customerService: CustomerServiceMock,
|
|
||||||
regionService: RegionServiceMock,
|
|
||||||
totalsService: TotalsServiceMock,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
api_key: "test",
|
api_key: "test",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
result = await stripeProviderService.updatePayment(
|
result = await stripeBase.updatePayment(
|
||||||
{
|
{
|
||||||
id: "pi_lebron",
|
id: "pi_lebron",
|
||||||
amount: 800,
|
amount: 800,
|
||||||
@@ -177,18 +167,14 @@ describe("StripeProviderService", () => {
|
|||||||
let result
|
let result
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
const stripeProviderService = new StripeProviderService(
|
const stripeBase = new StripeBase(
|
||||||
{
|
fakeContainer,
|
||||||
customerService: CustomerServiceMock,
|
|
||||||
regionService: RegionServiceMock,
|
|
||||||
totalsService: TotalsServiceMock,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
api_key: "test",
|
api_key: "test",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
result = await stripeProviderService.updatePaymentIntentCustomer(
|
result = await stripeBase.updatePaymentIntentCustomer(
|
||||||
"pi_lebron",
|
"pi_lebron",
|
||||||
"cus_lebron_2"
|
"cus_lebron_2"
|
||||||
)
|
)
|
||||||
@@ -207,14 +193,14 @@ describe("StripeProviderService", () => {
|
|||||||
let result
|
let result
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
const stripeProviderService = new StripeProviderService(
|
const stripeBase = new StripeBase(
|
||||||
{},
|
fakeContainer,
|
||||||
{
|
{
|
||||||
api_key: "test",
|
api_key: "test",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
result = await stripeProviderService.capturePayment({
|
result = await stripeBase.capturePayment({
|
||||||
data: {
|
data: {
|
||||||
id: "pi_lebron",
|
id: "pi_lebron",
|
||||||
customer: "cus_lebron",
|
customer: "cus_lebron",
|
||||||
@@ -237,14 +223,14 @@ describe("StripeProviderService", () => {
|
|||||||
let result
|
let result
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
const stripeProviderService = new StripeProviderService(
|
const stripeBase = new StripeBase(
|
||||||
{},
|
fakeContainer,
|
||||||
{
|
{
|
||||||
api_key: "test",
|
api_key: "test",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
result = await stripeProviderService.refundPayment(
|
result = await stripeBase.refundPayment(
|
||||||
{
|
{
|
||||||
data: {
|
data: {
|
||||||
id: "re_123",
|
id: "re_123",
|
||||||
@@ -271,14 +257,14 @@ describe("StripeProviderService", () => {
|
|||||||
let result
|
let result
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
const stripeProviderService = new StripeProviderService(
|
const stripeBase = new StripeBase(
|
||||||
{},
|
fakeContainer,
|
||||||
{
|
{
|
||||||
api_key: "test",
|
api_key: "test",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
result = await stripeProviderService.cancelPayment({
|
result = await stripeBase.cancelPayment({
|
||||||
data: {
|
data: {
|
||||||
id: "pi_lebron",
|
id: "pi_lebron",
|
||||||
customer: "cus_lebron",
|
customer: "cus_lebron",
|
||||||
@@ -1,29 +1,12 @@
|
|||||||
import { AbstractPaymentService, PaymentSessionData } from "@medusajs/medusa"
|
import { AbstractPaymentService } from "@medusajs/medusa"
|
||||||
import Stripe from "stripe"
|
import Stripe from "stripe"
|
||||||
|
import { PaymentSessionStatus } from "@medusajs/medusa/dist";
|
||||||
|
|
||||||
class StripeBase extends AbstractPaymentService {
|
class StripeBase extends AbstractPaymentService {
|
||||||
static identifier = null
|
static identifier = null
|
||||||
|
|
||||||
constructor(
|
constructor(_, options) {
|
||||||
{
|
super(_, options)
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
{
|
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required Stripe options:
|
* Required Stripe options:
|
||||||
@@ -38,21 +21,6 @@ class StripeBase extends AbstractPaymentService {
|
|||||||
|
|
||||||
/** @private @const {Stripe} */
|
/** @private @const {Stripe} */
|
||||||
this.stripe_ = Stripe(options.api_key)
|
this.stripe_ = Stripe(options.api_key)
|
||||||
|
|
||||||
/** @private @const {CustomerService} */
|
|
||||||
this.stripeProviderService_ = stripeProviderService
|
|
||||||
|
|
||||||
/** @private @const {CustomerService} */
|
|
||||||
this.customerService_ = customerService
|
|
||||||
|
|
||||||
/** @private @const {RegionService} */
|
|
||||||
this.regionService_ = regionService
|
|
||||||
|
|
||||||
/** @private @const {TotalsService} */
|
|
||||||
this.totalsService_ = totalsService
|
|
||||||
|
|
||||||
/** @private @const {EntityManager} */
|
|
||||||
this.manager_ = manager
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getPaymentIntentOptions() {
|
getPaymentIntentOptions() {
|
||||||
@@ -74,22 +42,48 @@ class StripeBase extends AbstractPaymentService {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches Stripe payment intent. Check its status and returns the
|
* Get payment session status
|
||||||
* corresponding Medusa status.
|
* statuses.
|
||||||
* @param {PaymentSessionData} paymentSessionData - payment method data from cart
|
* @param {PaymentSessionData} paymentData - the data stored with the payment session
|
||||||
* @return {Promise<PaymentSessionStatus>} the status of the payment intent
|
* @return {Promise<PaymentSessionStatus>} the status of the order
|
||||||
*/
|
*/
|
||||||
async getStatus(paymentSessionData) {
|
async getStatus(paymentData) {
|
||||||
return await this.stripeProviderService_.getStatus(paymentSessionData)
|
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.
|
* Fetches a customers saved payment methods if registered in Stripe.
|
||||||
* @param {object} customer - customer to fetch saved cards for
|
* @param {Customer} customer - customer to fetch saved cards for
|
||||||
* @return {Promise<Data[]>} saved payments methods
|
* @return {Promise<Data[]>} saved payments methods
|
||||||
*/
|
*/
|
||||||
async retrieveSavedMethods(customer) {
|
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 []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,49 +93,68 @@ class StripeBase extends AbstractPaymentService {
|
|||||||
* @return {Promise<object>} Stripe customer
|
* @return {Promise<object>} Stripe customer
|
||||||
*/
|
*/
|
||||||
async retrieveCustomer(customerId) {
|
async retrieveCustomer(customerId) {
|
||||||
return await this.stripeProviderService_.retrieveCustomer(customerId)
|
if (!customerId) {
|
||||||
}
|
return
|
||||||
|
}
|
||||||
/**
|
return await this.stripe_.customers.retrieve(customerId)
|
||||||
* Creates a Stripe customer using a Medusa customer.
|
|
||||||
* @param {object} customer - Customer data from Medusa
|
|
||||||
* @return {Promise<object>} Stripe customer
|
|
||||||
*/
|
|
||||||
async createCustomer(customer) {
|
|
||||||
return await this.stripeProviderService_
|
|
||||||
.withTransaction(this.manager_)
|
|
||||||
.createCustomer(customer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Stripe payment intent.
|
* Creates a Stripe payment intent.
|
||||||
* If customer is not registered in Stripe, we do so.
|
* If customer is not registered in Stripe, we do so.
|
||||||
* @param {Cart} cart - cart to create a payment for
|
* @param {Cart & PaymentContext} context - context to use to create a payment for
|
||||||
* @return {Promise<PaymentSessionData>} Stripe payment intent
|
* @return {Promise<PaymentSessionResponse>} Stripe payment intent
|
||||||
*/
|
*/
|
||||||
async createPayment(cart) {
|
async createPayment(context) {
|
||||||
const intentRequestData = this.getPaymentIntentOptions()
|
const intentRequestData = this.getPaymentIntentOptions()
|
||||||
|
const { id: cart_id, email, context: cart_context, currency_code, amount, resource_id, customer } = context
|
||||||
|
|
||||||
return await this.stripeProviderService_
|
const intentRequest = {
|
||||||
.withTransaction(this.manager_)
|
description:
|
||||||
.createPayment(cart, intentRequestData)
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
async createPaymentNew(paymentInput) {
|
if (this.options_?.automatic_payment_methods) {
|
||||||
const intentRequestData = this.getPaymentIntentOptions()
|
intentRequest.automatic_payment_methods = { enabled: true }
|
||||||
|
}
|
||||||
|
|
||||||
return await this.stripeProviderService_
|
if (customer?.metadata?.stripe_id) {
|
||||||
.withTransaction(this.manager_)
|
intentRequest.customer = customer?.metadata?.stripe_id
|
||||||
.createPaymentNew(paymentInput, intentRequestData)
|
} 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: intentRequest.customer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves Stripe payment intent.
|
* Retrieves Stripe payment intent.
|
||||||
* @param {PaymentData} paymentData - the data of the payment to retrieve
|
* @param {PaymentData} data - the data of the payment to retrieve
|
||||||
* @return {Promise<Data>} Stripe payment intent
|
* @return {Promise<Data>} Stripe payment intent
|
||||||
*/
|
*/
|
||||||
async retrievePayment(paymentData) {
|
async retrievePayment(data) {
|
||||||
return await this.stripeProviderService_.retrievePayment(paymentData)
|
return await this.stripe_.paymentIntents.retrieve(data.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -150,67 +163,73 @@ class StripeBase extends AbstractPaymentService {
|
|||||||
* @return {Promise<PaymentData>} Stripe payment intent
|
* @return {Promise<PaymentData>} Stripe payment intent
|
||||||
*/
|
*/
|
||||||
async getPaymentData(paymentSession) {
|
async getPaymentData(paymentSession) {
|
||||||
return await this.stripeProviderService_.getPaymentData(paymentSession)
|
return await this.stripe_.paymentIntents.retrieve(paymentSession.data.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authorizes Stripe payment intent by simply returning
|
* Authorizes Stripe payment intent by simply returning
|
||||||
* the status for the payment intent in use.
|
* the status for the payment intent in use.
|
||||||
* @param {PaymentSession} paymentSession - payment session data
|
* @param {PaymentSession} paymentSession - payment session data
|
||||||
* @param {object} context - properties relevant to current context
|
* @param {Data} context - properties relevant to current context
|
||||||
* @return {Promise<{data: PaymentSessionData; status: PaymentSessionStatus}>} result with data and status
|
* @return {Promise<{ data: PaymentSessionData; status: PaymentSessionStatus }>} result with data and status
|
||||||
*/
|
*/
|
||||||
async authorizePayment(paymentSession, context = {}) {
|
async authorizePayment(paymentSession, context = {}) {
|
||||||
return await this.stripeProviderService_.authorizePayment(
|
const stat = await this.getStatus(paymentSession.data)
|
||||||
paymentSession,
|
return { data: paymentSession.data, status: stat }
|
||||||
context
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async updatePaymentData(paymentSessionData, data) {
|
async updatePaymentData(sessionData, update) {
|
||||||
return await this.stripeProviderService_.updatePaymentData(
|
return await this.stripe_.paymentIntents.update(sessionData.id, {
|
||||||
paymentSessionData,
|
...update.data,
|
||||||
data
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates Stripe payment intent.
|
* Updates Stripe payment intent.
|
||||||
* @param {PaymentSessionData} paymentSessionData - payment session data.
|
* @param {PaymentSessionData} paymentSessionData - payment session data.
|
||||||
* @param {Cart} cart
|
* @param {Cart & PaymentContext} context
|
||||||
* @return {Promise<PaymentSessionData>} Stripe payment intent
|
* @return {Promise<PaymentSessionData>} Stripe payment intent
|
||||||
*/
|
*/
|
||||||
async updatePayment(paymentSessionData, cart) {
|
async updatePayment(paymentSessionData, context) {
|
||||||
const intentRequestData = this.getPaymentIntentOptions()
|
const { amount, customer } = context
|
||||||
|
const stripeId = customer?.metadata?.stripe_id || undefined
|
||||||
|
|
||||||
return await this.stripeProviderService_
|
if (stripeId !== paymentSessionData.customer) {
|
||||||
.withTransaction(this.manager_)
|
return await this.createPayment(context)
|
||||||
.updatePayment(paymentSessionData, cart, intentRequestData)
|
} else {
|
||||||
|
if (
|
||||||
|
amount &&
|
||||||
|
paymentSessionData.amount === Math.round(amount)
|
||||||
|
) {
|
||||||
|
return paymentSessionData
|
||||||
|
}
|
||||||
|
|
||||||
|
return await this.stripe_.paymentIntents.update(paymentSessionData.id, {
|
||||||
|
amount: Math.round(amount),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updatePaymentNew(paymentSessionData, paymentInput) {
|
async deletePayment(payment) {
|
||||||
const intentRequestData = this.getPaymentIntentOptions()
|
const { id } = payment.data
|
||||||
|
return this.stripe_.paymentIntents.cancel(id).catch((err) => {
|
||||||
return await this.stripeProviderService_
|
if (err.statusCode === 400) {
|
||||||
.withTransaction(this.manager_)
|
return
|
||||||
.updatePaymentNew(paymentSessionData, paymentInput, intentRequestData)
|
}
|
||||||
}
|
throw err
|
||||||
|
})
|
||||||
async deletePayment(paymentSession) {
|
|
||||||
return await this.stripeProviderService_.deletePayment(paymentSession)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates customer of Stripe payment intent.
|
* Updates customer of Stripe payment intent.
|
||||||
* @param {string} paymentIntentId - id of payment intent to update
|
* @param {string} paymentIntentId - id of payment intent to update
|
||||||
* @param {string} customerId - id of new Stripe customer
|
* @param {string} customerId - id of \ Stripe customer
|
||||||
* @return {object} Stripe payment intent
|
* @return {object} Stripe payment intent
|
||||||
*/
|
*/
|
||||||
async updatePaymentIntentCustomer(paymentIntentId, customerId) {
|
async updatePaymentIntentCustomer(paymentIntentId, customerId) {
|
||||||
return await this.stripeProviderService_.updatePaymentIntentCustomer(
|
return await this.stripe_.paymentIntents.update(paymentIntentId, {
|
||||||
paymentIntentId,
|
customer: customerId,
|
||||||
customerId
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,7 +238,18 @@ class StripeBase extends AbstractPaymentService {
|
|||||||
* @return {Promise<PaymentData>} Stripe payment intent
|
* @return {Promise<PaymentData>} Stripe payment intent
|
||||||
*/
|
*/
|
||||||
async capturePayment(payment) {
|
async capturePayment(payment) {
|
||||||
return await this.stripeProviderService_.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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -228,11 +258,14 @@ class StripeBase extends AbstractPaymentService {
|
|||||||
* @param {number} refundAmount - amount to refund
|
* @param {number} refundAmount - amount to refund
|
||||||
* @return {Promise<PaymentData>} refunded payment intent
|
* @return {Promise<PaymentData>} refunded payment intent
|
||||||
*/
|
*/
|
||||||
async refundPayment(payment, refundAmount) {
|
async refundPayment(payment, amountToRefund) {
|
||||||
return await this.stripeProviderService_.refundPayment(
|
const { id } = payment.data
|
||||||
payment,
|
await this.stripe_.refunds.create({
|
||||||
refundAmount
|
amount: Math.round(amountToRefund),
|
||||||
)
|
payment_intent: id,
|
||||||
|
})
|
||||||
|
|
||||||
|
return payment.data
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -241,7 +274,31 @@ class StripeBase extends AbstractPaymentService {
|
|||||||
* @return {Promise<PaymentData>} canceled payment intent
|
* @return {Promise<PaymentData>} canceled payment intent
|
||||||
*/
|
*/
|
||||||
async cancelPayment(payment) {
|
async cancelPayment(payment) {
|
||||||
return await this.stripeProviderService_.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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
import { IdMap } from "medusa-test-utils"
|
|
||||||
|
|
||||||
export const StripeProviderServiceMock = {
|
|
||||||
withTransaction: function () {
|
|
||||||
return this
|
|
||||||
},
|
|
||||||
retrievePayment: jest.fn().mockImplementation((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((cart) => {
|
|
||||||
return Promise.resolve()
|
|
||||||
}),
|
|
||||||
updatePaymentIntentCustomer: jest.fn().mockImplementation((cart) => {
|
|
||||||
return Promise.resolve()
|
|
||||||
}),
|
|
||||||
retrieveCustomer: jest.fn().mockImplementation((customerId) => {
|
|
||||||
if (customerId === "cus_123456789_new") {
|
|
||||||
return Promise.resolve({
|
|
||||||
id: "cus_123456789_new",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return Promise.resolve(undefined)
|
|
||||||
}),
|
|
||||||
createCustomer: jest.fn().mockImplementation((customer) => {
|
|
||||||
if (customer._id === IdMap.getId("vvd")) {
|
|
||||||
return Promise.resolve({
|
|
||||||
id: "cus_123456789_new_vvd",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return Promise.resolve(undefined)
|
|
||||||
}),
|
|
||||||
createPayment: jest.fn().mockImplementation((cart) => {
|
|
||||||
return Promise.resolve({
|
|
||||||
id: "pi_new",
|
|
||||||
customer: "cus_123456789_new",
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
|
|
||||||
const mock = jest.fn().mockImplementation(() => {
|
|
||||||
return StripeProviderServiceMock
|
|
||||||
})
|
|
||||||
|
|
||||||
export default mock
|
|
||||||
@@ -3,26 +3,8 @@ import StripeBase from "../helpers/stripe-base"
|
|||||||
class BancontactProviderService extends StripeBase {
|
class BancontactProviderService extends StripeBase {
|
||||||
static identifier = "stripe-bancontact"
|
static identifier = "stripe-bancontact"
|
||||||
|
|
||||||
constructor(
|
constructor(_, options) {
|
||||||
{
|
super(_, options)
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
{
|
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get paymentIntentOptions() {
|
get paymentIntentOptions() {
|
||||||
|
|||||||
@@ -3,26 +3,8 @@ import StripeBase from "../helpers/stripe-base"
|
|||||||
class BlikProviderService extends StripeBase {
|
class BlikProviderService extends StripeBase {
|
||||||
static identifier = "stripe-blik"
|
static identifier = "stripe-blik"
|
||||||
|
|
||||||
constructor(
|
constructor(_, options) {
|
||||||
{
|
super(_, options)
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
{
|
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get paymentIntentOptions() {
|
get paymentIntentOptions() {
|
||||||
|
|||||||
@@ -3,26 +3,8 @@ import StripeBase from "../helpers/stripe-base"
|
|||||||
class GiropayProviderService extends StripeBase {
|
class GiropayProviderService extends StripeBase {
|
||||||
static identifier = "stripe-giropay"
|
static identifier = "stripe-giropay"
|
||||||
|
|
||||||
constructor(
|
constructor(_, options) {
|
||||||
{
|
super(_, options)
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
{
|
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get paymentIntentOptions() {
|
get paymentIntentOptions() {
|
||||||
|
|||||||
@@ -3,26 +3,8 @@ import StripeBase from "../helpers/stripe-base"
|
|||||||
class IdealProviderService extends StripeBase {
|
class IdealProviderService extends StripeBase {
|
||||||
static identifier = "stripe-ideal"
|
static identifier = "stripe-ideal"
|
||||||
|
|
||||||
constructor(
|
constructor(_, options) {
|
||||||
{
|
super(_, options)
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
{
|
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get paymentIntentOptions() {
|
get paymentIntentOptions() {
|
||||||
|
|||||||
@@ -1,424 +1,14 @@
|
|||||||
import {
|
import StripeBase from "../helpers/stripe-base";
|
||||||
AbstractPaymentService,
|
|
||||||
PaymentSessionData,
|
|
||||||
PaymentSessionStatus,
|
|
||||||
} from "@medusajs/medusa"
|
|
||||||
import Stripe from "stripe"
|
|
||||||
|
|
||||||
class StripeProviderService extends AbstractPaymentService {
|
class StripeProviderService extends StripeBase {
|
||||||
static identifier = "stripe"
|
static identifier = "stripe"
|
||||||
|
|
||||||
constructor(
|
constructor(_, options) {
|
||||||
{ customerService, totalsService, regionService, manager },
|
super(_, options)
|
||||||
options
|
|
||||||
) {
|
|
||||||
super({ customerService, totalsService, regionService, manager }, 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)
|
|
||||||
|
|
||||||
/** @private @const {CustomerService} */
|
|
||||||
this.customerService_ = customerService
|
|
||||||
|
|
||||||
/** @private @const {RegionService} */
|
|
||||||
this.regionService_ = regionService
|
|
||||||
|
|
||||||
/** @private @const {TotalsService} */
|
|
||||||
this.totalsService_ = totalsService
|
|
||||||
|
|
||||||
/** @private @const {EntityManager} */
|
|
||||||
this.manager_ = manager
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
get paymentIntentOptions() {
|
||||||
* Get payment session status
|
return {}
|
||||||
* statuses.
|
|
||||||
* @param {PaymentSessionData} paymentData - the data stored with the payment session
|
|
||||||
* @return {Promise<PaymentSessionStatus>} 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<Data[]>} 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<object>} Stripe customer
|
|
||||||
*/
|
|
||||||
async retrieveCustomer(customerId) {
|
|
||||||
if (!customerId) {
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
return this.stripe_.customers.retrieve(customerId)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Stripe customer using a Medusa customer.
|
|
||||||
* @param {object} customer - Customer data from Medusa
|
|
||||||
* @return {Promise<object>} Stripe customer
|
|
||||||
*/
|
|
||||||
async createCustomer(customer) {
|
|
||||||
try {
|
|
||||||
const stripeCustomer = await this.stripe_.customers.create({
|
|
||||||
email: customer.email,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (customer.id) {
|
|
||||||
await this.customerService_
|
|
||||||
.withTransaction(this.manager_)
|
|
||||||
.update(customer.id, {
|
|
||||||
metadata: { stripe_id: stripeCustomer.id },
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return stripeCustomer
|
|
||||||
} catch (error) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Stripe payment intent.
|
|
||||||
* If customer is not registered in Stripe, we do so.
|
|
||||||
* @param {Cart} cart - cart to create a payment for
|
|
||||||
* @param intentRequestData
|
|
||||||
* @return {Promise<PaymentSessionData>} Stripe payment intent
|
|
||||||
*/
|
|
||||||
async createPayment(cart, intentRequestData = {}) {
|
|
||||||
const { customer_id, region_id, email } = cart
|
|
||||||
const { currency_code } = await this.regionService_
|
|
||||||
.withTransaction(this.manager_)
|
|
||||||
.retrieve(region_id)
|
|
||||||
|
|
||||||
const amount = cart.total
|
|
||||||
|
|
||||||
const intentRequest = {
|
|
||||||
description:
|
|
||||||
cart?.context?.payment_description ??
|
|
||||||
this.options_?.payment_description,
|
|
||||||
amount: Math.round(amount),
|
|
||||||
currency: currency_code,
|
|
||||||
metadata: { cart_id: `${cart.id}` },
|
|
||||||
capture_method: this.options_.capture ? "automatic" : "manual",
|
|
||||||
...intentRequestData,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options_?.automatic_payment_methods) {
|
|
||||||
intentRequest.automatic_payment_methods = { enabled: true }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (customer_id) {
|
|
||||||
const customer = await this.customerService_
|
|
||||||
.withTransaction(this.manager_)
|
|
||||||
.retrieve(customer_id)
|
|
||||||
|
|
||||||
if (customer.metadata?.stripe_id) {
|
|
||||||
intentRequest.customer = customer.metadata.stripe_id
|
|
||||||
} else {
|
|
||||||
const stripeCustomer = await this.createCustomer({
|
|
||||||
email,
|
|
||||||
id: customer_id,
|
|
||||||
})
|
|
||||||
|
|
||||||
intentRequest.customer = stripeCustomer.id
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const stripeCustomer = await this.createCustomer({
|
|
||||||
email,
|
|
||||||
})
|
|
||||||
|
|
||||||
intentRequest.customer = stripeCustomer.id
|
|
||||||
}
|
|
||||||
|
|
||||||
return await this.stripe_.paymentIntents.create(intentRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
async createPaymentNew(paymentInput, intentRequestData = {}) {
|
|
||||||
const { customer, currency_code, amount, resource_id, cart } = paymentInput
|
|
||||||
const { id: customer_id, email } = customer ?? {}
|
|
||||||
|
|
||||||
const intentRequest = {
|
|
||||||
description:
|
|
||||||
cart?.context?.payment_description ??
|
|
||||||
this.options_?.payment_description,
|
|
||||||
amount: Math.round(amount),
|
|
||||||
currency: currency_code,
|
|
||||||
metadata: { resource_id },
|
|
||||||
capture_method: this.options_.capture ? "automatic" : "manual",
|
|
||||||
...intentRequestData,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (customer_id) {
|
|
||||||
if (customer.metadata?.stripe_id) {
|
|
||||||
intentRequest.customer = customer.metadata.stripe_id
|
|
||||||
} else {
|
|
||||||
const stripeCustomer = await this.createCustomer({
|
|
||||||
email,
|
|
||||||
id: customer_id,
|
|
||||||
})
|
|
||||||
|
|
||||||
intentRequest.customer = stripeCustomer.id
|
|
||||||
}
|
|
||||||
} else if (email) {
|
|
||||||
const stripeCustomer = await this.createCustomer({
|
|
||||||
email,
|
|
||||||
})
|
|
||||||
|
|
||||||
intentRequest.customer = stripeCustomer.id
|
|
||||||
}
|
|
||||||
|
|
||||||
return await this.stripe_.paymentIntents.create(intentRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves Stripe payment intent.
|
|
||||||
* @param {PaymentData} paymentData - the data of the payment to retrieve
|
|
||||||
* @return {Promise<Data>} Stripe payment intent
|
|
||||||
*/
|
|
||||||
async retrievePayment(data) {
|
|
||||||
try {
|
|
||||||
return await this.stripe_.paymentIntents.retrieve(data.id)
|
|
||||||
} catch (error) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a Stripe payment intent and returns it.
|
|
||||||
* @param {PaymentSession} paymentSession - the data of the payment to retrieve
|
|
||||||
* @return {Promise<PaymentData>} Stripe payment intent
|
|
||||||
*/
|
|
||||||
async getPaymentData(paymentSession) {
|
|
||||||
try {
|
|
||||||
return await this.stripe_.paymentIntents.retrieve(paymentSession.data.id)
|
|
||||||
} catch (error) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
try {
|
|
||||||
return { data: paymentSession.data, status: stat }
|
|
||||||
} catch (error) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async updatePaymentData(sessionData, update) {
|
|
||||||
try {
|
|
||||||
return await this.stripe_.paymentIntents.update(sessionData.id, {
|
|
||||||
...update.data,
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates Stripe payment intent.
|
|
||||||
* @param {PaymentSessionData} paymentSessionData - payment session data.
|
|
||||||
* @param {Cart} cart
|
|
||||||
* @param intentRequestData
|
|
||||||
* @return {Promise<PaymentSessionData>} Stripe payment intent
|
|
||||||
*/
|
|
||||||
async updatePayment(paymentSessionData, cart, intentRequestData) {
|
|
||||||
try {
|
|
||||||
const stripeId = cart.customer?.metadata?.stripe_id || undefined
|
|
||||||
|
|
||||||
if (stripeId !== paymentSessionData.customer) {
|
|
||||||
return await this.createPayment(cart, intentRequestData)
|
|
||||||
} else {
|
|
||||||
if (
|
|
||||||
cart.total &&
|
|
||||||
paymentSessionData.amount === Math.round(cart.total)
|
|
||||||
) {
|
|
||||||
return paymentSessionData
|
|
||||||
}
|
|
||||||
|
|
||||||
return await this.stripe_.paymentIntents.update(paymentSessionData.id, {
|
|
||||||
amount: Math.round(cart.total),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async updatePaymentNew(paymentSessionData, paymentInput, intentRequestData) {
|
|
||||||
try {
|
|
||||||
const stripeId = paymentInput.customer?.metadata?.stripe_id
|
|
||||||
|
|
||||||
if (stripeId !== paymentSessionData.customer) {
|
|
||||||
return await this.createPaymentNew(paymentInput, intentRequestData)
|
|
||||||
} else {
|
|
||||||
if (paymentSessionData.amount === Math.round(paymentInput.amount)) {
|
|
||||||
return paymentSessionData
|
|
||||||
}
|
|
||||||
|
|
||||||
return await this.stripe_.paymentIntents.update(paymentSessionData.id, {
|
|
||||||
amount: Math.round(paymentInput.amount),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async deletePayment(payment) {
|
|
||||||
try {
|
|
||||||
const { id } = payment.data
|
|
||||||
return this.stripe_.paymentIntents.cancel(id).catch((err) => {
|
|
||||||
if (err.statusCode === 400) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
throw err
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates customer of Stripe payment intent.
|
|
||||||
* @param {string} paymentIntentId - id of payment intent to update
|
|
||||||
* @param {string} customerId - id of new Stripe customer
|
|
||||||
* @return {object} Stripe payment intent
|
|
||||||
*/
|
|
||||||
async updatePaymentIntentCustomer(paymentIntentId, customerId) {
|
|
||||||
try {
|
|
||||||
return await this.stripe_.paymentIntents.update(paymentIntentId, {
|
|
||||||
customer: customerId,
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Captures payment for Stripe payment intent.
|
|
||||||
* @param {Payment} payment - payment method data from cart
|
|
||||||
* @return {Promise<PaymentData>} 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<PaymentData>} refunded payment intent
|
|
||||||
*/
|
|
||||||
async refundPayment(payment, amountToRefund) {
|
|
||||||
const { id } = payment.data
|
|
||||||
try {
|
|
||||||
await this.stripe_.refunds.create({
|
|
||||||
amount: Math.round(amountToRefund),
|
|
||||||
payment_intent: id,
|
|
||||||
})
|
|
||||||
|
|
||||||
return payment.data
|
|
||||||
} catch (error) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancels payment for Stripe payment intent.
|
|
||||||
* @param {Payment} payment - payment method data from cart
|
|
||||||
* @return {Promise<PaymentData>} 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
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,26 +3,8 @@ import StripeBase from "../helpers/stripe-base"
|
|||||||
class Przelewy24ProviderService extends StripeBase {
|
class Przelewy24ProviderService extends StripeBase {
|
||||||
static identifier = "stripe-przelewy24"
|
static identifier = "stripe-przelewy24"
|
||||||
|
|
||||||
constructor(
|
constructor(_, options) {
|
||||||
{
|
super(_, options)
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
{
|
|
||||||
stripeProviderService,
|
|
||||||
customerService,
|
|
||||||
totalsService,
|
|
||||||
regionService,
|
|
||||||
manager,
|
|
||||||
},
|
|
||||||
options
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get paymentIntentOptions() {
|
get paymentIntentOptions() {
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
class CartSubscriber {
|
|
||||||
constructor({
|
|
||||||
manager,
|
|
||||||
cartService,
|
|
||||||
paymentProviderService,
|
|
||||||
eventBusService,
|
|
||||||
}) {
|
|
||||||
this.cartService_ = cartService
|
|
||||||
this.paymentProviderService_ = paymentProviderService
|
|
||||||
this.eventBus_ = eventBusService
|
|
||||||
this.manager_ = manager
|
|
||||||
|
|
||||||
this.eventBus_.subscribe("cart.customer_updated", async (cart) => {
|
|
||||||
await this.onCustomerUpdated(cart)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async onCustomerUpdated(cartId) {
|
|
||||||
await this.manager_.transaction(async (transactionManager) => {
|
|
||||||
const cart = await this.cartService_
|
|
||||||
.withTransaction(transactionManager)
|
|
||||||
.retrieve(cartId, {
|
|
||||||
select: [
|
|
||||||
"subtotal",
|
|
||||||
"tax_total",
|
|
||||||
"shipping_total",
|
|
||||||
"discount_total",
|
|
||||||
"gift_card_total",
|
|
||||||
"total",
|
|
||||||
],
|
|
||||||
relations: [
|
|
||||||
"billing_address",
|
|
||||||
"shipping_address",
|
|
||||||
"region",
|
|
||||||
"region.payment_providers",
|
|
||||||
"items",
|
|
||||||
"items.adjustments",
|
|
||||||
"payment_sessions",
|
|
||||||
"customer",
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!cart.payment_sessions?.length) {
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
|
|
||||||
const session = cart.payment_sessions.find(
|
|
||||||
(ps) => ps.provider_id === "stripe"
|
|
||||||
)
|
|
||||||
|
|
||||||
if (session) {
|
|
||||||
return await this.paymentProviderService_
|
|
||||||
.withTransaction(transactionManager)
|
|
||||||
.updateSession(session, cart)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default CartSubscriber
|
|
||||||
Executable → Regular
File mode changed.
@@ -6,7 +6,7 @@ import { DateComparisonOperator } from "../../../../types/common"
|
|||||||
import { IsType } from "../../../../utils/validators/is-type"
|
import { IsType } from "../../../../utils/validators/is-type"
|
||||||
import { Request } from "express"
|
import { Request } from "express"
|
||||||
import { pickBy } from "lodash"
|
import { pickBy } from "lodash"
|
||||||
import { isDefined } from "../../../../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [get] /batch-jobs
|
* @oas [get] /batch-jobs
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { GiftCardService } from "../../../../services"
|
|||||||
import { Type } from "class-transformer"
|
import { Type } from "class-transformer"
|
||||||
import { pickBy } from "lodash"
|
import { pickBy } from "lodash"
|
||||||
import { validator } from "../../../../utils/validator"
|
import { validator } from "../../../../utils/validator"
|
||||||
import { isDefined } from "../../../../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [get] /gift-cards
|
* @oas [get] /gift-cards
|
||||||
|
|||||||
@@ -14,11 +14,10 @@ import {
|
|||||||
} from "../../../../services"
|
} from "../../../../services"
|
||||||
|
|
||||||
import { Type } from "class-transformer"
|
import { Type } from "class-transformer"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { Order, Return } from "../../../../models"
|
import { Order, Return } from "../../../../models"
|
||||||
import { OrdersReturnItem } from "../../../../types/orders"
|
import { OrdersReturnItem } from "../../../../types/orders"
|
||||||
import { isDefined } from "../../../../utils"
|
|
||||||
import { validator } from "../../../../utils/validator"
|
import { validator } from "../../../../utils/validator"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { ProductStatus } from "../../../../models"
|
|||||||
import { Request } from "express"
|
import { Request } from "express"
|
||||||
import { Type } from "class-transformer"
|
import { Type } from "class-transformer"
|
||||||
import { pickBy } from "lodash"
|
import { pickBy } from "lodash"
|
||||||
import { isDefined } from "../../../../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [get] /price-lists/{id}/products
|
* @oas [get] /price-lists/{id}/products
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { OrderService, ReturnService, SwapService } from "../../../../services"
|
|||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { Type } from "class-transformer"
|
import { Type } from "class-transformer"
|
||||||
import { validator } from "../../../../utils/validator"
|
import { validator } from "../../../../utils/validator"
|
||||||
import { isDefined } from "../../../../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [post] /returns/{id}/receive
|
* @oas [post] /returns/{id}/receive
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ import { getRetrieveConfig, pickByConfig } from "./utils/get-query-config"
|
|||||||
|
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { IsType } from "../../../../utils/validators/is-type"
|
import { IsType } from "../../../../utils/validators/is-type"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { TaxRate } from "../../../.."
|
import { TaxRate } from "../../../.."
|
||||||
import { TaxRateService } from "../../../../services"
|
import { TaxRateService } from "../../../../services"
|
||||||
import { omit } from "lodash"
|
import { omit } from "lodash"
|
||||||
import { validator } from "../../../../utils/validator"
|
import { validator } from "../../../../utils/validator"
|
||||||
import { isDefined } from "../../../../utils"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [post] /tax-rates
|
* @oas [post] /tax-rates
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { TaxRate } from "../../../.."
|
|||||||
import { TaxRateService } from "../../../../services"
|
import { TaxRateService } from "../../../../services"
|
||||||
import { omit } from "lodash"
|
import { omit } from "lodash"
|
||||||
import { validator } from "../../../../utils/validator"
|
import { validator } from "../../../../utils/validator"
|
||||||
import { isDefined } from "../../../../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [post] /tax-rates/{id}
|
* @oas [post] /tax-rates/{id}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { pick } from "lodash"
|
|||||||
import { defaultAdminTaxRatesFields, defaultAdminTaxRatesRelations } from "../"
|
import { defaultAdminTaxRatesFields, defaultAdminTaxRatesRelations } from "../"
|
||||||
import { TaxRate } from "../../../../.."
|
import { TaxRate } from "../../../../.."
|
||||||
import { FindConfig } from "../../../../../types/common"
|
import { FindConfig } from "../../../../../types/common"
|
||||||
import { isDefined } from "../../../../../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
|
|
||||||
export function pickByConfig<T>(
|
export function pickByConfig<T>(
|
||||||
obj: T | T[],
|
obj: T | T[],
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import reqIp from "request-ip"
|
import reqIp from "request-ip"
|
||||||
import { Type } from "class-transformer"
|
import { Type } from "class-transformer"
|
||||||
import {
|
import {
|
||||||
@@ -22,7 +22,6 @@ import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators
|
|||||||
import { FlagRouter } from "../../../../utils/flag-router"
|
import { FlagRouter } from "../../../../utils/flag-router"
|
||||||
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
|
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
|
||||||
import { CartCreateProps } from "../../../../types/cart"
|
import { CartCreateProps } from "../../../../types/cart"
|
||||||
import { isDefined } from "../../../../utils"
|
|
||||||
import PublishableAPIKeysFeatureFlag from "../../../../loaders/feature-flags/publishable-api-keys"
|
import PublishableAPIKeysFeatureFlag from "../../../../loaders/feature-flags/publishable-api-keys"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -13,14 +13,13 @@ import {
|
|||||||
ProductService,
|
ProductService,
|
||||||
RegionService,
|
RegionService,
|
||||||
} from "../../../../services"
|
} from "../../../../services"
|
||||||
|
import { isDefined } from "medusa-core-utils"
|
||||||
import { defaultStoreProductsRelations } from "."
|
import { defaultStoreProductsRelations } from "."
|
||||||
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
|
import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-channels"
|
||||||
import { Product } from "../../../../models"
|
import { Product } from "../../../../models"
|
||||||
import PricingService from "../../../../services/pricing"
|
import PricingService from "../../../../services/pricing"
|
||||||
import { DateComparisonOperator } from "../../../../types/common"
|
import { DateComparisonOperator } from "../../../../types/common"
|
||||||
import { PriceSelectionParams } from "../../../../types/price-selection"
|
import { PriceSelectionParams } from "../../../../types/price-selection"
|
||||||
import { isDefined } from "../../../../utils"
|
|
||||||
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
|
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
|
||||||
import { validator } from "../../../../utils/validator"
|
import { validator } from "../../../../utils/validator"
|
||||||
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
|
import { optionalBooleanMapper } from "../../../../utils/validators/is-boolean"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { CustomerService } from "../../services"
|
|||||||
import { FindConfig } from "../../types/common"
|
import { FindConfig } from "../../types/common"
|
||||||
import { validator } from "../../utils/validator"
|
import { validator } from "../../utils/validator"
|
||||||
import { Customer } from "../../models/customer"
|
import { Customer } from "../../models/customer"
|
||||||
import { isDefined } from "../../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
|
|
||||||
const listAndCount = async (
|
const listAndCount = async (
|
||||||
scope,
|
scope,
|
||||||
|
|||||||
@@ -1,18 +1,38 @@
|
|||||||
import { TransactionBaseService } from "./transaction-base-service"
|
import { TransactionBaseService } from "./transaction-base-service"
|
||||||
import {
|
import {
|
||||||
|
Address,
|
||||||
Cart,
|
Cart,
|
||||||
Customer,
|
Customer,
|
||||||
Payment,
|
Payment,
|
||||||
PaymentSession,
|
PaymentSession,
|
||||||
PaymentSessionStatus,
|
PaymentSessionStatus,
|
||||||
|
ShippingMethod,
|
||||||
} from "../models"
|
} from "../models"
|
||||||
import { PaymentService } from "medusa-interfaces"
|
import { PaymentService } from "medusa-interfaces"
|
||||||
import { PaymentProviderDataInput } from "../types/payment-collection"
|
|
||||||
|
|
||||||
export type Data = Record<string, unknown>
|
export type Data = Record<string, unknown>
|
||||||
export type PaymentData = Data
|
export type PaymentData = Data
|
||||||
export type PaymentSessionData = Data
|
export type PaymentSessionData = Data
|
||||||
|
|
||||||
|
export type PaymentContext = {
|
||||||
|
cart: {
|
||||||
|
context: Record<string, unknown>
|
||||||
|
id: string
|
||||||
|
email: string
|
||||||
|
shipping_address: Address | null
|
||||||
|
shipping_methods: ShippingMethod[]
|
||||||
|
}
|
||||||
|
currency_code: string
|
||||||
|
amount: number
|
||||||
|
resource_id?: string
|
||||||
|
customer?: Customer
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PaymentSessionResponse = {
|
||||||
|
update_requests: { customer_metadata: Record<string, unknown> }
|
||||||
|
session_data: Record<string, unknown>
|
||||||
|
}
|
||||||
|
|
||||||
export interface PaymentService extends TransactionBaseService {
|
export interface PaymentService extends TransactionBaseService {
|
||||||
getIdentifier(): string
|
getIdentifier(): string
|
||||||
|
|
||||||
@@ -23,6 +43,16 @@ export interface PaymentService extends TransactionBaseService {
|
|||||||
data: Data
|
data: Data
|
||||||
): Promise<PaymentSessionData>
|
): Promise<PaymentSessionData>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context The type of this argument is meant to be temporary and once the previous method signature
|
||||||
|
* will be removed, the type will only be PaymentContext instead of Cart & PaymentContext
|
||||||
|
*/
|
||||||
|
createPayment(context: Cart & PaymentContext): Promise<PaymentSessionResponse>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use createPayment(context: Cart & PaymentContext): Promise<PaymentSessionResponse> instead
|
||||||
|
* @param cart
|
||||||
|
*/
|
||||||
createPayment(cart: Cart): Promise<PaymentSessionData>
|
createPayment(cart: Cart): Promise<PaymentSessionData>
|
||||||
|
|
||||||
retrievePayment(paymentData: PaymentData): Promise<Data>
|
retrievePayment(paymentData: PaymentData): Promise<Data>
|
||||||
@@ -76,23 +106,42 @@ export abstract class AbstractPaymentService
|
|||||||
data: Data
|
data: Data
|
||||||
): Promise<PaymentSessionData>
|
): Promise<PaymentSessionData>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context The type of this argument is meant to be temporary and once the previous method signature
|
||||||
|
* will be removed, the type will only be PaymentContext instead of Cart & PaymentContext
|
||||||
|
*/
|
||||||
|
public abstract createPayment(
|
||||||
|
context: Cart & PaymentContext
|
||||||
|
): Promise<PaymentSessionResponse>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use createPayment(context: Cart & PaymentContext): Promise<PaymentSessionResponse> instead
|
||||||
|
* @param cart
|
||||||
|
*/
|
||||||
public abstract createPayment(cart: Cart): Promise<PaymentSessionData>
|
public abstract createPayment(cart: Cart): Promise<PaymentSessionData>
|
||||||
public abstract createPaymentNew(
|
|
||||||
paymentInput: PaymentProviderDataInput
|
|
||||||
): Promise<PaymentSessionData>
|
|
||||||
|
|
||||||
public abstract retrievePayment(paymentData: PaymentData): Promise<Data>
|
public abstract retrievePayment(paymentData: PaymentData): Promise<Data>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param paymentSessionData
|
||||||
|
* @param context The type of this argument is meant to be temporary and once the previous method signature
|
||||||
|
* will be removed, the type will only be PaymentContext instead of Cart & PaymentContext
|
||||||
|
*/
|
||||||
|
public abstract updatePayment(
|
||||||
|
paymentSessionData: PaymentSessionData,
|
||||||
|
context: Cart & PaymentContext
|
||||||
|
): Promise<PaymentSessionResponse>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use updatePayment(paymentSessionData: PaymentSessionData, context: Cart & PaymentContext): Promise<PaymentSessionResponse> instead
|
||||||
|
* @param paymentSessionData
|
||||||
|
* @param cart
|
||||||
|
*/
|
||||||
public abstract updatePayment(
|
public abstract updatePayment(
|
||||||
paymentSessionData: PaymentSessionData,
|
paymentSessionData: PaymentSessionData,
|
||||||
cart: Cart
|
cart: Cart
|
||||||
): Promise<PaymentSessionData>
|
): Promise<PaymentSessionData>
|
||||||
|
|
||||||
public abstract updatePaymentNew(
|
|
||||||
paymentSessionData: PaymentSessionData,
|
|
||||||
paymentInput: PaymentProviderDataInput
|
|
||||||
): Promise<PaymentSessionData>
|
|
||||||
|
|
||||||
public abstract authorizePayment(
|
public abstract authorizePayment(
|
||||||
paymentSession: PaymentSession,
|
paymentSession: PaymentSession,
|
||||||
context: Data
|
context: Data
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import path from "path"
|
|||||||
import { trackFeatureFlag } from "medusa-telemetry"
|
import { trackFeatureFlag } from "medusa-telemetry"
|
||||||
import { FlagSettings } from "../../types/feature-flags"
|
import { FlagSettings } from "../../types/feature-flags"
|
||||||
import { Logger } from "../../types/global"
|
import { Logger } from "../../types/global"
|
||||||
import { isDefined } from "../../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
import { FlagRouter } from "../../utils/flag-router"
|
import { FlagRouter } from "../../utils/flag-router"
|
||||||
|
|
||||||
const isTruthy = (val: string | boolean | undefined): boolean => {
|
const isTruthy = (val: string | boolean | undefined): boolean => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { asFunction } from "awilix"
|
|||||||
import glob from "glob"
|
import glob from "glob"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { ConfigModule, MedusaContainer } from "../types/global"
|
import { ConfigModule, MedusaContainer } from "../types/global"
|
||||||
import { isDefined } from "../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
import formatRegistrationName from "../utils/format-registration-name"
|
import formatRegistrationName from "../utils/format-registration-name"
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { aliasTo, asFunction } from "awilix"
|
|||||||
import formatRegistrationName from "../utils/format-registration-name"
|
import formatRegistrationName from "../utils/format-registration-name"
|
||||||
import { isBatchJobStrategy } from "../interfaces"
|
import { isBatchJobStrategy } from "../interfaces"
|
||||||
import { MedusaContainer } from "../types/global"
|
import { MedusaContainer } from "../types/global"
|
||||||
import { isDefined } from "../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
|
|
||||||
type LoaderOptions = {
|
type LoaderOptions = {
|
||||||
container: MedusaContainer
|
container: MedusaContainer
|
||||||
|
|||||||
@@ -1,12 +1,4 @@
|
|||||||
import {
|
import { BeforeInsert, Column, Entity, Index, JoinColumn, ManyToOne, Unique, } from "typeorm"
|
||||||
BeforeInsert,
|
|
||||||
Column,
|
|
||||||
Entity,
|
|
||||||
Index,
|
|
||||||
JoinColumn,
|
|
||||||
ManyToOne,
|
|
||||||
Unique,
|
|
||||||
} from "typeorm"
|
|
||||||
|
|
||||||
import { BaseEntity } from "../interfaces"
|
import { BaseEntity } from "../interfaces"
|
||||||
import { Cart } from "./cart"
|
import { Cart } from "./cart"
|
||||||
@@ -24,12 +16,13 @@ export enum PaymentSessionStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Unique("OneSelected", ["cart_id", "is_selected"])
|
@Unique("OneSelected", ["cart_id", "is_selected"])
|
||||||
|
// TODO: This uniq constraint should be updated once the order edit flag is dropped and should add a where clause on cart_id is not null
|
||||||
@Unique("UniqPaymentSessionCartIdProviderId", ["cart_id", "provider_id"])
|
@Unique("UniqPaymentSessionCartIdProviderId", ["cart_id", "provider_id"])
|
||||||
@Entity()
|
@Entity()
|
||||||
export class PaymentSession extends BaseEntity {
|
export class PaymentSession extends BaseEntity {
|
||||||
@Index()
|
@Index()
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
cart_id: string
|
cart_id: string | null
|
||||||
|
|
||||||
@ManyToOne(() => Cart, (cart) => cart.payment_sessions)
|
@ManyToOne(() => Cart, (cart) => cart.payment_sessions)
|
||||||
@JoinColumn({ name: "cart_id" })
|
@JoinColumn({ name: "cart_id" })
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { MedusaError } from "medusa-core-utils"
|
|||||||
import { PaymentCollection } from "./../models/payment-collection"
|
import { PaymentCollection } from "./../models/payment-collection"
|
||||||
import { EntityRepository, Repository } from "typeorm"
|
import { EntityRepository, Repository } from "typeorm"
|
||||||
import { FindConfig } from "../types/common"
|
import { FindConfig } from "../types/common"
|
||||||
import { PaymentSession } from "../models"
|
|
||||||
|
|
||||||
@EntityRepository(PaymentCollection)
|
@EntityRepository(PaymentCollection)
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
@@ -61,12 +60,4 @@ export class PaymentCollectionRepository extends Repository<PaymentCollection> {
|
|||||||
|
|
||||||
return paymentCollection[0]
|
return paymentCollection[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteMultiple(ids: string[]): Promise<void> {
|
|
||||||
await this.createQueryBuilder()
|
|
||||||
.delete()
|
|
||||||
.from(PaymentSession)
|
|
||||||
.where("id IN (:...ids)", { ids })
|
|
||||||
.execute()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,23 @@
|
|||||||
import { unionBy } from "lodash"
|
import { unionBy } from "lodash"
|
||||||
import {
|
import {
|
||||||
In,
|
|
||||||
Not,
|
|
||||||
DeleteResult,
|
DeleteResult,
|
||||||
SelectQueryBuilder,
|
|
||||||
EntityRepository,
|
EntityRepository,
|
||||||
FindManyOptions,
|
FindManyOptions,
|
||||||
FindOptionsUtils,
|
FindOptionsUtils,
|
||||||
|
In,
|
||||||
|
Not,
|
||||||
Repository,
|
Repository,
|
||||||
|
SelectQueryBuilder,
|
||||||
} from "typeorm"
|
} from "typeorm"
|
||||||
import { TaxRate } from "../models/tax-rate"
|
import {
|
||||||
import { ProductTaxRate } from "../models/product-tax-rate"
|
Product,
|
||||||
import { ProductTypeTaxRate } from "../models/product-type-tax-rate"
|
ProductTaxRate,
|
||||||
import { ShippingTaxRate } from "../models/shipping-tax-rate"
|
ProductTypeTaxRate,
|
||||||
import { Product } from "../models/product"
|
ShippingTaxRate,
|
||||||
import { ShippingMethod } from "../models/shipping-method"
|
TaxRate,
|
||||||
|
} from "../models"
|
||||||
import { TaxRateListByConfig } from "../types/tax-rate"
|
import { TaxRateListByConfig } from "../types/tax-rate"
|
||||||
import { isDefined } from "../utils"
|
import { isDefined } from "medusa-core-utils"
|
||||||
|
|
||||||
const resolveableFields = [
|
const resolveableFields = [
|
||||||
"product_count",
|
"product_count",
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { asClass, asValue, createContainer } from "awilix"
|
||||||
|
import { MockManager, MockRepository } from "medusa-test-utils"
|
||||||
|
import PaymentProviderService from "../payment-provider";
|
||||||
|
import { PaymentProviderServiceMock } from "../__mocks__/payment-provider";
|
||||||
|
import { CustomerServiceMock } from "../__mocks__/customer";
|
||||||
|
import { FlagRouter } from "../../utils/flag-router";
|
||||||
|
import Logger from "../../loaders/logger";
|
||||||
|
|
||||||
|
export const defaultContainer = createContainer()
|
||||||
|
defaultContainer.register("paymentProviderService", asClass(PaymentProviderService))
|
||||||
|
defaultContainer.register("manager", asValue(MockManager))
|
||||||
|
defaultContainer.register("paymentSessionRepository", asValue(MockRepository()))
|
||||||
|
defaultContainer.register("paymentProviderRepository", asValue(PaymentProviderServiceMock))
|
||||||
|
defaultContainer.register("paymentRepository", asValue(MockRepository()))
|
||||||
|
defaultContainer.register("refundRepository", asValue(MockRepository()))
|
||||||
|
defaultContainer.register("customerService", asValue(CustomerServiceMock))
|
||||||
|
defaultContainer.register("featureFlagRouter", asValue(new FlagRouter({})))
|
||||||
|
defaultContainer.register("logger", asValue(Logger))
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { isString } from "../../utils";
|
||||||
|
|
||||||
export const DefaultProviderMock = {
|
export const DefaultProviderMock = {
|
||||||
getStatus: jest.fn().mockImplementation((data) => {
|
getStatus: jest.fn().mockImplementation((data) => {
|
||||||
if (data.money_id === "success") {
|
if (data.money_id === "success") {
|
||||||
@@ -28,12 +30,6 @@ export const PaymentProviderServiceMock = {
|
|||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
updateSession: jest.fn().mockImplementation((session, cart) => {
|
updateSession: jest.fn().mockImplementation((session, cart) => {
|
||||||
return Promise.resolve({
|
|
||||||
...session.data,
|
|
||||||
id: `${session.data.id}_updated`,
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
updateSessionNew: jest.fn().mockImplementation((session, sessionInput) => {
|
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
...session,
|
...session,
|
||||||
id: `${session.id}_updated`,
|
id: `${session.id}_updated`,
|
||||||
@@ -45,16 +41,17 @@ export const PaymentProviderServiceMock = {
|
|||||||
registerInstalledProviders: jest.fn().mockImplementation(() => {
|
registerInstalledProviders: jest.fn().mockImplementation(() => {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}),
|
}),
|
||||||
createSession: jest.fn().mockImplementation((providerId, cart) => {
|
createSession: jest.fn().mockImplementation((providerIdOrSessionInput, cart) => {
|
||||||
return Promise.resolve({
|
if (isString(providerIdOrSessionInput)) {
|
||||||
id: `${providerId}_session`,
|
return Promise.resolve({
|
||||||
cartId: cart._id,
|
id: `${providerIdOrSessionInput}_session`,
|
||||||
})
|
cartId: cart._id,
|
||||||
}),
|
})
|
||||||
createSessionNew: jest.fn().mockImplementation((sessionInput) => {
|
} else {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
id: `${sessionInput.providerId}_session`,
|
id: `${providerIdOrSessionInput.providerId}_session`,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
retrieveProvider: jest.fn().mockImplementation((providerId) => {
|
retrieveProvider: jest.fn().mockImplementation((providerId) => {
|
||||||
if (providerId === "default_provider") {
|
if (providerId === "default_provider") {
|
||||||
@@ -62,9 +59,9 @@ export const PaymentProviderServiceMock = {
|
|||||||
}
|
}
|
||||||
throw new Error("Provider Not Found")
|
throw new Error("Provider Not Found")
|
||||||
}),
|
}),
|
||||||
refreshSessionNew: jest.fn().mockImplementation((session, inputData) => {
|
refreshSession: jest.fn().mockImplementation((session, inputData) => {
|
||||||
DefaultProviderMock.deletePayment()
|
DefaultProviderMock.deletePayment()
|
||||||
PaymentProviderServiceMock.createSessionNew(inputData)
|
PaymentProviderServiceMock.createSession(inputData)
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
...session,
|
...session,
|
||||||
id: `${session.id}_refreshed`,
|
id: `${session.id}_refreshed`,
|
||||||
@@ -73,7 +70,7 @@ export const PaymentProviderServiceMock = {
|
|||||||
authorizePayment: jest
|
authorizePayment: jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockReturnValue(Promise.resolve({ status: "authorized" })),
|
.mockReturnValue(Promise.resolve({ status: "authorized" })),
|
||||||
createPaymentNew: jest.fn().mockImplementation((session, inputData) => {
|
createPayment: jest.fn().mockImplementation((session, inputData) => {
|
||||||
Promise.resolve(inputData)
|
Promise.resolve(inputData)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1528,12 +1528,22 @@ describe("CartService", () => {
|
|||||||
|
|
||||||
expect(paymentProviderService.createSession).toHaveBeenCalledTimes(2)
|
expect(paymentProviderService.createSession).toHaveBeenCalledTimes(2)
|
||||||
expect(paymentProviderService.createSession).toHaveBeenCalledWith(
|
expect(paymentProviderService.createSession).toHaveBeenCalledWith(
|
||||||
"provider_1",
|
{
|
||||||
cart1
|
cart: cart1,
|
||||||
|
customer: cart1.customer,
|
||||||
|
amount: cart1.total,
|
||||||
|
currency_code: cart1.region.currency_code,
|
||||||
|
provider_id: "provider_1",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
expect(paymentProviderService.createSession).toHaveBeenCalledWith(
|
expect(paymentProviderService.createSession).toHaveBeenCalledWith(
|
||||||
"provider_2",
|
{
|
||||||
cart1
|
cart: cart1,
|
||||||
|
customer: cart1.customer,
|
||||||
|
amount: cart1.total,
|
||||||
|
currency_code: cart1.region.currency_code,
|
||||||
|
provider_id: "provider_2",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,8 @@
|
|||||||
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
|
import { IdMap, MockManager, MockRepository } from "medusa-test-utils"
|
||||||
import {
|
import { CustomerService, EventBusService, PaymentCollectionService, PaymentProviderService, } from "../index"
|
||||||
CustomerService,
|
import { PaymentCollection, PaymentCollectionStatus, PaymentCollectionType, } from "../../models"
|
||||||
EventBusService,
|
|
||||||
PaymentCollectionService,
|
|
||||||
PaymentProviderService,
|
|
||||||
PaymentService,
|
|
||||||
} from "../index"
|
|
||||||
import {
|
|
||||||
PaymentCollectionStatus,
|
|
||||||
PaymentCollectionType,
|
|
||||||
PaymentCollection,
|
|
||||||
} from "../../models"
|
|
||||||
import { EventBusServiceMock } from "../__mocks__/event-bus"
|
import { EventBusServiceMock } from "../__mocks__/event-bus"
|
||||||
import {
|
import { DefaultProviderMock, PaymentProviderServiceMock, } from "../__mocks__/payment-provider"
|
||||||
DefaultProviderMock,
|
|
||||||
PaymentProviderServiceMock,
|
|
||||||
} from "../__mocks__/payment-provider"
|
|
||||||
import { CustomerServiceMock } from "../__mocks__/customer"
|
import { CustomerServiceMock } from "../__mocks__/customer"
|
||||||
import { PaymentCollectionsSessionsBatchInput } from "../../types/payment-collection"
|
import { PaymentCollectionsSessionsBatchInput } from "../../types/payment-collection"
|
||||||
|
|
||||||
@@ -395,7 +382,7 @@ describe("PaymentCollectionService", () => {
|
|||||||
`Cannot set payment sessions for a payment collection with status ${PaymentCollectionStatus.AUTHORIZED}`
|
`Cannot set payment sessions for a payment collection with status ${PaymentCollectionStatus.AUTHORIZED}`
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toBeCalledTimes(0)
|
expect(PaymentProviderServiceMock.createSession).toBeCalledTimes(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should ignore session if provider doesn't belong to the region", async () => {
|
it("should ignore session if provider doesn't belong to the region", async () => {
|
||||||
@@ -408,7 +395,7 @@ describe("PaymentCollectionService", () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
expect(multiRet).rejects.toThrow(`Payment provider not found`)
|
expect(multiRet).rejects.toThrow(`Payment provider not found`)
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toBeCalledTimes(0)
|
expect(PaymentProviderServiceMock.createSession).toBeCalledTimes(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should add a new session", async () => {
|
it("should add a new session", async () => {
|
||||||
@@ -420,7 +407,7 @@ describe("PaymentCollectionService", () => {
|
|||||||
"lebron"
|
"lebron"
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createSession).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
expect(CustomerServiceMock.retrieve).toHaveBeenCalledTimes(1)
|
expect(CustomerServiceMock.retrieve).toHaveBeenCalledTimes(1)
|
||||||
@@ -436,10 +423,10 @@ describe("PaymentCollectionService", () => {
|
|||||||
"lebron"
|
"lebron"
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createSession).toHaveBeenCalledTimes(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
expect(PaymentProviderServiceMock.updateSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.updateSession).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
expect(CustomerServiceMock.retrieve).toHaveBeenCalledTimes(1)
|
expect(CustomerServiceMock.retrieve).toHaveBeenCalledTimes(1)
|
||||||
@@ -459,13 +446,13 @@ describe("PaymentCollectionService", () => {
|
|||||||
IdMap.getId("lebron")
|
IdMap.getId("lebron")
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createSession).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
expect(PaymentProviderServiceMock.updateSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.updateSession).toHaveBeenCalledTimes(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
expect(paymentCollectionRepository.deleteMultiple).toHaveBeenCalledTimes(
|
expect(paymentCollectionRepository.delete).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -497,7 +484,7 @@ describe("PaymentCollectionService", () => {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toBeCalledTimes(0)
|
expect(PaymentProviderServiceMock.createSession).toBeCalledTimes(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should throw error if amount is different than requested", async () => {
|
it("should throw error if amount is different than requested", async () => {
|
||||||
@@ -514,7 +501,7 @@ describe("PaymentCollectionService", () => {
|
|||||||
"customer1"
|
"customer1"
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createSession).toHaveBeenCalledTimes(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
expect(ret).rejects.toThrow(
|
expect(ret).rejects.toThrow(
|
||||||
@@ -537,7 +524,7 @@ describe("PaymentCollectionService", () => {
|
|||||||
"customer1"
|
"customer1"
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createSession).toHaveBeenCalledTimes(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
expect(multiRet).rejects.toThrow(
|
expect(multiRet).rejects.toThrow(
|
||||||
@@ -565,7 +552,7 @@ describe("PaymentCollectionService", () => {
|
|||||||
expect(multiRet).rejects.toThrow(
|
expect(multiRet).rejects.toThrow(
|
||||||
`The sum of sessions is not equal to 100 on Payment Collection`
|
`The sum of sessions is not equal to 100 on Payment Collection`
|
||||||
)
|
)
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toBeCalledTimes(0)
|
expect(PaymentProviderServiceMock.createSession).toBeCalledTimes(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should add a new session and update existing one", async () => {
|
it("should add a new session and update existing one", async () => {
|
||||||
@@ -586,10 +573,10 @@ describe("PaymentCollectionService", () => {
|
|||||||
"lebron"
|
"lebron"
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createSession).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
expect(PaymentProviderServiceMock.updateSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.updateSession).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
expect(CustomerServiceMock.retrieve).toHaveBeenCalledTimes(1)
|
expect(CustomerServiceMock.retrieve).toHaveBeenCalledTimes(1)
|
||||||
@@ -609,13 +596,13 @@ describe("PaymentCollectionService", () => {
|
|||||||
IdMap.getId("lebron")
|
IdMap.getId("lebron")
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createSession).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
expect(PaymentProviderServiceMock.updateSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.updateSession).toHaveBeenCalledTimes(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
expect(paymentCollectionRepository.deleteMultiple).toHaveBeenCalledTimes(
|
expect(paymentCollectionRepository.delete).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -630,10 +617,10 @@ describe("PaymentCollectionService", () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
PaymentProviderServiceMock.refreshSessionNew
|
PaymentProviderServiceMock.refreshSession
|
||||||
).toHaveBeenCalledTimes(1)
|
).toHaveBeenCalledTimes(1)
|
||||||
expect(DefaultProviderMock.deletePayment).toHaveBeenCalledTimes(1)
|
expect(DefaultProviderMock.deletePayment).toHaveBeenCalledTimes(1)
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createSession).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -650,9 +637,9 @@ describe("PaymentCollectionService", () => {
|
|||||||
"payCol_session-not-found"
|
"payCol_session-not-found"
|
||||||
)} was not found`
|
)} was not found`
|
||||||
)
|
)
|
||||||
expect(PaymentProviderServiceMock.refreshSessionNew).toBeCalledTimes(0)
|
expect(PaymentProviderServiceMock.refreshSession).toBeCalledTimes(0)
|
||||||
expect(DefaultProviderMock.deletePayment).toBeCalledTimes(0)
|
expect(DefaultProviderMock.deletePayment).toBeCalledTimes(0)
|
||||||
expect(PaymentProviderServiceMock.createSessionNew).toBeCalledTimes(0)
|
expect(PaymentProviderServiceMock.createSession).toBeCalledTimes(0)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -695,7 +682,7 @@ describe("PaymentCollectionService", () => {
|
|||||||
expect(PaymentProviderServiceMock.authorizePayment).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.authorizePayment).toHaveBeenCalledTimes(
|
||||||
2
|
2
|
||||||
)
|
)
|
||||||
expect(PaymentProviderServiceMock.createPaymentNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createPayment).toHaveBeenCalledTimes(
|
||||||
2
|
2
|
||||||
)
|
)
|
||||||
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(1)
|
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(1)
|
||||||
@@ -710,7 +697,7 @@ describe("PaymentCollectionService", () => {
|
|||||||
expect(PaymentProviderServiceMock.authorizePayment).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.authorizePayment).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
expect(PaymentProviderServiceMock.createPaymentNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createPayment).toHaveBeenCalledTimes(
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(1)
|
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(1)
|
||||||
@@ -725,7 +712,7 @@ describe("PaymentCollectionService", () => {
|
|||||||
expect(PaymentProviderServiceMock.authorizePayment).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.authorizePayment).toHaveBeenCalledTimes(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
expect(PaymentProviderServiceMock.createPaymentNew).toHaveBeenCalledTimes(
|
expect(PaymentProviderServiceMock.createPayment).toHaveBeenCalledTimes(
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(0)
|
expect(EventBusServiceMock.emit).toHaveBeenCalledTimes(0)
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
import { MockManager, MockRepository } from "medusa-test-utils"
|
import { asValue, createContainer } from "awilix"
|
||||||
|
import { MockRepository } from "medusa-test-utils"
|
||||||
import PaymentProviderService from "../payment-provider"
|
import PaymentProviderService from "../payment-provider"
|
||||||
|
import { defaultContainer } from "../__fixtures__/payment-provider"
|
||||||
import { testPayServiceMock } from "../__mocks__/test-pay"
|
import { testPayServiceMock } from "../__mocks__/test-pay"
|
||||||
import { FlagRouter } from "../../utils/flag-router"
|
|
||||||
|
|
||||||
describe("PaymentProviderService", () => {
|
describe("PaymentProviderService", () => {
|
||||||
describe("retrieveProvider", () => {
|
describe("retrieveProvider", () => {
|
||||||
const container = {
|
const container = createContainer({}, defaultContainer)
|
||||||
manager: MockManager,
|
container.register("pp_default_provider", asValue("good"))
|
||||||
paymentSessionRepository: MockRepository(),
|
|
||||||
pp_default_provider: "good",
|
|
||||||
}
|
|
||||||
|
|
||||||
const providerService = new PaymentProviderService(container)
|
const providerService = container.resolve("paymentProviderService")
|
||||||
|
|
||||||
it("successfully retrieves payment provider", () => {
|
it("successfully retrieves payment provider", () => {
|
||||||
const provider = providerService.retrieveProvider("default_provider")
|
const provider = providerService.retrieveProvider("default_provider")
|
||||||
@@ -30,56 +28,78 @@ describe("PaymentProviderService", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("createSession", () => {
|
describe("createSession", () => {
|
||||||
const createPayment = jest.fn().mockReturnValue(Promise.resolve())
|
const container = createContainer({}, defaultContainer)
|
||||||
const container = {
|
container.register(
|
||||||
manager: MockManager,
|
"pp_default_provider",
|
||||||
paymentSessionRepository: MockRepository(),
|
asValue({
|
||||||
pp_default_provider: {
|
|
||||||
withTransaction: function () {
|
withTransaction: function () {
|
||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
createPayment,
|
createPayment: jest.fn().mockReturnValue(Promise.resolve({})),
|
||||||
},
|
})
|
||||||
}
|
)
|
||||||
|
|
||||||
const providerService = new PaymentProviderService(container)
|
const providerService = container.resolve("paymentProviderService")
|
||||||
|
|
||||||
it("successfully creates session", async () => {
|
it("successfully creates session", async () => {
|
||||||
await providerService.createSession("default_provider", {
|
await providerService.createSession("default_provider", {
|
||||||
|
object: "cart",
|
||||||
|
region: {
|
||||||
|
currency_code: "usd",
|
||||||
|
},
|
||||||
total: 100,
|
total: 100,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(createPayment).toBeCalledTimes(1)
|
const defaultProvider = container.resolve("pp_default_provider")
|
||||||
expect(createPayment).toBeCalledWith({
|
|
||||||
|
expect(defaultProvider.createPayment).toBeCalledTimes(1)
|
||||||
|
expect(defaultProvider.createPayment).toBeCalledWith({
|
||||||
|
amount: 100,
|
||||||
|
object: "cart",
|
||||||
total: 100,
|
total: 100,
|
||||||
|
region: {
|
||||||
|
currency_code: "usd",
|
||||||
|
},
|
||||||
|
cart: {
|
||||||
|
context: undefined,
|
||||||
|
email: undefined,
|
||||||
|
id: undefined,
|
||||||
|
shipping_address: undefined,
|
||||||
|
shipping_methods: undefined,
|
||||||
|
},
|
||||||
|
currency_code: "usd",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("updateSession", () => {
|
describe("updateSession", () => {
|
||||||
const updatePayment = jest.fn().mockReturnValue(Promise.resolve())
|
const container = createContainer({}, defaultContainer)
|
||||||
|
container.register(
|
||||||
const container = {
|
"paymentSessionRepository",
|
||||||
manager: MockManager,
|
asValue(
|
||||||
paymentSessionRepository: MockRepository({
|
MockRepository({
|
||||||
findOne: () =>
|
findOne: () =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
id: "session",
|
id: "session",
|
||||||
provider_id: "default_provider",
|
provider_id: "default_provider",
|
||||||
data: {
|
data: {
|
||||||
id: "1234",
|
id: "1234",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
}),
|
})
|
||||||
pp_default_provider: {
|
)
|
||||||
|
)
|
||||||
|
container.register(
|
||||||
|
"pp_default_provider",
|
||||||
|
asValue({
|
||||||
withTransaction: function () {
|
withTransaction: function () {
|
||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
updatePayment,
|
updatePayment: jest.fn().mockReturnValue(Promise.resolve()),
|
||||||
},
|
})
|
||||||
}
|
)
|
||||||
|
|
||||||
const providerService = new PaymentProviderService(container)
|
const providerService = container.resolve("paymentProviderService")
|
||||||
|
|
||||||
it("successfully creates session", async () => {
|
it("successfully creates session", async () => {
|
||||||
await providerService.updateSession(
|
await providerService.updateSession(
|
||||||
@@ -91,15 +111,28 @@ describe("PaymentProviderService", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
object: "cart",
|
||||||
total: 100,
|
total: 100,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(updatePayment).toBeCalledTimes(1)
|
const defaultProvider = container.resolve("pp_default_provider")
|
||||||
expect(updatePayment).toBeCalledWith(
|
|
||||||
|
expect(defaultProvider.updatePayment).toBeCalledTimes(1)
|
||||||
|
expect(defaultProvider.updatePayment).toBeCalledWith(
|
||||||
{ id: "1234" },
|
{ id: "1234" },
|
||||||
{
|
{
|
||||||
|
object: "cart",
|
||||||
|
amount: 100,
|
||||||
total: 100,
|
total: 100,
|
||||||
|
cart: {
|
||||||
|
context: undefined,
|
||||||
|
email: undefined,
|
||||||
|
id: undefined,
|
||||||
|
shipping_address: undefined,
|
||||||
|
shipping_methods: undefined,
|
||||||
|
},
|
||||||
|
currency_code: undefined,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -107,50 +140,53 @@ describe("PaymentProviderService", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe(`PaymentProviderService`, () => {
|
describe(`PaymentProviderService`, () => {
|
||||||
const featureFlagRouter = new FlagRouter({
|
const container = createContainer({}, defaultContainer)
|
||||||
order_editing: false,
|
container.register("pp_default_provider", asValue(testPayServiceMock))
|
||||||
})
|
container.register(
|
||||||
|
"paymentSessionRepository",
|
||||||
const container = {
|
asValue(
|
||||||
manager: MockManager,
|
MockRepository({
|
||||||
paymentSessionRepository: MockRepository({
|
findOne: () =>
|
||||||
findOne: () =>
|
Promise.resolve({
|
||||||
Promise.resolve({
|
id: "session",
|
||||||
id: "session",
|
provider_id: "default_provider",
|
||||||
provider_id: "default_provider",
|
data: {
|
||||||
data: {
|
id: "1234",
|
||||||
id: "1234",
|
},
|
||||||
},
|
}),
|
||||||
}),
|
})
|
||||||
}),
|
)
|
||||||
paymentRepository: MockRepository({
|
)
|
||||||
findOne: () =>
|
container.register(
|
||||||
Promise.resolve({
|
"paymentRepository",
|
||||||
id: "pay_jadazdjk",
|
asValue(
|
||||||
provider_id: "default_provider",
|
MockRepository({
|
||||||
data: {
|
findOne: () =>
|
||||||
id: "1234",
|
Promise.resolve({
|
||||||
},
|
|
||||||
}),
|
|
||||||
find: () =>
|
|
||||||
Promise.resolve([
|
|
||||||
{
|
|
||||||
id: "pay_jadazdjk",
|
id: "pay_jadazdjk",
|
||||||
provider_id: "default_provider",
|
provider_id: "default_provider",
|
||||||
data: {
|
data: {
|
||||||
id: "1234",
|
id: "1234",
|
||||||
},
|
},
|
||||||
captured_at: new Date(),
|
}),
|
||||||
amount: 100,
|
find: () =>
|
||||||
amount_refunded: 0,
|
Promise.resolve([
|
||||||
},
|
{
|
||||||
]),
|
id: "pay_jadazdjk",
|
||||||
}),
|
provider_id: "default_provider",
|
||||||
refundRepository: MockRepository(),
|
data: {
|
||||||
pp_default_provider: testPayServiceMock,
|
id: "1234",
|
||||||
featureFlagRouter,
|
},
|
||||||
}
|
captured_at: new Date(),
|
||||||
const providerService = new PaymentProviderService(container)
|
amount: 100,
|
||||||
|
amount_refunded: 0,
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
const providerService = container.resolve("paymentProviderService")
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
@@ -163,12 +199,29 @@ describe(`PaymentProviderService`, () => {
|
|||||||
|
|
||||||
it("successfully creates session", async () => {
|
it("successfully creates session", async () => {
|
||||||
await providerService.createSession("default_provider", {
|
await providerService.createSession("default_provider", {
|
||||||
|
object: "cart",
|
||||||
|
region: {
|
||||||
|
currency_code: "usd",
|
||||||
|
},
|
||||||
total: 100,
|
total: 100,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(testPayServiceMock.createPayment).toBeCalledTimes(1)
|
expect(testPayServiceMock.createPayment).toBeCalledTimes(1)
|
||||||
expect(testPayServiceMock.createPayment).toBeCalledWith({
|
expect(testPayServiceMock.createPayment).toBeCalledWith({
|
||||||
|
amount: 100,
|
||||||
|
object: "cart",
|
||||||
total: 100,
|
total: 100,
|
||||||
|
region: {
|
||||||
|
currency_code: "usd",
|
||||||
|
},
|
||||||
|
cart: {
|
||||||
|
context: undefined,
|
||||||
|
email: undefined,
|
||||||
|
id: undefined,
|
||||||
|
shipping_address: undefined,
|
||||||
|
shipping_methods: undefined,
|
||||||
|
},
|
||||||
|
currency_code: "usd",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -182,6 +235,7 @@ describe(`PaymentProviderService`, () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
object: "cart",
|
||||||
total: 100,
|
total: 100,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -190,7 +244,16 @@ describe(`PaymentProviderService`, () => {
|
|||||||
expect(testPayServiceMock.updatePayment).toBeCalledWith(
|
expect(testPayServiceMock.updatePayment).toBeCalledWith(
|
||||||
{ id: "1234" },
|
{ id: "1234" },
|
||||||
{
|
{
|
||||||
|
amount: 100,
|
||||||
|
object: "cart",
|
||||||
total: 100,
|
total: 100,
|
||||||
|
cart: {
|
||||||
|
context: undefined,
|
||||||
|
email: undefined,
|
||||||
|
id: undefined,
|
||||||
|
shipping_address: undefined,
|
||||||
|
shipping_methods: undefined,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -205,7 +268,9 @@ describe(`PaymentProviderService`, () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
total: 100,
|
provider_id: "default_provider",
|
||||||
|
amount: 100,
|
||||||
|
currency_code: "usd",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import {
|
|||||||
} from "../types/batch-job"
|
} from "../types/batch-job"
|
||||||
import { FindConfig } from "../types/common"
|
import { FindConfig } from "../types/common"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { buildQuery, isDefined } from "../utils"
|
import { buildQuery } from "../utils"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EventBusService, StrategyResolverService } from "./index"
|
import { EventBusService, StrategyResolverService } from "./index"
|
||||||
import { Request } from "express"
|
import { Request } from "express"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { isEmpty, isEqual } from "lodash"
|
import { isEmpty, isEqual } from "lodash"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { DeepPartial, EntityManager, In } from "typeorm"
|
import { DeepPartial, EntityManager, In } from "typeorm"
|
||||||
import { IPriceSelectionStrategy, TransactionBaseService } from "../interfaces"
|
import { IPriceSelectionStrategy, TransactionBaseService } from "../interfaces"
|
||||||
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
|
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
|
||||||
@@ -34,7 +34,7 @@ import {
|
|||||||
TotalField,
|
TotalField,
|
||||||
WithRequiredProperty,
|
WithRequiredProperty,
|
||||||
} from "../types/common"
|
} from "../types/common"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
import { validateEmail } from "../utils/is-email"
|
import { validateEmail } from "../utils/is-email"
|
||||||
import CustomShippingOptionService from "./custom-shipping-option"
|
import CustomShippingOptionService from "./custom-shipping-option"
|
||||||
@@ -54,6 +54,7 @@ import ShippingOptionService from "./shipping-option"
|
|||||||
import StoreService from "./store"
|
import StoreService from "./store"
|
||||||
import TaxProviderService from "./tax-provider"
|
import TaxProviderService from "./tax-provider"
|
||||||
import TotalsService from "./totals"
|
import TotalsService from "./totals"
|
||||||
|
import { PaymentSessionInput } from "../types/payment"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
manager: EntityManager
|
manager: EntityManager
|
||||||
@@ -1678,6 +1679,12 @@ class CartService extends TransactionBaseService {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const { total, region } = cart
|
const { total, region } = cart
|
||||||
|
const partialSessionInput: Omit<PaymentSessionInput, "provider_id"> = {
|
||||||
|
cart: cart as Cart,
|
||||||
|
customer: cart.customer,
|
||||||
|
amount: cart.total,
|
||||||
|
currency_code: cart.region.currency_code,
|
||||||
|
}
|
||||||
|
|
||||||
// If there are existing payment sessions ensure that these are up to date
|
// If there are existing payment sessions ensure that these are up to date
|
||||||
const seen: string[] = []
|
const seen: string[] = []
|
||||||
@@ -1695,9 +1702,15 @@ class CartService extends TransactionBaseService {
|
|||||||
.deleteSession(paymentSession)
|
.deleteSession(paymentSession)
|
||||||
} else {
|
} else {
|
||||||
seen.push(paymentSession.provider_id)
|
seen.push(paymentSession.provider_id)
|
||||||
|
|
||||||
|
const paymentSessionInput = {
|
||||||
|
...partialSessionInput,
|
||||||
|
provider_id: paymentSession.provider_id,
|
||||||
|
}
|
||||||
|
|
||||||
return this.paymentProviderService_
|
return this.paymentProviderService_
|
||||||
.withTransaction(transactionManager)
|
.withTransaction(transactionManager)
|
||||||
.updateSession(paymentSession, cart)
|
.updateSession(paymentSession, paymentSessionInput)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -1707,9 +1720,14 @@ class CartService extends TransactionBaseService {
|
|||||||
// If only one payment session exists, we preselect it
|
// If only one payment session exists, we preselect it
|
||||||
if (region.payment_providers.length === 1 && !cart.payment_session) {
|
if (region.payment_providers.length === 1 && !cart.payment_session) {
|
||||||
const paymentProvider = region.payment_providers[0]
|
const paymentProvider = region.payment_providers[0]
|
||||||
|
const paymentSessionInput = {
|
||||||
|
...partialSessionInput,
|
||||||
|
provider_id: paymentProvider.id,
|
||||||
|
}
|
||||||
|
|
||||||
const paymentSession = await this.paymentProviderService_
|
const paymentSession = await this.paymentProviderService_
|
||||||
.withTransaction(transactionManager)
|
.withTransaction(transactionManager)
|
||||||
.createSession(paymentProvider.id, cart)
|
.createSession(paymentSessionInput)
|
||||||
|
|
||||||
paymentSession.is_selected = true
|
paymentSession.is_selected = true
|
||||||
|
|
||||||
@@ -1718,9 +1736,14 @@ class CartService extends TransactionBaseService {
|
|||||||
await Promise.all(
|
await Promise.all(
|
||||||
region.payment_providers.map(async (paymentProvider) => {
|
region.payment_providers.map(async (paymentProvider) => {
|
||||||
if (!seen.includes(paymentProvider.id)) {
|
if (!seen.includes(paymentProvider.id)) {
|
||||||
|
const paymentSessionInput = {
|
||||||
|
...partialSessionInput,
|
||||||
|
provider_id: paymentProvider.id,
|
||||||
|
}
|
||||||
|
|
||||||
return this.paymentProviderService_
|
return this.paymentProviderService_
|
||||||
.withTransaction(transactionManager)
|
.withTransaction(transactionManager)
|
||||||
.createSession(paymentProvider.id, cart)
|
.createSession(paymentSessionInput)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
@@ -1792,7 +1815,7 @@ class CartService extends TransactionBaseService {
|
|||||||
): Promise<Cart> {
|
): Promise<Cart> {
|
||||||
return await this.atomicPhase_(
|
return await this.atomicPhase_(
|
||||||
async (transactionManager: EntityManager) => {
|
async (transactionManager: EntityManager) => {
|
||||||
const cart = await this.retrieve(cartId, {
|
const cart = await this.retrieveWithTotals(cartId, {
|
||||||
relations: ["payment_sessions"],
|
relations: ["payment_sessions"],
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1805,7 +1828,13 @@ class CartService extends TransactionBaseService {
|
|||||||
// Delete the session with the provider
|
// Delete the session with the provider
|
||||||
await this.paymentProviderService_
|
await this.paymentProviderService_
|
||||||
.withTransaction(transactionManager)
|
.withTransaction(transactionManager)
|
||||||
.refreshSession(paymentSession, cart)
|
.refreshSession(paymentSession, {
|
||||||
|
cart: cart as Cart,
|
||||||
|
customer: cart.customer,
|
||||||
|
amount: cart.total,
|
||||||
|
currency_code: cart.region.currency_code,
|
||||||
|
provider_id: providerId,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { ClaimImage, ClaimItem, ClaimTag } from "../models"
|
import { ClaimImage, ClaimItem, ClaimTag } from "../models"
|
||||||
@@ -7,7 +7,7 @@ import { ClaimItemRepository } from "../repositories/claim-item"
|
|||||||
import { ClaimTagRepository } from "../repositories/claim-tag"
|
import { ClaimTagRepository } from "../repositories/claim-tag"
|
||||||
import { CreateClaimItemInput } from "../types/claim"
|
import { CreateClaimItemInput } from "../types/claim"
|
||||||
import { FindConfig, Selector } from "../types/common"
|
import { FindConfig, Selector } from "../types/common"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import EventBusService from "./event-bus"
|
import EventBusService from "./event-bus"
|
||||||
import LineItemService from "./line-item"
|
import LineItemService from "./line-item"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { DeepPartial, EntityManager } from "typeorm"
|
import { DeepPartial, EntityManager } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import {
|
import {
|
||||||
@@ -16,7 +16,7 @@ import { LineItemRepository } from "../repositories/line-item"
|
|||||||
import { ShippingMethodRepository } from "../repositories/shipping-method"
|
import { ShippingMethodRepository } from "../repositories/shipping-method"
|
||||||
import { CreateClaimInput, UpdateClaimInput } from "../types/claim"
|
import { CreateClaimInput, UpdateClaimInput } from "../types/claim"
|
||||||
import { FindConfig } from "../types/common"
|
import { FindConfig } from "../types/common"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import ClaimItemService from "./claim-item"
|
import ClaimItemService from "./claim-item"
|
||||||
import EventBusService from "./event-bus"
|
import EventBusService from "./event-bus"
|
||||||
import FulfillmentService from "./fulfillment"
|
import FulfillmentService from "./fulfillment"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { DeepPartial, EntityManager, ILike } from "typeorm"
|
import { DeepPartial, EntityManager, ILike } from "typeorm"
|
||||||
import { CustomerService } from "."
|
import { CustomerService } from "."
|
||||||
import { CustomerGroup } from ".."
|
import { CustomerGroup } from ".."
|
||||||
@@ -8,13 +8,7 @@ import {
|
|||||||
} from "../repositories/customer-group"
|
} from "../repositories/customer-group"
|
||||||
import { FindConfig, Selector } from "../types/common"
|
import { FindConfig, Selector } from "../types/common"
|
||||||
import { CustomerGroupUpdate } from "../types/customer-groups"
|
import { CustomerGroupUpdate } from "../types/customer-groups"
|
||||||
import {
|
import { buildQuery, isString, PostgresError, setMetadata } from "../utils"
|
||||||
buildQuery,
|
|
||||||
isDefined,
|
|
||||||
isString,
|
|
||||||
PostgresError,
|
|
||||||
setMetadata,
|
|
||||||
} from "../utils"
|
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
|
|
||||||
type CustomerGroupConstructorProps = {
|
type CustomerGroupConstructorProps = {
|
||||||
@@ -35,6 +29,7 @@ class CustomerGroupService extends TransactionBaseService {
|
|||||||
customerGroupRepository,
|
customerGroupRepository,
|
||||||
customerService,
|
customerService,
|
||||||
}: CustomerGroupConstructorProps) {
|
}: CustomerGroupConstructorProps) {
|
||||||
|
// eslint-disable-next-line prefer-rest-params
|
||||||
super(arguments[0])
|
super(arguments[0])
|
||||||
|
|
||||||
this.manager_ = manager
|
this.manager_ = manager
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import jwt from "jsonwebtoken"
|
import jwt from "jsonwebtoken"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import Scrypt from "scrypt-kdf"
|
import Scrypt from "scrypt-kdf"
|
||||||
import { DeepPartial, EntityManager } from "typeorm"
|
import { DeepPartial, EntityManager } from "typeorm"
|
||||||
import { EventBusService } from "."
|
import { EventBusService } from "."
|
||||||
@@ -10,7 +10,7 @@ import { AddressRepository } from "../repositories/address"
|
|||||||
import { CustomerRepository } from "../repositories/customer"
|
import { CustomerRepository } from "../repositories/customer"
|
||||||
import { AddressCreatePayload, FindConfig, Selector } from "../types/common"
|
import { AddressCreatePayload, FindConfig, Selector } from "../types/common"
|
||||||
import { CreateCustomerInput, UpdateCustomerInput } from "../types/customers"
|
import { CreateCustomerInput, UpdateCustomerInput } from "../types/customers"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
manager: EntityManager
|
manager: EntityManager
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { EventBusService } from "."
|
import { EventBusService } from "."
|
||||||
import {
|
import {
|
||||||
@@ -14,7 +14,7 @@ import { DiscountConditionRepository } from "../repositories/discount-condition"
|
|||||||
import { FindConfig } from "../types/common"
|
import { FindConfig } from "../types/common"
|
||||||
import { DiscountConditionInput } from "../types/discount"
|
import { DiscountConditionInput } from "../types/discount"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { buildQuery, isDefined, PostgresError } from "../utils"
|
import { buildQuery, PostgresError } from "../utils"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
manager: EntityManager
|
manager: EntityManager
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { parse, toSeconds } from "iso8601-duration"
|
import { parse, toSeconds } from "iso8601-duration"
|
||||||
import { isEmpty, omit } from "lodash"
|
import { isEmpty, omit } from "lodash"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import {
|
import {
|
||||||
Brackets,
|
Brackets,
|
||||||
DeepPartial,
|
DeepPartial,
|
||||||
@@ -36,7 +36,7 @@ import {
|
|||||||
UpdateDiscountInput,
|
UpdateDiscountInput,
|
||||||
UpdateDiscountRuleInput,
|
UpdateDiscountRuleInput,
|
||||||
} from "../types/discount"
|
} from "../types/discount"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import { isFuture, isPast } from "../utils/date-helpers"
|
import { isFuture, isPast } from "../utils/date-helpers"
|
||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
import CustomerService from "./customer"
|
import CustomerService from "./customer"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { Brackets, EntityManager, FindManyOptions, UpdateResult } from "typeorm"
|
import { Brackets, EntityManager, FindManyOptions, UpdateResult } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { Cart, CartType, DraftOrder, DraftOrderStatus } from "../models"
|
import { Cart, CartType, DraftOrder, DraftOrderStatus } from "../models"
|
||||||
@@ -7,7 +7,7 @@ import { OrderRepository } from "../repositories/order"
|
|||||||
import { PaymentRepository } from "../repositories/payment"
|
import { PaymentRepository } from "../repositories/payment"
|
||||||
import { ExtendedFindConfig, FindConfig } from "../types/common"
|
import { ExtendedFindConfig, FindConfig } from "../types/common"
|
||||||
import { DraftOrderCreateProps } from "../types/draft-orders"
|
import { DraftOrderCreateProps } from "../types/draft-orders"
|
||||||
import { buildQuery, isDefined } from "../utils"
|
import { buildQuery } from "../utils"
|
||||||
import CartService from "./cart"
|
import CartService from "./cart"
|
||||||
import CustomShippingOptionService from "./custom-shipping-option"
|
import CustomShippingOptionService from "./custom-shipping-option"
|
||||||
import EventBusService from "./event-bus"
|
import EventBusService from "./event-bus"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { ShippingProfileService } from "."
|
import { ShippingProfileService } from "."
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
FulfillmentItemPartition,
|
FulfillmentItemPartition,
|
||||||
FulFillmentItemType,
|
FulFillmentItemType,
|
||||||
} from "../types/fulfillment"
|
} from "../types/fulfillment"
|
||||||
import { buildQuery, isDefined } from "../utils"
|
import { buildQuery } from "../utils"
|
||||||
import FulfillmentProviderService from "./fulfillment-provider"
|
import FulfillmentProviderService from "./fulfillment-provider"
|
||||||
import LineItemService from "./line-item"
|
import LineItemService from "./line-item"
|
||||||
import TotalsService from "./totals"
|
import TotalsService from "./totals"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import randomize from "randomatic"
|
import randomize from "randomatic"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { EventBusService } from "."
|
import { EventBusService } from "."
|
||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
CreateGiftCardTransactionInput,
|
CreateGiftCardTransactionInput,
|
||||||
UpdateGiftCardInput,
|
UpdateGiftCardInput,
|
||||||
} from "../types/gift-card"
|
} from "../types/gift-card"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import RegionService from "./region"
|
import RegionService from "./region"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { v4 } from "uuid"
|
import { v4 } from "uuid"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { DeepPartial, EntityManager } from "typeorm"
|
import { DeepPartial, EntityManager } from "typeorm"
|
||||||
@@ -8,7 +8,6 @@ import {
|
|||||||
CreateIdempotencyKeyInput,
|
CreateIdempotencyKeyInput,
|
||||||
IdempotencyCallbackResult,
|
IdempotencyCallbackResult,
|
||||||
} from "../types/idempotency-key"
|
} from "../types/idempotency-key"
|
||||||
import { isDefined } from "../utils"
|
|
||||||
|
|
||||||
const KEY_LOCKED_TIMEOUT = 1000
|
const KEY_LOCKED_TIMEOUT = 1000
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import ProductVariantService from "./product-variant"
|
import ProductVariantService from "./product-variant"
|
||||||
import { ProductVariant } from "../models"
|
import { ProductVariant } from "../models"
|
||||||
import { isDefined } from "../utils"
|
|
||||||
|
|
||||||
type InventoryServiceProps = {
|
type InventoryServiceProps = {
|
||||||
manager: EntityManager
|
manager: EntityManager
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager, In } from "typeorm"
|
import { EntityManager, In } from "typeorm"
|
||||||
|
|
||||||
import { Cart, DiscountRuleType, LineItem, LineItemAdjustment } from "../models"
|
import { Cart, DiscountRuleType, LineItem, LineItemAdjustment } from "../models"
|
||||||
@@ -7,7 +7,7 @@ import { FindConfig } from "../types/common"
|
|||||||
import { FilterableLineItemAdjustmentProps } from "../types/line-item-adjustment"
|
import { FilterableLineItemAdjustmentProps } from "../types/line-item-adjustment"
|
||||||
import DiscountService from "./discount"
|
import DiscountService from "./discount"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import { CalculationContextData } from "../types/totals"
|
import { CalculationContextData } from "../types/totals"
|
||||||
|
|
||||||
type LineItemAdjustmentServiceProps = {
|
type LineItemAdjustmentServiceProps = {
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ import { TaxProviderService } from "./index"
|
|||||||
import { LineAllocationsMap } from "../types/totals"
|
import { LineAllocationsMap } from "../types/totals"
|
||||||
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
import { calculatePriceTaxAmount, isDefined } from "../utils"
|
import { calculatePriceTaxAmount } from "../utils"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
|
|
||||||
type LineItemTotals = {
|
type LineItemTotals = {
|
||||||
unit_price: number
|
unit_price: number
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { NoteRepository } from "../repositories/note"
|
import { NoteRepository } from "../repositories/note"
|
||||||
import EventBusService from "./event-bus"
|
import EventBusService from "./event-bus"
|
||||||
import { FindConfig, Selector } from "../types/common"
|
import { FindConfig, Selector } from "../types/common"
|
||||||
import { Note } from "../models"
|
import { Note } from "../models"
|
||||||
import { buildQuery, isDefined } from "../utils"
|
import { buildQuery } from "../utils"
|
||||||
import { CreateNoteInput } from "../types/note"
|
import { CreateNoteInput } from "../types/note"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { Oauth as OAuthModel } from "../models"
|
import { Oauth as OAuthModel } from "../models"
|
||||||
@@ -6,7 +6,7 @@ import { OauthRepository } from "../repositories/oauth"
|
|||||||
import { Selector } from "../types/common"
|
import { Selector } from "../types/common"
|
||||||
import { MedusaContainer } from "../types/global"
|
import { MedusaContainer } from "../types/global"
|
||||||
import { CreateOauthInput, UpdateOauthInput } from "../types/oauth"
|
import { CreateOauthInput, UpdateOauthInput } from "../types/oauth"
|
||||||
import { buildQuery, isDefined } from "../utils"
|
import { buildQuery } from "../utils"
|
||||||
import EventBusService from "./event-bus"
|
import EventBusService from "./event-bus"
|
||||||
|
|
||||||
type InjectedDependencies = MedusaContainer & {
|
type InjectedDependencies = MedusaContainer & {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { DeepPartial, EntityManager, ILike, IsNull } from "typeorm"
|
import { DeepPartial, EntityManager, ILike, IsNull } from "typeorm"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
|
|
||||||
import { FindConfig, Selector } from "../types/common"
|
import { FindConfig, Selector } from "../types/common"
|
||||||
import { buildQuery, isDefined, isString } from "../utils"
|
import { buildQuery, isString } from "../utils"
|
||||||
import { OrderEditRepository } from "../repositories/order-edit"
|
import { OrderEditRepository } from "../repositories/order-edit"
|
||||||
import {
|
import {
|
||||||
Cart,
|
Cart,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import jwt, { JwtPayload } from "jsonwebtoken"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
|
||||||
import { Brackets, EntityManager } from "typeorm"
|
import { Brackets, EntityManager } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
|
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
|
||||||
@@ -28,7 +27,7 @@ import {
|
|||||||
} from "../types/fulfillment"
|
} from "../types/fulfillment"
|
||||||
import { UpdateOrderInput } from "../types/orders"
|
import { UpdateOrderInput } from "../types/orders"
|
||||||
import { CreateShippingMethodDto } from "../types/shipping-options"
|
import { CreateShippingMethodDto } from "../types/shipping-options"
|
||||||
import { buildQuery, isDefined, isString, setMetadata } from "../utils"
|
import { buildQuery, isString, setMetadata } from "../utils"
|
||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
import CartService from "./cart"
|
import CartService from "./cart"
|
||||||
import CustomerService from "./customer"
|
import CustomerService from "./customer"
|
||||||
@@ -46,8 +45,6 @@ import ShippingOptionService from "./shipping-option"
|
|||||||
import ShippingProfileService from "./shipping-profile"
|
import ShippingProfileService from "./shipping-profile"
|
||||||
import TotalsService from "./totals"
|
import TotalsService from "./totals"
|
||||||
import { NewTotalsService, TaxProviderService } from "./index"
|
import { NewTotalsService, TaxProviderService } from "./index"
|
||||||
import { ConfigModule } from "../types/global"
|
|
||||||
import logger from "../loaders/logger"
|
|
||||||
|
|
||||||
export const ORDER_CART_ALREADY_EXISTS_ERROR = "Order from cart already exists"
|
export const ORDER_CART_ALREADY_EXISTS_ERROR = "Order from cart already exists"
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { DeepPartial, EntityManager } from "typeorm"
|
import { DeepPartial, EntityManager } from "typeorm"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
|
|
||||||
import { FindConfig } from "../types/common"
|
import { FindConfig } from "../types/common"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import { PaymentCollectionRepository } from "../repositories/payment-collection"
|
import { PaymentCollectionRepository } from "../repositories/payment-collection"
|
||||||
import {
|
import {
|
||||||
PaymentCollection,
|
PaymentCollection,
|
||||||
@@ -21,8 +21,8 @@ import {
|
|||||||
CreatePaymentCollectionInput,
|
CreatePaymentCollectionInput,
|
||||||
PaymentCollectionsSessionsBatchInput,
|
PaymentCollectionsSessionsBatchInput,
|
||||||
PaymentCollectionsSessionsInput,
|
PaymentCollectionsSessionsInput,
|
||||||
PaymentProviderDataInput,
|
|
||||||
} from "../types/payment-collection"
|
} from "../types/payment-collection"
|
||||||
|
import { CreatePaymentInput, PaymentSessionInput } from "../types/payment"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
manager: EntityManager
|
manager: EntityManager
|
||||||
@@ -194,10 +194,10 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
[
|
![
|
||||||
PaymentCollectionStatus.CANCELED,
|
PaymentCollectionStatus.CANCELED,
|
||||||
PaymentCollectionStatus.NOT_PAID,
|
PaymentCollectionStatus.NOT_PAID,
|
||||||
].includes(paymentCollection.status) === false
|
].includes(paymentCollection.status)
|
||||||
) {
|
) {
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
MedusaError.Types.NOT_ALLOWED,
|
MedusaError.Types.NOT_ALLOWED,
|
||||||
@@ -251,10 +251,14 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionsInput = sessionsInput.filter((session) => {
|
const payColRegionProviderMap = new Map(
|
||||||
return !!payCol.region.payment_providers.find(({ id }) => {
|
payCol.region.payment_providers.map((provider) => {
|
||||||
return id === session.provider_id
|
return [provider.id, provider]
|
||||||
})
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
sessionsInput = sessionsInput.filter((session) => {
|
||||||
|
return !!payColRegionProviderMap.get(session.provider_id)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!this.isValidTotalAmount(payCol.amount, sessionsInput)) {
|
if (!this.isValidTotalAmount(payCol.amount, sessionsInput)) {
|
||||||
@@ -273,15 +277,30 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
})
|
})
|
||||||
.catch(() => null)
|
.catch(() => null)
|
||||||
|
|
||||||
|
const payColSessionMap = new Map(
|
||||||
|
(payCol.payment_sessions ?? []).map((session) => {
|
||||||
|
return [session.id, session]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const paymentProviderTx =
|
||||||
|
this.paymentProviderService_.withTransaction(manager)
|
||||||
|
|
||||||
const selectedSessionIds: string[] = []
|
const selectedSessionIds: string[] = []
|
||||||
const paymentSessions: PaymentSession[] = []
|
const paymentSessions: PaymentSession[] = []
|
||||||
|
|
||||||
for (const session of sessionsInput) {
|
for (const session of sessionsInput) {
|
||||||
const existingSession = payCol.payment_sessions?.find(
|
const existingSession =
|
||||||
(sess) => session.session_id === sess?.id
|
session.session_id && payColSessionMap.get(session.session_id)
|
||||||
)
|
|
||||||
|
|
||||||
const inputData: PaymentProviderDataInput = {
|
const inputData: PaymentSessionInput = {
|
||||||
|
cart: {
|
||||||
|
email: customer?.email || "",
|
||||||
|
context: {},
|
||||||
|
shipping_methods: [],
|
||||||
|
shipping_address: null,
|
||||||
|
id: "",
|
||||||
|
},
|
||||||
resource_id: payCol.id,
|
resource_id: payCol.id,
|
||||||
currency_code: payCol.currency_code,
|
currency_code: payCol.currency_code,
|
||||||
amount: session.amount,
|
amount: session.amount,
|
||||||
@@ -289,21 +308,19 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
customer,
|
customer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let paymentSession
|
||||||
|
|
||||||
if (existingSession) {
|
if (existingSession) {
|
||||||
const paymentSession = await this.paymentProviderService_
|
paymentSession = await paymentProviderTx.updateSession(
|
||||||
.withTransaction(manager)
|
existingSession,
|
||||||
.updateSessionNew(existingSession, inputData)
|
inputData
|
||||||
|
)
|
||||||
selectedSessionIds.push(existingSession.id)
|
|
||||||
paymentSessions.push(paymentSession)
|
|
||||||
} else {
|
} else {
|
||||||
const paymentSession = await this.paymentProviderService_
|
paymentSession = await paymentProviderTx.createSession(inputData)
|
||||||
.withTransaction(manager)
|
|
||||||
.createSessionNew(inputData)
|
|
||||||
|
|
||||||
selectedSessionIds.push(paymentSession.id)
|
|
||||||
paymentSessions.push(paymentSession)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectedSessionIds.push(paymentSession.id)
|
||||||
|
paymentSessions.push(paymentSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payCol.payment_sessions?.length) {
|
if (payCol.payment_sessions?.length) {
|
||||||
@@ -312,15 +329,16 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (removeSessions.length) {
|
if (removeSessions.length) {
|
||||||
await paymentCollectionRepository.deleteMultiple(
|
await paymentCollectionRepository.delete(
|
||||||
removeSessions.map((sess) => sess.id)
|
removeSessions.map((sess) => sess.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const paymentProviderTx =
|
||||||
|
this.paymentProviderService_.withTransaction(manager)
|
||||||
|
|
||||||
Promise.all(
|
Promise.all(
|
||||||
removeSessions.map(async (sess) =>
|
removeSessions.map(async (sess) =>
|
||||||
this.paymentProviderService_
|
paymentProviderTx.deleteSession(sess)
|
||||||
.withTransaction(manager)
|
|
||||||
.deleteSessionNew(sess)
|
|
||||||
)
|
)
|
||||||
).catch(() => void 0)
|
).catch(() => void 0)
|
||||||
}
|
}
|
||||||
@@ -335,7 +353,7 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
/**
|
/**
|
||||||
* Manages a single payment sessions of a payment collection.
|
* Manages a single payment sessions of a payment collection.
|
||||||
* @param paymentCollectionId - the id of the payment collection
|
* @param paymentCollectionId - the id of the payment collection
|
||||||
* @param sessionsInput - object containing payment session info
|
* @param sessionInput - object containing payment session info
|
||||||
* @param customerId - the id of the customer
|
* @param customerId - the id of the customer
|
||||||
* @return the payment collection and its payment session.
|
* @return the payment collection and its payment session.
|
||||||
*/
|
*/
|
||||||
@@ -381,7 +399,15 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
.catch(() => null)
|
.catch(() => null)
|
||||||
|
|
||||||
const paymentSessions: PaymentSession[] = []
|
const paymentSessions: PaymentSession[] = []
|
||||||
const inputData: PaymentProviderDataInput = {
|
|
||||||
|
const inputData: PaymentSessionInput = {
|
||||||
|
cart: {
|
||||||
|
email: customer?.email || "",
|
||||||
|
context: {},
|
||||||
|
shipping_methods: [],
|
||||||
|
shipping_address: null,
|
||||||
|
id: "",
|
||||||
|
},
|
||||||
resource_id: payCol.id,
|
resource_id: payCol.id,
|
||||||
currency_code: payCol.currency_code,
|
currency_code: payCol.currency_code,
|
||||||
amount: payCol.amount,
|
amount: payCol.amount,
|
||||||
@@ -396,13 +422,13 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
if (existingSession) {
|
if (existingSession) {
|
||||||
const paymentSession = await this.paymentProviderService_
|
const paymentSession = await this.paymentProviderService_
|
||||||
.withTransaction(manager)
|
.withTransaction(manager)
|
||||||
.updateSessionNew(existingSession, inputData)
|
.updateSession(existingSession, inputData)
|
||||||
|
|
||||||
paymentSessions.push(paymentSession)
|
paymentSessions.push(paymentSession)
|
||||||
} else {
|
} else {
|
||||||
const paymentSession = await this.paymentProviderService_
|
const paymentSession = await this.paymentProviderService_
|
||||||
.withTransaction(manager)
|
.withTransaction(manager)
|
||||||
.createSessionNew(inputData)
|
.createSession(inputData)
|
||||||
|
|
||||||
paymentSessions.push(paymentSession)
|
paymentSessions.push(paymentSession)
|
||||||
|
|
||||||
@@ -411,15 +437,16 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (removeSessions.length) {
|
if (removeSessions.length) {
|
||||||
await paymentCollectionRepository.deleteMultiple(
|
await paymentCollectionRepository.delete(
|
||||||
removeSessions.map((sess) => sess.id)
|
removeSessions.map((sess) => sess.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const paymentProviderTx =
|
||||||
|
this.paymentProviderService_.withTransaction(manager)
|
||||||
|
|
||||||
Promise.all(
|
Promise.all(
|
||||||
removeSessions.map(async (sess) =>
|
removeSessions.map(async (sess) =>
|
||||||
this.paymentProviderService_
|
paymentProviderTx.deleteSession(sess)
|
||||||
.withTransaction(manager)
|
|
||||||
.deleteSessionNew(sess)
|
|
||||||
)
|
)
|
||||||
).catch(() => void 0)
|
).catch(() => void 0)
|
||||||
}
|
}
|
||||||
@@ -487,7 +514,14 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
})
|
})
|
||||||
.catch(() => null)
|
.catch(() => null)
|
||||||
|
|
||||||
const inputData: PaymentProviderDataInput = {
|
const inputData: PaymentSessionInput = {
|
||||||
|
cart: {
|
||||||
|
email: customer?.email || "",
|
||||||
|
context: {},
|
||||||
|
shipping_methods: [],
|
||||||
|
shipping_address: null,
|
||||||
|
id: "",
|
||||||
|
},
|
||||||
resource_id: payCol.id,
|
resource_id: payCol.id,
|
||||||
currency_code: payCol.currency_code,
|
currency_code: payCol.currency_code,
|
||||||
amount: session.amount,
|
amount: session.amount,
|
||||||
@@ -497,7 +531,7 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
|
|
||||||
const sessionRefreshed = await this.paymentProviderService_
|
const sessionRefreshed = await this.paymentProviderService_
|
||||||
.withTransaction(manager)
|
.withTransaction(manager)
|
||||||
.refreshSessionNew(session, inputData)
|
.refreshSession(session, inputData)
|
||||||
|
|
||||||
payCol.payment_sessions = payCol.payment_sessions.map((sess) => {
|
payCol.payment_sessions = payCol.payment_sessions.map((sess) => {
|
||||||
if (sess.id === sessionId) {
|
if (sess.id === sessionId) {
|
||||||
@@ -581,6 +615,9 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const paymentProviderTx =
|
||||||
|
this.paymentProviderService_.withTransaction(manager)
|
||||||
|
|
||||||
let authorizedAmount = 0
|
let authorizedAmount = 0
|
||||||
for (let i = 0; i < payCol.payment_sessions.length; i++) {
|
for (let i = 0; i < payCol.payment_sessions.length; i++) {
|
||||||
const session = payCol.payment_sessions[i]
|
const session = payCol.payment_sessions[i]
|
||||||
@@ -594,32 +631,27 @@ export default class PaymentCollectionService extends TransactionBaseService {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const auth = await this.paymentProviderService_
|
const paymentSession = await paymentProviderTx.authorizePayment(
|
||||||
.withTransaction(manager)
|
session,
|
||||||
.authorizePayment(session, context)
|
context
|
||||||
|
)
|
||||||
|
|
||||||
if (auth) {
|
if (paymentSession) {
|
||||||
payCol.payment_sessions[i] = auth
|
payCol.payment_sessions[i] = paymentSession
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auth?.status === PaymentSessionStatus.AUTHORIZED) {
|
if (paymentSession?.status === PaymentSessionStatus.AUTHORIZED) {
|
||||||
authorizedAmount += session.amount
|
authorizedAmount += session.amount
|
||||||
|
|
||||||
const inputData: Omit<PaymentProviderDataInput, "customer"> & {
|
const inputData: CreatePaymentInput = {
|
||||||
payment_session: PaymentSession
|
|
||||||
} = {
|
|
||||||
amount: session.amount,
|
amount: session.amount,
|
||||||
currency_code: payCol.currency_code,
|
currency_code: payCol.currency_code,
|
||||||
provider_id: session.provider_id,
|
provider_id: session.provider_id,
|
||||||
resource_id: payCol.id,
|
resource_id: payCol.id,
|
||||||
payment_session: auth,
|
payment_session: paymentSession,
|
||||||
}
|
}
|
||||||
|
|
||||||
payCol.payments.push(
|
payCol.payments.push(await paymentProviderTx.createPayment(inputData))
|
||||||
await this.paymentProviderService_
|
|
||||||
.withTransaction(manager)
|
|
||||||
.createPaymentNew(inputData)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { BasePaymentService } from "medusa-interfaces"
|
import { BasePaymentService } from "medusa-interfaces"
|
||||||
import { AbstractPaymentService, TransactionBaseService } from "../interfaces"
|
import {
|
||||||
|
AbstractPaymentService,
|
||||||
|
PaymentContext,
|
||||||
|
PaymentSessionResponse,
|
||||||
|
TransactionBaseService,
|
||||||
|
} from "../interfaces"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { PaymentSessionRepository } from "../repositories/payment-session"
|
import { PaymentSessionRepository } from "../repositories/payment-session"
|
||||||
import { PaymentRepository } from "../repositories/payment"
|
import { PaymentRepository } from "../repositories/payment"
|
||||||
import { RefundRepository } from "../repositories/refund"
|
import { RefundRepository } from "../repositories/refund"
|
||||||
import { PaymentProviderRepository } from "../repositories/payment-provider"
|
import { PaymentProviderRepository } from "../repositories/payment-provider"
|
||||||
import { buildQuery } from "../utils"
|
import { buildQuery, isString } from "../utils"
|
||||||
import { FindConfig, Selector } from "../types/common"
|
import { FindConfig, Selector } from "../types/common"
|
||||||
import {
|
import {
|
||||||
Cart,
|
Cart,
|
||||||
@@ -16,11 +21,12 @@ import {
|
|||||||
PaymentSessionStatus,
|
PaymentSessionStatus,
|
||||||
Refund,
|
Refund,
|
||||||
} from "../models"
|
} from "../models"
|
||||||
import { PaymentProviderDataInput } from "../types/payment-collection"
|
|
||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
import OrderEditingFeatureFlag from "../loaders/feature-flags/order-editing"
|
import OrderEditingFeatureFlag from "../loaders/feature-flags/order-editing"
|
||||||
import PaymentService from "./payment"
|
import PaymentService from "./payment"
|
||||||
import { Logger } from "../types/global"
|
import { Logger } from "../types/global"
|
||||||
|
import { CreatePaymentInput, PaymentSessionInput } from "../types/payment"
|
||||||
|
import { CustomerService } from "./index"
|
||||||
|
|
||||||
type PaymentProviderKey = `pp_${string}` | "systemPaymentProviderService"
|
type PaymentProviderKey = `pp_${string}` | "systemPaymentProviderService"
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
@@ -30,6 +36,7 @@ type InjectedDependencies = {
|
|||||||
paymentRepository: typeof PaymentRepository
|
paymentRepository: typeof PaymentRepository
|
||||||
refundRepository: typeof RefundRepository
|
refundRepository: typeof RefundRepository
|
||||||
paymentService: PaymentService
|
paymentService: PaymentService
|
||||||
|
customerService: CustomerService
|
||||||
featureFlagRouter: FlagRouter
|
featureFlagRouter: FlagRouter
|
||||||
logger: Logger
|
logger: Logger
|
||||||
} & {
|
} & {
|
||||||
@@ -50,6 +57,7 @@ export default class PaymentProviderService extends TransactionBaseService {
|
|||||||
protected readonly paymentProviderRepository_: typeof PaymentProviderRepository
|
protected readonly paymentProviderRepository_: typeof PaymentProviderRepository
|
||||||
protected readonly paymentRepository_: typeof PaymentRepository
|
protected readonly paymentRepository_: typeof PaymentRepository
|
||||||
protected readonly refundRepository_: typeof RefundRepository
|
protected readonly refundRepository_: typeof RefundRepository
|
||||||
|
protected readonly customerService_: CustomerService
|
||||||
protected readonly logger_: Logger
|
protected readonly logger_: Logger
|
||||||
|
|
||||||
protected readonly featureFlagRouter_: FlagRouter
|
protected readonly featureFlagRouter_: FlagRouter
|
||||||
@@ -63,6 +71,7 @@ export default class PaymentProviderService extends TransactionBaseService {
|
|||||||
this.paymentProviderRepository_ = container.paymentProviderRepository
|
this.paymentProviderRepository_ = container.paymentProviderRepository
|
||||||
this.paymentRepository_ = container.paymentRepository
|
this.paymentRepository_ = container.paymentRepository
|
||||||
this.refundRepository_ = container.refundRepository
|
this.refundRepository_ = container.refundRepository
|
||||||
|
this.customerService_ = container.customerService
|
||||||
this.featureFlagRouter_ = container.featureFlagRouter
|
this.featureFlagRouter_ = container.featureFlagRouter
|
||||||
this.logger_ = container.logger
|
this.logger_ = container.logger
|
||||||
}
|
}
|
||||||
@@ -165,55 +174,59 @@ export default class PaymentProviderService extends TransactionBaseService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a payment session with the given provider.
|
* Creates a payment session with the given provider.
|
||||||
* @param providerId - the id of the provider to create payment with
|
* @param providerIdOrSessionInput - the id of the provider to create payment with or the input data
|
||||||
* @param cart - a cart object used to calculate the amount, etc. from
|
* @param cart - a cart object used to calculate the amount, etc. from
|
||||||
* @return the payment session
|
* @return the payment session
|
||||||
*/
|
*/
|
||||||
async createSession(providerId: string, cart: Cart): Promise<PaymentSession> {
|
async createSession<
|
||||||
return await this.atomicPhase_(async (transactionManager) => {
|
TInput extends string | PaymentSessionInput = string | PaymentSessionInput
|
||||||
const provider = this.retrieveProvider(providerId)
|
>(
|
||||||
const sessionData = await provider
|
providerIdOrSessionInput: TInput,
|
||||||
.withTransaction(transactionManager)
|
...[cart]: TInput extends string ? [Cart] : [never?]
|
||||||
.createPayment(cart)
|
|
||||||
|
|
||||||
const sessionRepo = transactionManager.getCustomRepository(
|
|
||||||
this.paymentSessionRepository_
|
|
||||||
)
|
|
||||||
|
|
||||||
const toCreate = {
|
|
||||||
cart_id: cart.id,
|
|
||||||
provider_id: providerId,
|
|
||||||
data: sessionData,
|
|
||||||
status: "pending",
|
|
||||||
}
|
|
||||||
|
|
||||||
const created = sessionRepo.create(toCreate)
|
|
||||||
return await sessionRepo.save(created)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async createSessionNew(
|
|
||||||
sessionInput: PaymentProviderDataInput
|
|
||||||
): Promise<PaymentSession> {
|
): Promise<PaymentSession> {
|
||||||
return await this.atomicPhase_(async (transactionManager) => {
|
return await this.atomicPhase_(async (transactionManager) => {
|
||||||
const provider = this.retrieveProvider(sessionInput.provider_id)
|
const providerId = isString(providerIdOrSessionInput)
|
||||||
const sessionData = await provider
|
? providerIdOrSessionInput
|
||||||
.withTransaction(transactionManager)
|
: providerIdOrSessionInput.provider_id
|
||||||
.createPaymentNew(sessionInput)
|
const data = (
|
||||||
|
isString(providerIdOrSessionInput) ? cart : providerIdOrSessionInput
|
||||||
|
) as Cart | PaymentSessionInput
|
||||||
|
|
||||||
const sessionRepo = transactionManager.getCustomRepository(
|
const provider = this.retrieveProvider<AbstractPaymentService>(providerId)
|
||||||
this.paymentSessionRepository_
|
const context = this.buildPaymentContext(data)
|
||||||
|
|
||||||
|
if (!isDefined(context.currency_code) || !isDefined(context.amount)) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.INVALID_ARGUMENT,
|
||||||
|
"`currency_code` and `amount` are required to create payment session."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const paymentResponse = await provider
|
||||||
|
.withTransaction(transactionManager)
|
||||||
|
.createPayment(context)
|
||||||
|
|
||||||
|
const sessionData = paymentResponse.session_data ?? paymentResponse
|
||||||
|
|
||||||
|
await this.processUpdateRequestsData(
|
||||||
|
{
|
||||||
|
customer: { id: context.customer?.id },
|
||||||
|
},
|
||||||
|
paymentResponse
|
||||||
)
|
)
|
||||||
|
|
||||||
const toCreate = {
|
const amount = this.featureFlagRouter_.isFeatureEnabled(
|
||||||
provider_id: sessionInput.provider_id,
|
OrderEditingFeatureFlag.key
|
||||||
data: sessionData,
|
)
|
||||||
status: "pending",
|
? context.amount
|
||||||
amount: sessionInput.amount,
|
: undefined
|
||||||
} as PaymentSession
|
|
||||||
|
|
||||||
const created = sessionRepo.create(toCreate)
|
return await this.saveSession(providerId, {
|
||||||
return await sessionRepo.save(created)
|
cartId: context.id,
|
||||||
|
sessionData,
|
||||||
|
status: PaymentSessionStatus.PENDING,
|
||||||
|
amount,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,16 +235,22 @@ export default class PaymentProviderService extends TransactionBaseService {
|
|||||||
* This means, that we delete the current one and create a new.
|
* This means, that we delete the current one and create a new.
|
||||||
* @param paymentSession - the payment session object to
|
* @param paymentSession - the payment session object to
|
||||||
* update
|
* update
|
||||||
* @param cart - a cart object used to calculate the amount, etc. from
|
* @param sessionInput
|
||||||
* @return the payment session
|
* @return the payment session
|
||||||
*/
|
*/
|
||||||
async refreshSession(
|
async refreshSession(
|
||||||
paymentSession: PaymentSession,
|
paymentSession: {
|
||||||
cart: Cart
|
id: string
|
||||||
|
data: Record<string, unknown>
|
||||||
|
provider_id: string
|
||||||
|
},
|
||||||
|
sessionInput: PaymentSessionInput
|
||||||
): Promise<PaymentSession> {
|
): Promise<PaymentSession> {
|
||||||
return this.atomicPhase_(async (transactionManager) => {
|
return this.atomicPhase_(async (transactionManager) => {
|
||||||
const session = await this.retrieveSession(paymentSession.id)
|
const session = await this.retrieveSession(paymentSession.id)
|
||||||
const provider = this.retrieveProvider(paymentSession.provider_id)
|
const provider = this.retrieveProvider<AbstractPaymentService>(
|
||||||
|
paymentSession.provider_id
|
||||||
|
)
|
||||||
await provider.withTransaction(transactionManager).deletePayment(session)
|
await provider.withTransaction(transactionManager).deletePayment(session)
|
||||||
|
|
||||||
const sessionRepo = transactionManager.getCustomRepository(
|
const sessionRepo = transactionManager.getCustomRepository(
|
||||||
@@ -239,88 +258,44 @@ export default class PaymentProviderService extends TransactionBaseService {
|
|||||||
)
|
)
|
||||||
|
|
||||||
await sessionRepo.remove(session)
|
await sessionRepo.remove(session)
|
||||||
|
return await this.createSession(sessionInput)
|
||||||
const sessionData = await provider
|
|
||||||
.withTransaction(transactionManager)
|
|
||||||
.createPayment(cart)
|
|
||||||
|
|
||||||
const toCreate = {
|
|
||||||
cart_id: cart.id,
|
|
||||||
provider_id: session.provider_id,
|
|
||||||
data: sessionData,
|
|
||||||
is_selected: true,
|
|
||||||
status: "pending",
|
|
||||||
}
|
|
||||||
|
|
||||||
const created = sessionRepo.create(toCreate)
|
|
||||||
return await sessionRepo.save(created)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async refreshSessionNew(
|
|
||||||
paymentSession: PaymentSession,
|
|
||||||
sessionInput: PaymentProviderDataInput
|
|
||||||
): Promise<PaymentSession> {
|
|
||||||
return this.atomicPhase_(async (transactionManager) => {
|
|
||||||
const session = await this.retrieveSession(paymentSession.id)
|
|
||||||
const provider = this.retrieveProvider(paymentSession.provider_id)
|
|
||||||
|
|
||||||
await provider.withTransaction(transactionManager).deletePayment(session)
|
|
||||||
|
|
||||||
const sessionRepo = transactionManager.getCustomRepository(
|
|
||||||
this.paymentSessionRepository_
|
|
||||||
)
|
|
||||||
|
|
||||||
await sessionRepo.remove(session)
|
|
||||||
|
|
||||||
return await this.createSessionNew(sessionInput)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an existing payment session.
|
* Update a payment session with the given provider.
|
||||||
* @param paymentSession - the payment session object to
|
* @param paymentSession - The paymentSession to update
|
||||||
* update
|
* @param sessionInput
|
||||||
* @param cart - the cart object to update for
|
* @return the payment session
|
||||||
* @return the updated payment session
|
|
||||||
*/
|
*/
|
||||||
async updateSession(
|
async updateSession(
|
||||||
paymentSession: PaymentSession,
|
paymentSession: {
|
||||||
cart: Cart
|
id: string
|
||||||
|
data: Record<string, unknown>
|
||||||
|
provider_id: string
|
||||||
|
},
|
||||||
|
sessionInput: Cart | PaymentSessionInput
|
||||||
): Promise<PaymentSession> {
|
): Promise<PaymentSession> {
|
||||||
return await this.atomicPhase_(async (transactionManager) => {
|
return await this.atomicPhase_(async (transactionManager) => {
|
||||||
const session = await this.retrieveSession(paymentSession.id)
|
|
||||||
const provider = this.retrieveProvider(paymentSession.provider_id)
|
|
||||||
session.data = await provider
|
|
||||||
.withTransaction(transactionManager)
|
|
||||||
.updatePayment(paymentSession.data, cart)
|
|
||||||
|
|
||||||
const sessionRepo = transactionManager.getCustomRepository(
|
|
||||||
this.paymentSessionRepository_
|
|
||||||
)
|
|
||||||
return await sessionRepo.save(session)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateSessionNew(
|
|
||||||
paymentSession: PaymentSession,
|
|
||||||
sessionInput: PaymentProviderDataInput
|
|
||||||
): Promise<PaymentSession> {
|
|
||||||
return await this.atomicPhase_(async (transactionManager) => {
|
|
||||||
const session = await this.retrieveSession(paymentSession.id)
|
|
||||||
const provider = this.retrieveProvider(paymentSession.provider_id)
|
const provider = this.retrieveProvider(paymentSession.provider_id)
|
||||||
|
|
||||||
session.amount = sessionInput.amount
|
const context = this.buildPaymentContext(sessionInput)
|
||||||
paymentSession.data.amount = sessionInput.amount
|
|
||||||
session.data = await provider
|
const sessionData = await provider
|
||||||
.withTransaction(transactionManager)
|
.withTransaction(transactionManager)
|
||||||
.updatePaymentNew(paymentSession.data, sessionInput)
|
.updatePayment(paymentSession.data, context)
|
||||||
|
|
||||||
const sessionRepo = transactionManager.getCustomRepository(
|
const amount = this.featureFlagRouter_.isFeatureEnabled(
|
||||||
this.paymentSessionRepository_
|
OrderEditingFeatureFlag.key
|
||||||
)
|
)
|
||||||
|
? context.amount
|
||||||
|
: undefined
|
||||||
|
|
||||||
return await sessionRepo.save(session)
|
return await this.saveSession(paymentSession.provider_id, {
|
||||||
|
payment_session_id: paymentSession.id,
|
||||||
|
sessionData,
|
||||||
|
amount,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,15 +324,6 @@ export default class PaymentProviderService extends TransactionBaseService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteSessionNew(paymentSession: PaymentSession): Promise<void> {
|
|
||||||
return await this.atomicPhase_(async (transactionManager) => {
|
|
||||||
const provider = this.retrieveProvider(paymentSession.provider_id)
|
|
||||||
return await provider
|
|
||||||
.withTransaction(transactionManager)
|
|
||||||
.deletePayment(paymentSession)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a provider given an id
|
* Finds a provider given an id
|
||||||
* @param {string} providerId - the id of the provider to get
|
* @param {string} providerId - the id of the provider to get
|
||||||
@@ -387,26 +353,22 @@ export default class PaymentProviderService extends TransactionBaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async createPayment(data: {
|
async createPayment(data: CreatePaymentInput): Promise<Payment> {
|
||||||
cart_id: string
|
|
||||||
amount: number
|
|
||||||
currency_code: string
|
|
||||||
payment_session: PaymentSession
|
|
||||||
}): Promise<Payment> {
|
|
||||||
return await this.atomicPhase_(async (transactionManager) => {
|
return await this.atomicPhase_(async (transactionManager) => {
|
||||||
const { payment_session: paymentSession, currency_code, amount } = data
|
const { payment_session, currency_code, amount, provider_id } = data
|
||||||
|
const providerId = provider_id ?? payment_session.provider_id
|
||||||
|
|
||||||
const provider = this.retrieveProvider(paymentSession.provider_id)
|
const provider = this.retrieveProvider<AbstractPaymentService>(providerId)
|
||||||
const paymentData = await provider
|
const paymentData = await provider
|
||||||
.withTransaction(transactionManager)
|
.withTransaction(transactionManager)
|
||||||
.getPaymentData(paymentSession)
|
.getPaymentData(payment_session)
|
||||||
|
|
||||||
const paymentRepo = transactionManager.getCustomRepository(
|
const paymentRepo = transactionManager.getCustomRepository(
|
||||||
this.paymentRepository_
|
this.paymentRepository_
|
||||||
)
|
)
|
||||||
|
|
||||||
const created = paymentRepo.create({
|
const created = paymentRepo.create({
|
||||||
provider_id: paymentSession.provider_id,
|
provider_id: providerId,
|
||||||
amount,
|
amount,
|
||||||
currency_code,
|
currency_code,
|
||||||
data: paymentData,
|
data: paymentData,
|
||||||
@@ -417,30 +379,6 @@ export default class PaymentProviderService extends TransactionBaseService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async createPaymentNew(
|
|
||||||
paymentInput: Omit<PaymentProviderDataInput, "customer"> & {
|
|
||||||
payment_session: PaymentSession
|
|
||||||
}
|
|
||||||
): Promise<Payment> {
|
|
||||||
return await this.atomicPhase_(async (transactionManager) => {
|
|
||||||
const { payment_session, currency_code, amount, provider_id } =
|
|
||||||
paymentInput
|
|
||||||
|
|
||||||
const provider = this.retrieveProvider(provider_id)
|
|
||||||
const paymentData = await provider
|
|
||||||
.withTransaction(transactionManager)
|
|
||||||
.getPaymentData(payment_session)
|
|
||||||
|
|
||||||
const paymentService = this.container_.paymentService
|
|
||||||
return await paymentService.withTransaction(transactionManager).create({
|
|
||||||
provider_id,
|
|
||||||
amount,
|
|
||||||
currency_code,
|
|
||||||
data: paymentData,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async updatePayment(
|
async updatePayment(
|
||||||
paymentId: string,
|
paymentId: string,
|
||||||
data: { order_id?: string; swap_id?: string }
|
data: { order_id?: string; swap_id?: string }
|
||||||
@@ -696,4 +634,123 @@ export default class PaymentProviderService extends TransactionBaseService {
|
|||||||
|
|
||||||
return refund
|
return refund
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the create session context for both legacy and new API
|
||||||
|
* @param cartOrData
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
protected buildPaymentContext(
|
||||||
|
cartOrData: Cart | PaymentSessionInput
|
||||||
|
): Cart & PaymentContext {
|
||||||
|
const cart =
|
||||||
|
"object" in cartOrData && cartOrData.object === "cart"
|
||||||
|
? cartOrData
|
||||||
|
: ((cartOrData as PaymentSessionInput).cart as Cart)
|
||||||
|
|
||||||
|
const context = {} as Cart & PaymentContext
|
||||||
|
|
||||||
|
// TODO: only to support legacy API. Once we are ready to break the API, the cartOrData will only support PaymentSessionInput
|
||||||
|
if ("object" in cartOrData && cartOrData.object === "cart") {
|
||||||
|
context.cart = {
|
||||||
|
context: cart.context,
|
||||||
|
shipping_address: cart.shipping_address,
|
||||||
|
id: cart.id,
|
||||||
|
email: cart.email,
|
||||||
|
shipping_methods: cart.shipping_methods,
|
||||||
|
}
|
||||||
|
context.amount = cart.total!
|
||||||
|
context.currency_code = cart.region?.currency_code
|
||||||
|
Object.assign(context, cart)
|
||||||
|
} else {
|
||||||
|
const data = cartOrData as PaymentSessionInput
|
||||||
|
context.cart = data.cart
|
||||||
|
context.amount = data.amount
|
||||||
|
context.currency_code = data.currency_code
|
||||||
|
Object.assign(context, cart)
|
||||||
|
}
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create or update a Payment session data.
|
||||||
|
* @param providerId
|
||||||
|
* @param data
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
protected async saveSession(
|
||||||
|
providerId: string,
|
||||||
|
data: {
|
||||||
|
payment_session_id?: string
|
||||||
|
cartId?: string
|
||||||
|
amount?: number
|
||||||
|
sessionData: Record<string, unknown>
|
||||||
|
isSelected?: boolean
|
||||||
|
status?: PaymentSessionStatus
|
||||||
|
}
|
||||||
|
): Promise<PaymentSession> {
|
||||||
|
const manager = this.transactionManager_ ?? this.manager_
|
||||||
|
|
||||||
|
if (
|
||||||
|
data.amount != null &&
|
||||||
|
!this.featureFlagRouter_.isFeatureEnabled(OrderEditingFeatureFlag.key)
|
||||||
|
) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.INVALID_ARGUMENT,
|
||||||
|
"Amount on payment sessions is only available with the OrderEditing API currently guarded by feature flag `MEDUSA_FF_ORDER_EDITING`. Read more about feature flags here: https://docs.medusajs.com/advanced/backend/feature-flags/toggle/"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionRepo = manager.getCustomRepository(
|
||||||
|
this.paymentSessionRepository_
|
||||||
|
)
|
||||||
|
|
||||||
|
if (data.payment_session_id) {
|
||||||
|
const session = await this.retrieveSession(data.payment_session_id)
|
||||||
|
session.data = data.sessionData ?? session.data
|
||||||
|
session.status = data.status ?? session.status
|
||||||
|
session.amount = data.amount ?? session.amount
|
||||||
|
return await sessionRepo.save(session)
|
||||||
|
} else {
|
||||||
|
const toCreate: Partial<PaymentSession> = {
|
||||||
|
cart_id: data.cartId || null,
|
||||||
|
provider_id: providerId,
|
||||||
|
data: data.sessionData,
|
||||||
|
is_selected: data.isSelected,
|
||||||
|
status: data.status,
|
||||||
|
amount: data.amount,
|
||||||
|
}
|
||||||
|
|
||||||
|
const created = sessionRepo.create(toCreate)
|
||||||
|
return await sessionRepo.save(created)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the collected data. Can be used every time we need to process some collected data returned by the provider
|
||||||
|
* @param data
|
||||||
|
* @param paymentResponse
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
protected async processUpdateRequestsData(
|
||||||
|
data: { customer?: { id?: string } } = {},
|
||||||
|
paymentResponse: PaymentSessionResponse | Record<string, unknown>
|
||||||
|
): Promise<void> {
|
||||||
|
const { update_requests } = paymentResponse as PaymentSessionResponse
|
||||||
|
|
||||||
|
if (!update_requests) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const manager = this.transactionManager_ ?? this.manager_
|
||||||
|
|
||||||
|
if (update_requests.customer_metadata && data.customer?.id) {
|
||||||
|
await this.customerService_
|
||||||
|
.withTransaction(manager)
|
||||||
|
.update(data.customer.id, {
|
||||||
|
metadata: update_requests.customer_metadata,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { PaymentRepository } from "./../repositories/payment"
|
import { PaymentRepository } from "./../repositories/payment"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
|
|
||||||
import { Payment, Refund } from "../models"
|
import { Payment, Refund } from "../models"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { EventBusService, PaymentProviderService } from "./index"
|
import { EventBusService, PaymentProviderService } from "./index"
|
||||||
import { buildQuery, isDefined } from "../utils"
|
import { buildQuery } from "../utils"
|
||||||
import { FindConfig } from "../types/common"
|
import { FindConfig } from "../types/common"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { DeepPartial, EntityManager, FindOperator } from "typeorm"
|
import { DeepPartial, EntityManager, FindOperator } from "typeorm"
|
||||||
import { CustomerGroupService } from "."
|
import { CustomerGroupService } from "."
|
||||||
import { CustomerGroup, PriceList, Product, ProductVariant } from "../models"
|
import { CustomerGroup, PriceList, Product, ProductVariant } from "../models"
|
||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
import ProductService from "./product"
|
import ProductService from "./product"
|
||||||
import RegionService from "./region"
|
import RegionService from "./region"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { buildQuery, isDefined } from "../utils"
|
import { buildQuery } from "../utils"
|
||||||
import { FilterableProductProps } from "../types/product"
|
import { FilterableProductProps } from "../types/product"
|
||||||
import ProductVariantService from "./product-variant"
|
import ProductVariantService from "./product-variant"
|
||||||
import { FilterableProductVariantProps } from "../types/product-variant"
|
import { FilterableProductVariantProps } from "../types/product-variant"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { Brackets, EntityManager, ILike } from "typeorm"
|
import { Brackets, EntityManager, ILike } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { ProductCollection } from "../models"
|
import { ProductCollection } from "../models"
|
||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
CreateProductCollection,
|
CreateProductCollection,
|
||||||
UpdateProductCollection,
|
UpdateProductCollection,
|
||||||
} from "../types/product-collection"
|
} from "../types/product-collection"
|
||||||
import { buildQuery, isDefined, isString, setMetadata } from "../utils"
|
import { buildQuery, isString, setMetadata } from "../utils"
|
||||||
import EventBusService from "./event-bus"
|
import EventBusService from "./event-bus"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { Brackets, EntityManager, ILike, SelectQueryBuilder } from "typeorm"
|
import { Brackets, EntityManager, ILike, SelectQueryBuilder } from "typeorm"
|
||||||
import {
|
import {
|
||||||
IPriceSelectionStrategy,
|
IPriceSelectionStrategy,
|
||||||
@@ -29,7 +29,7 @@ import {
|
|||||||
ProductVariantPrice,
|
ProductVariantPrice,
|
||||||
UpdateProductVariantInput,
|
UpdateProductVariantInput,
|
||||||
} from "../types/product-variant"
|
} from "../types/product-variant"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
|
|
||||||
class ProductVariantService extends TransactionBaseService {
|
class ProductVariantService extends TransactionBaseService {
|
||||||
static Events = {
|
static Events = {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
|
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { ProductVariantService, SearchService } from "."
|
import { ProductVariantService, SearchService } from "."
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
@@ -31,7 +31,7 @@ import {
|
|||||||
ProductSelector,
|
ProductSelector,
|
||||||
UpdateProductInput,
|
UpdateProductInput,
|
||||||
} from "../types/product"
|
} from "../types/product"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import EventBusService from "./event-bus"
|
import EventBusService from "./event-bus"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { EntityManager, ILike } from "typeorm"
|
import { EntityManager, ILike } from "typeorm"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
|
|
||||||
import { PublishableApiKeyRepository } from "../repositories/publishable-api-key"
|
import { PublishableApiKeyRepository } from "../repositories/publishable-api-key"
|
||||||
import { FindConfig, Selector } from "../types/common"
|
import { FindConfig, Selector } from "../types/common"
|
||||||
import { PublishableApiKey, SalesChannel } from "../models"
|
import { PublishableApiKey, SalesChannel } from "../models"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import EventBusService from "./event-bus"
|
import EventBusService from "./event-bus"
|
||||||
import { buildQuery, isDefined, isString } from "../utils"
|
import { buildQuery, isString } from "../utils"
|
||||||
import {
|
import {
|
||||||
CreatePublishableApiKeyInput,
|
CreatePublishableApiKeyInput,
|
||||||
UpdatePublishableApiKeyInput,
|
UpdatePublishableApiKeyInput,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { DeepPartial, EntityManager } from "typeorm"
|
import { DeepPartial, EntityManager } from "typeorm"
|
||||||
|
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
|
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
||||||
@@ -13,7 +13,7 @@ import { RegionRepository } from "../repositories/region"
|
|||||||
import { TaxProviderRepository } from "../repositories/tax-provider"
|
import { TaxProviderRepository } from "../repositories/tax-provider"
|
||||||
import { FindConfig, Selector } from "../types/common"
|
import { FindConfig, Selector } from "../types/common"
|
||||||
import { CreateRegionInput, UpdateRegionInput } from "../types/region"
|
import { CreateRegionInput, UpdateRegionInput } from "../types/region"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import { countries } from "../utils/countries"
|
import { countries } from "../utils/countries"
|
||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
import EventBusService from "./event-bus"
|
import EventBusService from "./event-bus"
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { Return, ReturnReason } from "../models"
|
import { ReturnReason } from "../models"
|
||||||
import { ReturnReasonRepository } from "../repositories/return-reason"
|
import { ReturnReasonRepository } from "../repositories/return-reason"
|
||||||
import { FindConfig, Selector } from "../types/common"
|
import { FindConfig, Selector } from "../types/common"
|
||||||
import { CreateReturnReason, UpdateReturnReason } from "../types/return-reason"
|
import { CreateReturnReason, UpdateReturnReason } from "../types/return-reason"
|
||||||
import { buildQuery, isDefined } from "../utils"
|
import { buildQuery } from "../utils"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
manager: EntityManager
|
manager: EntityManager
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { isDefined } from "class-validator"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
|
||||||
import { DeepPartial, EntityManager } from "typeorm"
|
import { DeepPartial, EntityManager } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import { FindConfig, QuerySelector, Selector } from "../types/common"
|
|||||||
|
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import EventBusService from "./event-bus"
|
import EventBusService from "./event-bus"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { SalesChannel } from "../models"
|
import { SalesChannel } from "../models"
|
||||||
import { SalesChannelRepository } from "../repositories/sales-channel"
|
import { SalesChannelRepository } from "../repositories/sales-channel"
|
||||||
import StoreService from "./store"
|
import StoreService from "./store"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { buildQuery, isDefined } from "../utils"
|
import { buildQuery } from "../utils"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
salesChannelRepository: typeof SalesChannelRepository
|
salesChannelRepository: typeof SalesChannelRepository
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
UpdateShippingOptionInput,
|
UpdateShippingOptionInput,
|
||||||
ValidatePriceTypeAndAmountInput,
|
ValidatePriceTypeAndAmountInput,
|
||||||
} from "../types/shipping-options"
|
} from "../types/shipping-options"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
import FulfillmentProviderService from "./fulfillment-provider"
|
import FulfillmentProviderService from "./fulfillment-provider"
|
||||||
import RegionService from "./region"
|
import RegionService from "./region"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import {
|
import {
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
CreateShippingProfile,
|
CreateShippingProfile,
|
||||||
UpdateShippingProfile,
|
UpdateShippingProfile,
|
||||||
} from "../types/shipping-profile"
|
} from "../types/shipping-profile"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import CustomShippingOptionService from "./custom-shipping-option"
|
import CustomShippingOptionService from "./custom-shipping-option"
|
||||||
import ProductService from "./product"
|
import ProductService from "./product"
|
||||||
import ShippingOptionService from "./shipping-option"
|
import ShippingOptionService from "./shipping-option"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
|
|
||||||
import { buildQuery, isDefined, setMetadata, validateId } from "../utils"
|
import { buildQuery, setMetadata, validateId } from "../utils"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
|
|
||||||
import LineItemAdjustmentService from "./line-item-adjustment"
|
import LineItemAdjustmentService from "./line-item-adjustment"
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { ProductTaxRate } from "../models/product-tax-rate"
|
import {
|
||||||
import { ProductTypeTaxRate } from "../models/product-type-tax-rate"
|
ProductTaxRate,
|
||||||
import { ShippingTaxRate } from "../models/shipping-tax-rate"
|
ProductTypeTaxRate,
|
||||||
import { TaxRate } from "../models/tax-rate"
|
ShippingTaxRate,
|
||||||
|
TaxRate,
|
||||||
|
} from "../models"
|
||||||
import { TaxRateRepository } from "../repositories/tax-rate"
|
import { TaxRateRepository } from "../repositories/tax-rate"
|
||||||
import ProductService from "../services/product"
|
import ProductService from "../services/product"
|
||||||
import ProductTypeService from "../services/product-type"
|
import ProductTypeService from "../services/product-type"
|
||||||
@@ -15,7 +17,7 @@ import {
|
|||||||
TaxRateListByConfig,
|
TaxRateListByConfig,
|
||||||
UpdateTaxRateInput,
|
UpdateTaxRateInput,
|
||||||
} from "../types/tax-rate"
|
} from "../types/tax-rate"
|
||||||
import { buildQuery, isDefined, PostgresError } from "../utils"
|
import { buildQuery, PostgresError } from "../utils"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
import { FindConditions } from "typeorm/find-options/FindConditions"
|
import { FindConditions } from "typeorm/find-options/FindConditions"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import {
|
import {
|
||||||
ITaxCalculationStrategy,
|
ITaxCalculationStrategy,
|
||||||
TaxCalculationContext,
|
TaxCalculationContext,
|
||||||
@@ -28,7 +28,7 @@ import {
|
|||||||
import TaxProviderService from "./tax-provider"
|
import TaxProviderService from "./tax-provider"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
|
|
||||||
import { calculatePriceTaxAmount, isDefined } from "../utils"
|
import { calculatePriceTaxAmount } from "../utils"
|
||||||
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import jwt from "jsonwebtoken"
|
import jwt from "jsonwebtoken"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import Scrypt from "scrypt-kdf"
|
import Scrypt from "scrypt-kdf"
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { TransactionBaseService } from "../interfaces"
|
import { TransactionBaseService } from "../interfaces"
|
||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
FilterableUserProps,
|
FilterableUserProps,
|
||||||
UpdateUserInput,
|
UpdateUserInput,
|
||||||
} from "../types/user"
|
} from "../types/user"
|
||||||
import { buildQuery, isDefined, setMetadata } from "../utils"
|
import { buildQuery, setMetadata } from "../utils"
|
||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
import { validateEmail } from "../utils/is-email"
|
import { validateEmail } from "../utils/is-email"
|
||||||
import AnalyticsConfigService from "./analytics-config"
|
import AnalyticsConfigService from "./analytics-config"
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import {
|
|||||||
PriceSelectionResult,
|
PriceSelectionResult,
|
||||||
PriceType,
|
PriceType,
|
||||||
} from "../interfaces"
|
} from "../interfaces"
|
||||||
|
import { isDefined } from "medusa-core-utils"
|
||||||
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
import TaxInclusivePricingFeatureFlag from "../loaders/feature-flags/tax-inclusive-pricing"
|
||||||
import { MoneyAmountRepository } from "../repositories/money-amount"
|
import { MoneyAmountRepository } from "../repositories/money-amount"
|
||||||
import { TaxServiceRate } from "../types/tax-service"
|
import { TaxServiceRate } from "../types/tax-service"
|
||||||
import { FlagRouter } from "../utils/flag-router"
|
import { FlagRouter } from "../utils/flag-router"
|
||||||
import { isDefined } from "../utils"
|
|
||||||
|
|
||||||
class PriceSelectionStrategy extends AbstractPriceSelectionStrategy {
|
class PriceSelectionStrategy extends AbstractPriceSelectionStrategy {
|
||||||
protected manager_: EntityManager
|
protected manager_: EntityManager
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import EventBusService from "../services/event-bus"
|
||||||
|
import { CartService, PaymentProviderService } from "../services"
|
||||||
|
import { EntityManager } from "typeorm"
|
||||||
|
|
||||||
|
type InjectedDependencies = {
|
||||||
|
eventBusService: EventBusService
|
||||||
|
cartService: CartService
|
||||||
|
paymentProviderService: PaymentProviderService
|
||||||
|
manager: EntityManager
|
||||||
|
}
|
||||||
|
|
||||||
|
class CartSubscriber {
|
||||||
|
protected readonly manager_: EntityManager
|
||||||
|
protected readonly cartService_: CartService
|
||||||
|
protected readonly paymentProviderService_: PaymentProviderService
|
||||||
|
protected readonly eventBus_: EventBusService
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
manager,
|
||||||
|
cartService,
|
||||||
|
paymentProviderService,
|
||||||
|
eventBusService,
|
||||||
|
}: InjectedDependencies) {
|
||||||
|
this.cartService_ = cartService
|
||||||
|
this.paymentProviderService_ = paymentProviderService
|
||||||
|
this.eventBus_ = eventBusService
|
||||||
|
this.manager_ = manager
|
||||||
|
|
||||||
|
this.eventBus_.subscribe(
|
||||||
|
CartService.Events.CUSTOMER_UPDATED,
|
||||||
|
async (cartId) => {
|
||||||
|
await this.onCustomerUpdated(cartId)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async onCustomerUpdated(cartId) {
|
||||||
|
await this.manager_.transaction(
|
||||||
|
"SERIALIZABLE",
|
||||||
|
async (transactionManager) => {
|
||||||
|
const cart = await this.cartService_
|
||||||
|
.withTransaction(transactionManager)
|
||||||
|
.retrieveWithTotals(cartId, {
|
||||||
|
relations: [
|
||||||
|
"billing_address",
|
||||||
|
"region",
|
||||||
|
"region.payment_providers",
|
||||||
|
"payment_sessions",
|
||||||
|
"customer",
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!cart.payment_sessions?.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const paymentProviderServiceTx =
|
||||||
|
this.paymentProviderService_.withTransaction(transactionManager)
|
||||||
|
|
||||||
|
return await Promise.all(
|
||||||
|
cart.payment_sessions.map(async (paymentSession) => {
|
||||||
|
return paymentProviderServiceTx.updateSession(paymentSession, cart)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CartSubscriber
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
import {
|
import { PaymentCollection, PaymentCollectionType } from "../models"
|
||||||
Cart,
|
|
||||||
Customer,
|
|
||||||
PaymentCollection,
|
|
||||||
PaymentCollectionType,
|
|
||||||
} from "../models"
|
|
||||||
|
|
||||||
export type CreatePaymentCollectionInput = {
|
export type CreatePaymentCollectionInput = {
|
||||||
region_id: string
|
region_id: string
|
||||||
@@ -25,15 +20,6 @@ export type PaymentCollectionsSessionsInput = {
|
|||||||
provider_id: string
|
provider_id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PaymentProviderDataInput = {
|
|
||||||
resource_id: string
|
|
||||||
customer: Partial<Customer> | null
|
|
||||||
currency_code: string
|
|
||||||
provider_id: string
|
|
||||||
amount: number
|
|
||||||
cart_id?: string
|
|
||||||
cart?: Cart
|
|
||||||
}
|
|
||||||
export const defaultPaymentCollectionRelations = [
|
export const defaultPaymentCollectionRelations = [
|
||||||
"region",
|
"region",
|
||||||
"region.payment_providers",
|
"region.payment_providers",
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import {
|
||||||
|
Address,
|
||||||
|
Cart,
|
||||||
|
Customer,
|
||||||
|
PaymentSession,
|
||||||
|
ShippingMethod,
|
||||||
|
} from "../models"
|
||||||
|
|
||||||
|
export type PaymentSessionInput = {
|
||||||
|
provider_id: string
|
||||||
|
// TODO: Support legacy payment provider API> Once we are ready to break the api then we can remove the Cart type
|
||||||
|
cart:
|
||||||
|
| Cart
|
||||||
|
| {
|
||||||
|
context: Record<string, unknown>
|
||||||
|
id: string
|
||||||
|
email: string
|
||||||
|
shipping_address: Address | null
|
||||||
|
shipping_methods: ShippingMethod[]
|
||||||
|
}
|
||||||
|
customer?: Customer | null
|
||||||
|
currency_code: string
|
||||||
|
amount: number
|
||||||
|
resource_id?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CreatePaymentInput = {
|
||||||
|
cart_id?: string
|
||||||
|
amount: number
|
||||||
|
currency_code: string
|
||||||
|
provider_id?: string
|
||||||
|
payment_session: PaymentSession
|
||||||
|
resource_id?: string
|
||||||
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
import { pick } from "lodash"
|
import { pick } from "lodash"
|
||||||
import { FindConfig, QueryConfig, RequestQueryFields } from "../types/common"
|
import { FindConfig, QueryConfig, RequestQueryFields } from "../types/common"
|
||||||
import { MedusaError } from "medusa-core-utils/dist"
|
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||||
import { BaseEntity } from "../interfaces"
|
import { BaseEntity } from "../interfaces"
|
||||||
import { isDefined } from "."
|
|
||||||
|
|
||||||
export function pickByConfig<TModel extends BaseEntity>(
|
export function pickByConfig<TModel extends BaseEntity>(
|
||||||
obj: TModel | TModel[],
|
obj: TModel | TModel[],
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ export * from "./set-metadata"
|
|||||||
export * from "./validate-id"
|
export * from "./validate-id"
|
||||||
export * from "./generate-entity-id"
|
export * from "./generate-entity-id"
|
||||||
export * from "./remove-undefined-properties"
|
export * from "./remove-undefined-properties"
|
||||||
export * from "./is-defined"
|
|
||||||
export * from "./is-string"
|
export * from "./is-string"
|
||||||
export * from "./calculate-price-tax-amount"
|
export * from "./calculate-price-tax-amount"
|
||||||
export * from "./csv-cell-content-formatter"
|
export * from "./csv-cell-content-formatter"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { isDefined } from "./is-defined"
|
import { isDefined } from "medusa-core-utils"
|
||||||
|
|
||||||
export function removeUndefinedProperties<T extends object>(inputObj: T): T {
|
export function removeUndefinedProperties<T extends object>(inputObj: T): T {
|
||||||
const removeProperties = (obj: T) => {
|
const removeProperties = (obj: T) => {
|
||||||
|
|||||||
Reference in new issue
Block a user