feat(medusa): Use transactions in CartCompletionStrategy (#1968)
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Use transactions in CartCompletionStrategy phases
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { EntityManager } from "typeorm";
|
import { EntityManager } from "typeorm";
|
||||||
import { ICartCompletionStrategy } from "../../../../interfaces"
|
import { AbstractCartCompletionStrategy } from "../../../../interfaces"
|
||||||
import { IdempotencyKey } from "../../../../models/idempotency-key"
|
import { IdempotencyKey } from "../../../../models/idempotency-key"
|
||||||
import { IdempotencyKeyService } from "../../../../services"
|
import { IdempotencyKeyService } from "../../../../services"
|
||||||
|
|
||||||
@@ -54,6 +54,7 @@ import { IdempotencyKeyService } from "../../../../services"
|
|||||||
export default async (req, res) => {
|
export default async (req, res) => {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
|
|
||||||
|
const manager: EntityManager = req.scope.resolve("manager")
|
||||||
const idempotencyKeyService: IdempotencyKeyService = req.scope.resolve(
|
const idempotencyKeyService: IdempotencyKeyService = req.scope.resolve(
|
||||||
"idempotencyKeyService"
|
"idempotencyKeyService"
|
||||||
)
|
)
|
||||||
@@ -62,7 +63,6 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
let idempotencyKey: IdempotencyKey
|
let idempotencyKey: IdempotencyKey
|
||||||
try {
|
try {
|
||||||
const manager: EntityManager = req.scope.resolve("manager")
|
|
||||||
idempotencyKey = await manager.transaction(async (transactionManager) => {
|
idempotencyKey = await manager.transaction(async (transactionManager) => {
|
||||||
return await idempotencyKeyService.withTransaction(transactionManager).initializeRequest(
|
return await idempotencyKeyService.withTransaction(transactionManager).initializeRequest(
|
||||||
headerKey,
|
headerKey,
|
||||||
@@ -80,7 +80,7 @@ export default async (req, res) => {
|
|||||||
res.setHeader("Access-Control-Expose-Headers", "Idempotency-Key")
|
res.setHeader("Access-Control-Expose-Headers", "Idempotency-Key")
|
||||||
res.setHeader("Idempotency-Key", idempotencyKey.idempotency_key)
|
res.setHeader("Idempotency-Key", idempotencyKey.idempotency_key)
|
||||||
|
|
||||||
const completionStrat: ICartCompletionStrategy = req.scope.resolve(
|
const completionStrat: AbstractCartCompletionStrategy = req.scope.resolve(
|
||||||
"cartCompletionStrategy"
|
"cartCompletionStrategy"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { IdempotencyKey } from "../models/idempotency-key"
|
import { IdempotencyKey } from "../models"
|
||||||
import { RequestContext } from "../types/request"
|
import { RequestContext } from "../types/request"
|
||||||
|
import { TransactionBaseService } from "./transaction-base-service"
|
||||||
|
|
||||||
export type CartCompletionResponse = {
|
export type CartCompletionResponse = {
|
||||||
/** The response code for the completion request */
|
/** The response code for the completion request */
|
||||||
@@ -25,9 +26,19 @@ export interface ICartCompletionStrategy {
|
|||||||
): Promise<CartCompletionResponse>
|
): Promise<CartCompletionResponse>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isCartCompletionStrategy(
|
export abstract class AbstractCartCompletionStrategy
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
implements ICartCompletionStrategy
|
||||||
object: any
|
{
|
||||||
): object is ICartCompletionStrategy {
|
abstract complete(
|
||||||
return typeof object.complete === "function"
|
cartId: string,
|
||||||
|
idempotencyKey: IdempotencyKey,
|
||||||
|
context: RequestContext
|
||||||
|
): Promise<CartCompletionResponse>
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isCartCompletionStrategy(obj: unknown): boolean {
|
||||||
|
return (
|
||||||
|
typeof (obj as AbstractCartCompletionStrategy).complete === "function" ||
|
||||||
|
obj instanceof AbstractCartCompletionStrategy
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { EntitySchema } from "typeorm"
|
|||||||
import {
|
import {
|
||||||
AbstractTaxService,
|
AbstractTaxService,
|
||||||
isBatchJobStrategy,
|
isBatchJobStrategy,
|
||||||
|
isCartCompletionStrategy,
|
||||||
isFileService,
|
isFileService,
|
||||||
isNotificationService,
|
isNotificationService,
|
||||||
isPriceSelectionStrategy,
|
isPriceSelectionStrategy,
|
||||||
@@ -184,6 +185,22 @@ export function registerStrategies(
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case isCartCompletionStrategy(module.prototype): {
|
||||||
|
if (!("cartCompletionStrategy" in registeredServices)) {
|
||||||
|
container.register({
|
||||||
|
cartCompletionStrategy: asFunction(
|
||||||
|
(cradle) => new module(cradle, pluginDetails.options)
|
||||||
|
).singleton(),
|
||||||
|
})
|
||||||
|
registeredServices["cartCompletionStrategy"] = file
|
||||||
|
} else {
|
||||||
|
logger.warn(
|
||||||
|
`Cannot register ${file}. A cart completion strategy is already registered`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
case isBatchJobStrategy(module.prototype): {
|
case isBatchJobStrategy(module.prototype): {
|
||||||
container.registerAdd(
|
container.registerAdd(
|
||||||
"batchJobStrategies",
|
"batchJobStrategies",
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ describe("CartCompletionStrategy", () => {
|
|||||||
idempotencyKeyService: idempotencyKeyServiceMock,
|
idempotencyKeyService: idempotencyKeyServiceMock,
|
||||||
orderService: orderServiceMock,
|
orderService: orderServiceMock,
|
||||||
swapService: swapServiceMock,
|
swapService: swapServiceMock,
|
||||||
|
manager: MockManager
|
||||||
})
|
})
|
||||||
|
|
||||||
const val = await completionStrat.complete(cart.id, idempotencyKey, {})
|
const val = await completionStrat.complete(cart.id, idempotencyKey, {})
|
||||||
|
|||||||
@@ -1,32 +1,48 @@
|
|||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { MedusaError } from "medusa-core-utils"
|
import { MedusaError } from "medusa-core-utils"
|
||||||
|
|
||||||
import { IdempotencyKey } from "../models/idempotency-key"
|
import { IdempotencyKey, Order } from "../models"
|
||||||
import { Order } from "../models/order"
|
|
||||||
import CartService from "../services/cart"
|
import CartService from "../services/cart"
|
||||||
import { RequestContext } from "../types/request"
|
import { RequestContext } from "../types/request"
|
||||||
import OrderService from "../services/order"
|
import OrderService from "../services/order"
|
||||||
import IdempotencyKeyService from "../services/idempotency-key"
|
import IdempotencyKeyService from "../services/idempotency-key"
|
||||||
import SwapService from "../services/swap"
|
import SwapService from "../services/swap"
|
||||||
|
|
||||||
import { ICartCompletionStrategy, CartCompletionResponse } from "../interfaces"
|
import {
|
||||||
|
CartCompletionResponse,
|
||||||
|
AbstractCartCompletionStrategy,
|
||||||
|
} from "../interfaces"
|
||||||
|
|
||||||
class CartCompletionStrategy implements ICartCompletionStrategy {
|
type InjectedDependencies = {
|
||||||
private idempotencyKeyService_: IdempotencyKeyService
|
idempotencyKeyService: IdempotencyKeyService
|
||||||
private cartService_: CartService
|
cartService: CartService
|
||||||
private orderService_: OrderService
|
orderService: OrderService
|
||||||
private swapService_: SwapService
|
swapService: SwapService
|
||||||
|
manager: EntityManager
|
||||||
|
}
|
||||||
|
|
||||||
|
class CartCompletionStrategy extends AbstractCartCompletionStrategy {
|
||||||
|
protected manager_: EntityManager
|
||||||
|
|
||||||
|
protected readonly idempotencyKeyService_: IdempotencyKeyService
|
||||||
|
protected readonly cartService_: CartService
|
||||||
|
protected readonly orderService_: OrderService
|
||||||
|
protected readonly swapService_: SwapService
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
idempotencyKeyService,
|
idempotencyKeyService,
|
||||||
cartService,
|
cartService,
|
||||||
orderService,
|
orderService,
|
||||||
swapService,
|
swapService,
|
||||||
}) {
|
manager,
|
||||||
|
}: InjectedDependencies) {
|
||||||
|
super()
|
||||||
|
|
||||||
this.idempotencyKeyService_ = idempotencyKeyService
|
this.idempotencyKeyService_ = idempotencyKeyService
|
||||||
this.cartService_ = cartService
|
this.cartService_ = cartService
|
||||||
this.orderService_ = orderService
|
this.orderService_ = orderService
|
||||||
this.swapService_ = swapService
|
this.swapService_ = swapService
|
||||||
|
this.manager_ = manager
|
||||||
}
|
}
|
||||||
|
|
||||||
async complete(
|
async complete(
|
||||||
@@ -47,159 +63,211 @@ class CartCompletionStrategy implements ICartCompletionStrategy {
|
|||||||
while (inProgress) {
|
while (inProgress) {
|
||||||
switch (idempotencyKey.recovery_point) {
|
switch (idempotencyKey.recovery_point) {
|
||||||
case "started": {
|
case "started": {
|
||||||
const { key, error } = await idempotencyKeyService.workStage(
|
await this.manager_.transaction(async (transactionManager) => {
|
||||||
idempotencyKey.idempotency_key,
|
const { key, error } = await idempotencyKeyService
|
||||||
async (manager: EntityManager) => {
|
.withTransaction(transactionManager)
|
||||||
const cart = await cartService
|
.workStage(
|
||||||
.withTransaction(manager)
|
idempotencyKey.idempotency_key,
|
||||||
.retrieve(id)
|
async (manager: EntityManager) => {
|
||||||
|
const cart = await cartService
|
||||||
if (cart.completed_at) {
|
.withTransaction(manager)
|
||||||
return {
|
.retrieve(id)
|
||||||
response_code: 409,
|
|
||||||
response_body: {
|
|
||||||
code: MedusaError.Codes.CART_INCOMPATIBLE_STATE,
|
|
||||||
message: "Cart has already been completed",
|
|
||||||
type: MedusaError.Types.NOT_ALLOWED,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await cartService.withTransaction(manager).createTaxLines(id)
|
|
||||||
|
|
||||||
return {
|
|
||||||
recovery_point: "tax_lines_created",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
inProgress = false
|
|
||||||
err = error
|
|
||||||
} else {
|
|
||||||
idempotencyKey = key
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case "tax_lines_created": {
|
|
||||||
const { key, error } = await idempotencyKeyService.workStage(
|
|
||||||
idempotencyKey.idempotency_key,
|
|
||||||
async (manager: EntityManager) => {
|
|
||||||
const cart = await cartService
|
|
||||||
.withTransaction(manager)
|
|
||||||
.authorizePayment(id, {
|
|
||||||
...context,
|
|
||||||
idempotency_key: idempotencyKey.idempotency_key,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (cart.payment_session) {
|
|
||||||
if (
|
|
||||||
cart.payment_session.status === "requires_more" ||
|
|
||||||
cart.payment_session.status === "pending"
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
response_code: 200,
|
|
||||||
response_body: {
|
|
||||||
data: cart,
|
|
||||||
payment_status: cart.payment_session.status,
|
|
||||||
type: "cart",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
recovery_point: "payment_authorized",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
inProgress = false
|
|
||||||
err = error
|
|
||||||
} else {
|
|
||||||
idempotencyKey = key
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case "payment_authorized": {
|
|
||||||
const { key, error } = await idempotencyKeyService.workStage(
|
|
||||||
idempotencyKey.idempotency_key,
|
|
||||||
async (manager: EntityManager) => {
|
|
||||||
const cart = await cartService
|
|
||||||
.withTransaction(manager)
|
|
||||||
.retrieve(id, {
|
|
||||||
select: ["total"],
|
|
||||||
relations: ["payment", "payment_sessions"],
|
|
||||||
})
|
|
||||||
|
|
||||||
// If cart is part of swap, we register swap as complete
|
|
||||||
switch (cart.type) {
|
|
||||||
case "swap": {
|
|
||||||
try {
|
|
||||||
const swapId = cart.metadata?.swap_id
|
|
||||||
let swap = await swapService
|
|
||||||
.withTransaction(manager)
|
|
||||||
.registerCartCompletion(swapId as string)
|
|
||||||
|
|
||||||
swap = await swapService
|
|
||||||
.withTransaction(manager)
|
|
||||||
.retrieve(swap.id, { relations: ["shipping_address"] })
|
|
||||||
|
|
||||||
|
if (cart.completed_at) {
|
||||||
return {
|
return {
|
||||||
response_code: 200,
|
response_code: 409,
|
||||||
response_body: { data: swap, type: "swap" },
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
if (
|
|
||||||
error &&
|
|
||||||
error.code === MedusaError.Codes.INSUFFICIENT_INVENTORY
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
response_code: 409,
|
|
||||||
response_body: {
|
|
||||||
message: error.message,
|
|
||||||
type: error.type,
|
|
||||||
code: error.code,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// case "payment_link":
|
|
||||||
default: {
|
|
||||||
if (typeof cart.total === "undefined") {
|
|
||||||
return {
|
|
||||||
response_code: 500,
|
|
||||||
response_body: {
|
response_body: {
|
||||||
message: "Unexpected state",
|
code: MedusaError.Codes.CART_INCOMPATIBLE_STATE,
|
||||||
|
message: "Cart has already been completed",
|
||||||
|
type: MedusaError.Types.NOT_ALLOWED,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cart.payment && cart.total > 0) {
|
await cartService.withTransaction(manager).createTaxLines(id)
|
||||||
throw new MedusaError(
|
|
||||||
MedusaError.Types.INVALID_DATA,
|
return {
|
||||||
`Cart payment not authorized`
|
recovery_point: "tax_lines_created",
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
inProgress = false
|
||||||
|
err = error
|
||||||
|
} else {
|
||||||
|
idempotencyKey = key
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case "tax_lines_created": {
|
||||||
|
await this.manager_.transaction(async (transactionManager) => {
|
||||||
|
const { key, error } = await idempotencyKeyService
|
||||||
|
.withTransaction(transactionManager)
|
||||||
|
.workStage(
|
||||||
|
idempotencyKey.idempotency_key,
|
||||||
|
async (manager: EntityManager) => {
|
||||||
|
const cart = await cartService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.authorizePayment(id, {
|
||||||
|
...context,
|
||||||
|
idempotency_key: idempotencyKey.idempotency_key,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (cart.payment_session) {
|
||||||
|
if (
|
||||||
|
cart.payment_session.status === "requires_more" ||
|
||||||
|
cart.payment_session.status === "pending"
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
response_code: 200,
|
||||||
|
response_body: {
|
||||||
|
data: cart,
|
||||||
|
payment_status: cart.payment_session.status,
|
||||||
|
type: "cart",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let order: Order
|
return {
|
||||||
try {
|
recovery_point: "payment_authorized",
|
||||||
order = await orderService
|
}
|
||||||
.withTransaction(manager)
|
}
|
||||||
.createFromCart(cart.id)
|
)
|
||||||
} catch (error) {
|
|
||||||
if (
|
if (error) {
|
||||||
error &&
|
inProgress = false
|
||||||
error.message === "Order from cart already exists"
|
err = error
|
||||||
) {
|
} else {
|
||||||
|
idempotencyKey = key
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
case "payment_authorized": {
|
||||||
|
await this.manager_.transaction(async (transactionManager) => {
|
||||||
|
const { key, error } = await idempotencyKeyService
|
||||||
|
.withTransaction(transactionManager)
|
||||||
|
.workStage(
|
||||||
|
idempotencyKey.idempotency_key,
|
||||||
|
async (manager: EntityManager) => {
|
||||||
|
const cart = await cartService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.retrieve(id, {
|
||||||
|
select: ["total"],
|
||||||
|
relations: ["payment", "payment_sessions"],
|
||||||
|
})
|
||||||
|
|
||||||
|
// If cart is part of swap, we register swap as complete
|
||||||
|
switch (cart.type) {
|
||||||
|
case "swap": {
|
||||||
|
try {
|
||||||
|
const swapId = cart.metadata?.swap_id
|
||||||
|
let swap = await swapService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.registerCartCompletion(swapId as string)
|
||||||
|
|
||||||
|
swap = await swapService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.retrieve(swap.id, {
|
||||||
|
relations: ["shipping_address"],
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
response_code: 200,
|
||||||
|
response_body: { data: swap, type: "swap" },
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (
|
||||||
|
error &&
|
||||||
|
error.code ===
|
||||||
|
MedusaError.Codes.INSUFFICIENT_INVENTORY
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
response_code: 409,
|
||||||
|
response_body: {
|
||||||
|
message: error.message,
|
||||||
|
type: error.type,
|
||||||
|
code: error.code,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
if (typeof cart.total === "undefined") {
|
||||||
|
return {
|
||||||
|
response_code: 500,
|
||||||
|
response_body: {
|
||||||
|
message: "Unexpected state",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cart.payment && cart.total > 0) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.INVALID_DATA,
|
||||||
|
`Cart payment not authorized`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let order: Order
|
||||||
|
try {
|
||||||
|
order = await orderService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.createFromCart(cart.id)
|
||||||
|
} catch (error) {
|
||||||
|
if (
|
||||||
|
error &&
|
||||||
|
error.message === "Order from cart already exists"
|
||||||
|
) {
|
||||||
|
order = await orderService
|
||||||
|
.withTransaction(manager)
|
||||||
|
.retrieveByCartId(id, {
|
||||||
|
select: [
|
||||||
|
"subtotal",
|
||||||
|
"tax_total",
|
||||||
|
"shipping_total",
|
||||||
|
"discount_total",
|
||||||
|
"total",
|
||||||
|
],
|
||||||
|
relations: [
|
||||||
|
"shipping_address",
|
||||||
|
"items",
|
||||||
|
"payments",
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
response_code: 200,
|
||||||
|
response_body: { data: order, type: "order" },
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
error &&
|
||||||
|
error.code ===
|
||||||
|
MedusaError.Codes.INSUFFICIENT_INVENTORY
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
response_code: 409,
|
||||||
|
response_body: {
|
||||||
|
message: error.message,
|
||||||
|
type: error.type,
|
||||||
|
code: error.code,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
order = await orderService
|
order = await orderService
|
||||||
.withTransaction(manager)
|
.withTransaction(manager)
|
||||||
.retrieveByCartId(id, {
|
.retrieve(order.id, {
|
||||||
select: [
|
select: [
|
||||||
"subtotal",
|
"subtotal",
|
||||||
"tax_total",
|
"tax_total",
|
||||||
@@ -214,51 +282,18 @@ class CartCompletionStrategy implements ICartCompletionStrategy {
|
|||||||
response_code: 200,
|
response_code: 200,
|
||||||
response_body: { data: order, type: "order" },
|
response_body: { data: order, type: "order" },
|
||||||
}
|
}
|
||||||
} else if (
|
|
||||||
error &&
|
|
||||||
error.code === MedusaError.Codes.INSUFFICIENT_INVENTORY
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
response_code: 409,
|
|
||||||
response_body: {
|
|
||||||
message: error.message,
|
|
||||||
type: error.type,
|
|
||||||
code: error.code,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
order = await orderService
|
|
||||||
.withTransaction(manager)
|
|
||||||
.retrieve(order.id, {
|
|
||||||
select: [
|
|
||||||
"subtotal",
|
|
||||||
"tax_total",
|
|
||||||
"shipping_total",
|
|
||||||
"discount_total",
|
|
||||||
"total",
|
|
||||||
],
|
|
||||||
relations: ["shipping_address", "items", "payments"],
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
response_code: 200,
|
|
||||||
response_body: { data: order, type: "order" },
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
inProgress = false
|
inProgress = false
|
||||||
err = error
|
err = error
|
||||||
} else {
|
} else {
|
||||||
idempotencyKey = key
|
idempotencyKey = key
|
||||||
}
|
}
|
||||||
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,14 +303,15 @@ class CartCompletionStrategy implements ICartCompletionStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
idempotencyKey = await idempotencyKeyService.update(
|
await this.manager_.transaction(async (transactionManager) => {
|
||||||
idempotencyKey.idempotency_key,
|
idempotencyKey = await idempotencyKeyService
|
||||||
{
|
.withTransaction(transactionManager)
|
||||||
recovery_point: "finished",
|
.update(idempotencyKey.idempotency_key, {
|
||||||
response_code: 500,
|
recovery_point: "finished",
|
||||||
response_body: { message: "Unknown recovery point" },
|
response_code: 500,
|
||||||
}
|
response_body: { message: "Unknown recovery point" },
|
||||||
)
|
})
|
||||||
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user