feat: Consolidate payment functions and handle sessions for storefront (#7231)
This commit is contained in:
@@ -1455,8 +1455,13 @@ medusaIntegrationTestRunner({
|
||||
rules: [
|
||||
{
|
||||
operator: RuleOperator.EQ,
|
||||
attribute: "shipping_address.province",
|
||||
value: "ny",
|
||||
attribute: "is_return",
|
||||
value: "false",
|
||||
},
|
||||
{
|
||||
operator: RuleOperator.EQ,
|
||||
attribute: "enabled_in_store",
|
||||
value: "true",
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -1197,7 +1197,7 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /store/carts/:id/payment-collections", () => {
|
||||
describe("POST /store/payment-collections", () => {
|
||||
it("should create a payment collection for the cart", async () => {
|
||||
const region = await regionModule.create({
|
||||
name: "US",
|
||||
@@ -1209,22 +1209,92 @@ medusaIntegrationTestRunner({
|
||||
region_id: region.id,
|
||||
})
|
||||
|
||||
const response = await api.post(
|
||||
`/store/carts/${cart.id}/payment-collections`
|
||||
)
|
||||
const response = await api.post(`/store/payment-collections`, {
|
||||
region_id: region.id,
|
||||
cart_id: cart.id,
|
||||
amount: 0,
|
||||
currency_code: cart.currency_code,
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.cart).toEqual(
|
||||
expect(response.data.payment_collection).toEqual(
|
||||
expect.objectContaining({
|
||||
id: cart.id,
|
||||
currency_code: "usd",
|
||||
payment_collection: expect.objectContaining({
|
||||
id: expect.any(String),
|
||||
amount: 0,
|
||||
}),
|
||||
id: expect.any(String),
|
||||
amount: 0,
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should return an existing payment collection for the cart", async () => {
|
||||
const region = await regionModule.create({
|
||||
name: "US",
|
||||
currency_code: "usd",
|
||||
})
|
||||
|
||||
const cart = await cartModule.create({
|
||||
currency_code: "usd",
|
||||
region_id: region.id,
|
||||
})
|
||||
|
||||
const firstCollection = (
|
||||
await api.post(`/store/payment-collections`, {
|
||||
region_id: region.id,
|
||||
cart_id: cart.id,
|
||||
amount: 0,
|
||||
currency_code: cart.currency_code,
|
||||
})
|
||||
).data.payment_collection
|
||||
|
||||
const response = await api.post(`/store/payment-collections`, {
|
||||
region_id: region.id,
|
||||
cart_id: cart.id,
|
||||
amount: 0,
|
||||
currency_code: cart.currency_code,
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(response.data.payment_collection.id).toEqual(
|
||||
firstCollection.id
|
||||
)
|
||||
})
|
||||
|
||||
it("should create a new payment collection for a new cart", async () => {
|
||||
const region = await regionModule.create({
|
||||
name: "US",
|
||||
currency_code: "usd",
|
||||
})
|
||||
|
||||
const firstCart = await cartModule.create({
|
||||
currency_code: "usd",
|
||||
region_id: region.id,
|
||||
})
|
||||
|
||||
const secondCart = await cartModule.create({
|
||||
currency_code: "usd",
|
||||
region_id: region.id,
|
||||
})
|
||||
|
||||
const firstCollection = (
|
||||
await api.post(`/store/payment-collections`, {
|
||||
region_id: region.id,
|
||||
cart_id: firstCart.id,
|
||||
amount: 0,
|
||||
currency_code: firstCart.currency_code,
|
||||
})
|
||||
).data.payment_collection
|
||||
|
||||
const secondCollection = (
|
||||
await api.post(`/store/payment-collections`, {
|
||||
region_id: region.id,
|
||||
cart_id: secondCart.id,
|
||||
amount: 0,
|
||||
currency_code: secondCart.currency_code,
|
||||
})
|
||||
).data.payment_collection
|
||||
|
||||
expect(firstCollection.id).toBeTruthy()
|
||||
expect(firstCollection.id).not.toEqual(secondCollection.id)
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /store/carts/:id/taxes", () => {
|
||||
@@ -1363,8 +1433,13 @@ medusaIntegrationTestRunner({
|
||||
rules: [
|
||||
{
|
||||
operator: RuleOperator.EQ,
|
||||
attribute: "shipping_address.country_code",
|
||||
value: "us",
|
||||
attribute: "is_return",
|
||||
value: "false",
|
||||
},
|
||||
{
|
||||
operator: RuleOperator.EQ,
|
||||
attribute: "enabled_in_store",
|
||||
value: "true",
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -5,6 +5,10 @@ import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface StepInput {
|
||||
cart: CartDTO
|
||||
shippingOptionsContext: {
|
||||
enabled_in_store?: "true" | "false"
|
||||
is_return?: "true" | "false"
|
||||
}
|
||||
option_ids: string[]
|
||||
}
|
||||
|
||||
@@ -13,7 +17,7 @@ export const validateCartShippingOptionsStepId =
|
||||
export const validateCartShippingOptionsStep = createStep(
|
||||
validateCartShippingOptionsStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
const { option_ids: optionIds = [], cart } = data
|
||||
const { option_ids: optionIds = [], cart, shippingOptionsContext } = data
|
||||
|
||||
if (!optionIds.length) {
|
||||
return new StepResponse(void 0)
|
||||
@@ -27,7 +31,7 @@ export const validateCartShippingOptionsStep = createStep(
|
||||
await fulfillmentModule.listShippingOptionsForContext(
|
||||
{
|
||||
id: optionIds,
|
||||
context: { ...cart },
|
||||
context: shippingOptionsContext,
|
||||
address: {
|
||||
country_code: cart.shipping_address?.country_code,
|
||||
province_code: cart.shipping_address?.province,
|
||||
|
||||
@@ -40,6 +40,7 @@ export const addShippingMethodToWorkflow = createWorkflow(
|
||||
validateCartShippingOptionsStep({
|
||||
option_ids: optionIds,
|
||||
cart,
|
||||
shippingOptionsContext: { is_return: "false", enabled_in_store: "true" },
|
||||
})
|
||||
|
||||
const shippingOptions = useRemoteQueryStep({
|
||||
|
||||
@@ -46,6 +46,10 @@ export const listShippingOptionsForCartWorkflow = createWorkflow(
|
||||
variables: {
|
||||
id: input.sales_channel_id,
|
||||
"stock_locations.fulfillment_sets.service_zones.shipping_options": {
|
||||
context: {
|
||||
is_return: "false",
|
||||
enabled_in_store: "true",
|
||||
},
|
||||
filters: {
|
||||
address: {
|
||||
city: input.shipping_address?.city,
|
||||
|
||||
@@ -40,6 +40,9 @@ import { storeCustomerRoutesMiddlewares } from "./store/customers/middlewares"
|
||||
import { storeProductRoutesMiddlewares } from "./store/products/middlewares"
|
||||
import { storeProductCategoryRoutesMiddlewares } from "./store/product-categories/middlewares"
|
||||
import { storeRegionRoutesMiddlewares } from "./store/regions/middlewares"
|
||||
import { storePaymentProvidersMiddlewares } from "./store/payment-providers/middlewares"
|
||||
import { storePaymentCollectionsMiddlewares } from "./store/payment-collections/middlewares"
|
||||
import { storeShippingOptionRoutesMiddlewares } from "./store/shipping-options/middlewares"
|
||||
|
||||
export const config: MiddlewaresConfig = {
|
||||
routes: [
|
||||
@@ -52,6 +55,9 @@ export const config: MiddlewaresConfig = {
|
||||
...storeCartRoutesMiddlewares,
|
||||
...storeCollectionRoutesMiddlewares,
|
||||
...storeProductCategoryRoutesMiddlewares,
|
||||
...storePaymentProvidersMiddlewares,
|
||||
...storeShippingOptionRoutesMiddlewares,
|
||||
...storePaymentCollectionsMiddlewares,
|
||||
...authRoutesMiddlewares,
|
||||
...adminWorkflowsExecutionsMiddlewares,
|
||||
...storeRegionRoutesMiddlewares,
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import { createPaymentCollectionForCartWorkflow } from "@medusajs/core-flows"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
|
||||
import { refetchCart } from "../../helpers"
|
||||
import { StoreUpdateCartType } from "../../validators"
|
||||
|
||||
export const POST = async (
|
||||
req: MedusaRequest<StoreUpdateCartType>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const workflow = createPaymentCollectionForCartWorkflow(req.scope)
|
||||
let cart = await refetchCart(req.params.id, req.scope, [
|
||||
"id",
|
||||
"currency_code",
|
||||
"region_id",
|
||||
"total",
|
||||
])
|
||||
|
||||
const { errors } = await workflow.run({
|
||||
input: {
|
||||
cart_id: req.params.id,
|
||||
region_id: cart.region_id,
|
||||
currency_code: cart.currency_code,
|
||||
amount: cart.total ?? 0, // TODO: This should be calculated from the cart when totals decoration is introduced
|
||||
},
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
cart = await refetchCart(
|
||||
req.params.id,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
)
|
||||
|
||||
res.status(200).json({ cart })
|
||||
}
|
||||
@@ -114,17 +114,6 @@ export const storeCartRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/store/carts/:id/payment-collections",
|
||||
middlewares: [
|
||||
validateAndTransformBody(StoreUpdateCart),
|
||||
validateAndTransformQuery(
|
||||
StoreGetCartsCart,
|
||||
QueryConfig.retrieveTransformQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/store/carts/:id/shipping-methods",
|
||||
|
||||
@@ -56,11 +56,11 @@ export const defaultStoreCartFields = [
|
||||
"shipping_methods.tax_lines.code",
|
||||
"shipping_methods.tax_lines.rate",
|
||||
"shipping_methods.tax_lines.provider_id",
|
||||
"shipping_methods.shipping_option_id",
|
||||
"shipping_methods.amount",
|
||||
"shipping_methods.adjustments.id",
|
||||
"shipping_methods.adjustments.code",
|
||||
"shipping_methods.adjustments.amount",
|
||||
"shipping_methods.shipping_option_id",
|
||||
"shipping_address.id",
|
||||
"shipping_address.first_name",
|
||||
"shipping_address.last_name",
|
||||
@@ -86,18 +86,16 @@ export const defaultStoreCartFields = [
|
||||
"region.name",
|
||||
"region.currency_code",
|
||||
"region.automatic_taxes",
|
||||
"*region.countries",
|
||||
"sales_channel_id",
|
||||
|
||||
// TODO: To be updated when payment sessions are introduces in the Rest API
|
||||
"payment_collection.id",
|
||||
"payment_collection.amount",
|
||||
"payment_collection.payment_sessions",
|
||||
"*payment_collection.payment_sessions",
|
||||
]
|
||||
|
||||
const allowedFields = [...defaultStoreCartFields]
|
||||
|
||||
export const retrieveTransformQueryConfig = {
|
||||
defaults: defaultStoreCartFields,
|
||||
allowed: allowedFields,
|
||||
isList: false,
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { transformBody } from "../../../../../api/middlewares"
|
||||
import { MiddlewareRoute } from "../../../../../loaders/helpers/routing/types"
|
||||
import { StorePostPaymentCollectionsPaymentSessionReq } from "./validators"
|
||||
|
||||
export const storeCartRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/store/payment-collections/:id/payment-sessions",
|
||||
middlewares: [transformBody(StorePostPaymentCollectionsPaymentSessionReq)],
|
||||
},
|
||||
]
|
||||
@@ -1,20 +0,0 @@
|
||||
export const defaultStorePaymentCollectionFields = [
|
||||
"id",
|
||||
"currency_code",
|
||||
"amount",
|
||||
"payment_sessions",
|
||||
"payment_sessions.id",
|
||||
"payment_sessions.amount",
|
||||
"payment_sessions.provider_id",
|
||||
]
|
||||
|
||||
export const defaultStorePaymentCollectionRelations = ["payment_sessions"]
|
||||
|
||||
export const allowedStorePaymentCollectionRelations = ["payment_sessions"]
|
||||
|
||||
export const retrieveTransformQueryConfig = {
|
||||
defaultFields: defaultStorePaymentCollectionFields,
|
||||
defaultRelations: defaultStorePaymentCollectionRelations,
|
||||
allowedRelations: allowedStorePaymentCollectionRelations,
|
||||
isList: false,
|
||||
}
|
||||
@@ -1,36 +1,33 @@
|
||||
import { createPaymentSessionsWorkflow } from "@medusajs/core-flows"
|
||||
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../../types/routing"
|
||||
import { defaultStorePaymentCollectionFields } from "./query-config"
|
||||
import { StorePostPaymentCollectionsPaymentSessionReq } from "./validators"
|
||||
import { StoreCreatePaymentSessionType } from "../../validators"
|
||||
import { refetchPaymentCollection } from "../../helpers"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<StorePostPaymentCollectionsPaymentSessionReq>,
|
||||
req: AuthenticatedMedusaRequest<StoreCreatePaymentSessionType>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const { id } = req.params
|
||||
const { context = {}, provider_id, data } = req.body
|
||||
const collectionId = req.params.id
|
||||
const { context = {}, data, provider_id } = req.body
|
||||
|
||||
// If the customer is logged in, we auto-assign them to the payment collection
|
||||
if (req.auth?.actor_id) {
|
||||
context.customer = {
|
||||
...context.customer,
|
||||
;(context as any).customer = {
|
||||
id: req.auth.actor_id,
|
||||
}
|
||||
}
|
||||
|
||||
const workflowInput = {
|
||||
payment_collection_id: id,
|
||||
payment_collection_id: collectionId,
|
||||
provider_id: provider_id,
|
||||
data,
|
||||
context,
|
||||
}
|
||||
|
||||
const { errors } = await createPaymentSessionsWorkflow(req.scope).run({
|
||||
input: workflowInput as any,
|
||||
input: workflowInput,
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
@@ -38,15 +35,11 @@ export const POST = async (
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const remoteQuery = req.scope.resolve("remoteQuery")
|
||||
const paymentCollection = await refetchPaymentCollection(
|
||||
collectionId,
|
||||
req.scope,
|
||||
req.remoteQueryConfig.fields
|
||||
)
|
||||
|
||||
const query = remoteQueryObjectFromString({
|
||||
entryPoint: "payment_collection",
|
||||
variables: { cart: { id } },
|
||||
fields: defaultStorePaymentCollectionFields,
|
||||
})
|
||||
|
||||
const [result] = await remoteQuery(query)
|
||||
|
||||
res.status(200).json({ payment_collection: result })
|
||||
res.status(200).json({ payment_collection: paymentCollection })
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import { PaymentProviderContext } from "@medusajs/types"
|
||||
|
||||
export class StorePostPaymentCollectionsPaymentSessionReq {
|
||||
provider_id: string
|
||||
context?: PaymentProviderContext
|
||||
data?: Record<string, unknown>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { MedusaContainer, PaymentCollectionDTO } from "@medusajs/types"
|
||||
import { refetchEntity } from "../../utils/refetch-entity"
|
||||
|
||||
export const refetchPaymentCollection = async (
|
||||
id: string,
|
||||
scope: MedusaContainer,
|
||||
fields: string[]
|
||||
): Promise<PaymentCollectionDTO> => {
|
||||
return refetchEntity("payment_collection", id, scope, fields)
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { MiddlewareRoute } from "../../../types/middlewares"
|
||||
import { authenticate } from "../../../utils/authenticate-middleware"
|
||||
import { validateAndTransformBody } from "../../utils/validate-body"
|
||||
import { validateAndTransformQuery } from "../../utils/validate-query"
|
||||
import * as queryConfig from "./query-config"
|
||||
import {
|
||||
StoreGetPaymentCollectionParams,
|
||||
StoreCreatePaymentCollection,
|
||||
StoreCreatePaymentSession,
|
||||
} from "./validators"
|
||||
|
||||
export const storePaymentCollectionsMiddlewares: MiddlewareRoute[] = [
|
||||
{
|
||||
method: "ALL",
|
||||
matcher: "/store/payment-collections*",
|
||||
middlewares: [
|
||||
authenticate("store", ["session", "bearer"], {
|
||||
allowUnauthenticated: true,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/store/payment-collections",
|
||||
middlewares: [
|
||||
validateAndTransformBody(StoreCreatePaymentCollection),
|
||||
validateAndTransformQuery(
|
||||
StoreGetPaymentCollectionParams,
|
||||
queryConfig.retrievePaymentCollectionTransformQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/store/payment-collections/:id/payment-sessions",
|
||||
middlewares: [
|
||||
validateAndTransformBody(StoreCreatePaymentSession),
|
||||
validateAndTransformQuery(
|
||||
StoreGetPaymentCollectionParams,
|
||||
queryConfig.retrievePaymentCollectionTransformQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,14 @@
|
||||
export const defaultPaymentCollectionFields = [
|
||||
"id",
|
||||
"currency_code",
|
||||
"amount",
|
||||
"payment_sessions",
|
||||
"payment_sessions.id",
|
||||
"payment_sessions.amount",
|
||||
"payment_sessions.provider_id",
|
||||
]
|
||||
|
||||
export const retrievePaymentCollectionTransformQueryConfig = {
|
||||
defaults: defaultPaymentCollectionFields,
|
||||
isList: false,
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { createPaymentCollectionForCartWorkflow } from "@medusajs/core-flows"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../types/routing"
|
||||
import { StoreCreatePaymentCollectionType } from "./validators"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<StoreCreatePaymentCollectionType>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const { cart_id } = req.body
|
||||
|
||||
// We can potentially refactor the workflow to behave more like an upsert and return an existing collection if there is one.
|
||||
const [cartCollectionRelation] = await remoteQuery(
|
||||
remoteQueryObjectFromString({
|
||||
entryPoint: "cart_payment_collection",
|
||||
variables: { filters: { cart_id } },
|
||||
fields: req.remoteQueryConfig.fields.map(
|
||||
(f) => `payment_collection.${f}`
|
||||
),
|
||||
})
|
||||
)
|
||||
let paymentCollection = cartCollectionRelation?.payment_collection
|
||||
|
||||
if (!paymentCollection) {
|
||||
const { errors } = await createPaymentCollectionForCartWorkflow(
|
||||
req.scope
|
||||
).run({
|
||||
input: req.body,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const [cartCollectionRelation] = await remoteQuery(
|
||||
remoteQueryObjectFromString({
|
||||
entryPoint: "cart_payment_collection",
|
||||
variables: { filters: { cart_id } },
|
||||
fields: req.remoteQueryConfig.fields.map(
|
||||
(f) => `payment_collection.${f}`
|
||||
),
|
||||
})
|
||||
)
|
||||
paymentCollection = cartCollectionRelation?.payment_collection
|
||||
}
|
||||
|
||||
res.status(200).json({ payment_collection: paymentCollection })
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { z } from "zod"
|
||||
import { createSelectParams } from "../../utils/validators"
|
||||
|
||||
export type StoreGetPaymentCollectionParamsType = z.infer<
|
||||
typeof StoreGetPaymentCollectionParams
|
||||
>
|
||||
export const StoreGetPaymentCollectionParams = createSelectParams()
|
||||
|
||||
export type StoreCreatePaymentSessionType = z.infer<
|
||||
typeof StoreCreatePaymentSession
|
||||
>
|
||||
export const StoreCreatePaymentSession = z
|
||||
.object({
|
||||
provider_id: z.string(),
|
||||
context: z.record(z.unknown()).optional(),
|
||||
data: z.record(z.unknown()).optional(),
|
||||
})
|
||||
.strict()
|
||||
|
||||
export type StoreCreatePaymentCollectionType = z.infer<
|
||||
typeof StoreCreatePaymentCollection
|
||||
>
|
||||
export const StoreCreatePaymentCollection = z
|
||||
.object({
|
||||
cart_id: z.string(),
|
||||
region_id: z.string(),
|
||||
currency_code: z.string(),
|
||||
amount: z.number(),
|
||||
})
|
||||
.strict()
|
||||
@@ -0,0 +1,17 @@
|
||||
import { MiddlewareRoute } from "../../../types/middlewares"
|
||||
import { validateAndTransformQuery } from "../../utils/validate-query"
|
||||
import * as queryConfig from "./query-config"
|
||||
import { StoreGetPaymentProvidersParams } from "./validators"
|
||||
|
||||
export const storePaymentProvidersMiddlewares: MiddlewareRoute[] = [
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/store/payment-providers",
|
||||
middlewares: [
|
||||
validateAndTransformQuery(
|
||||
StoreGetPaymentProvidersParams,
|
||||
queryConfig.listTransformPaymentProvidersQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
export const defaultAdminPaymentProviderFields = ["id", "is_enabled"]
|
||||
|
||||
export const listTransformPaymentProvidersQueryConfig = {
|
||||
defaults: defaultAdminPaymentProviderFields,
|
||||
isList: true,
|
||||
}
|
||||
50
packages/medusa/src/api-v2/store/payment-providers/route.ts
Normal file
50
packages/medusa/src/api-v2/store/payment-providers/route.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../types/routing"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
MedusaError,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { StoreGetPaymentProvidersParamsType } from "./validators"
|
||||
|
||||
// TODO: Add more fields to provider, such as default name and maybe logo.
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest<StoreGetPaymentProvidersParamsType>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
if (!req.filterableFields.region_id) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
"You must provide the region_id to list payment providers"
|
||||
)
|
||||
}
|
||||
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "region_payment_provider",
|
||||
variables: {
|
||||
filters: {
|
||||
region_id: req.filterableFields.region_id,
|
||||
},
|
||||
...req.remoteQueryConfig.pagination,
|
||||
},
|
||||
fields: req.remoteQueryConfig.fields.map((f) => `payment_provider.${f}`),
|
||||
})
|
||||
|
||||
const { rows: regionPaymentProvidersRelation, metadata } = await remoteQuery(
|
||||
queryObject
|
||||
)
|
||||
|
||||
const paymentProviders = regionPaymentProvidersRelation.map(
|
||||
(relation) => relation.payment_provider
|
||||
)
|
||||
|
||||
res.json({
|
||||
payment_providers: paymentProviders,
|
||||
count: metadata.count,
|
||||
offset: metadata.skip,
|
||||
limit: metadata.take,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { z } from "zod"
|
||||
import { createFindParams } from "../../utils/validators"
|
||||
|
||||
export type StoreGetPaymentProvidersParamsType = z.infer<
|
||||
typeof StoreGetPaymentProvidersParams
|
||||
>
|
||||
export const StoreGetPaymentProvidersParams = createFindParams({
|
||||
limit: 20,
|
||||
offset: 0,
|
||||
}).merge(
|
||||
z.object({
|
||||
region_id: z.string(),
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
is_enabled: z.boolean().optional(),
|
||||
$and: z.lazy(() => StoreGetPaymentProvidersParams.array()).optional(),
|
||||
$or: z.lazy(() => StoreGetPaymentProvidersParams.array()).optional(),
|
||||
})
|
||||
)
|
||||
@@ -1,9 +1,17 @@
|
||||
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
|
||||
import { validateAndTransformQuery } from "../../utils/validate-query"
|
||||
import { listTransformQueryConfig } from "./query-config"
|
||||
import { StoreGetShippingOptions } from "./validators"
|
||||
|
||||
export const storeShippingOptionRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/store/shipping-options/:cart_id",
|
||||
middlewares: [],
|
||||
matcher: "/store/shipping-options",
|
||||
middlewares: [
|
||||
validateAndTransformQuery(
|
||||
StoreGetShippingOptions,
|
||||
listTransformQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import { listShippingOptionsForCartWorkflow } from "@medusajs/core-flows"
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { ICartModuleService } from "@medusajs/types"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
|
||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
const { cart_id } = req.params
|
||||
const { cart_id } = req.filterableFields as { cart_id: string }
|
||||
if (!cart_id) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
"You must provide the cart_id to list shipping options"
|
||||
)
|
||||
}
|
||||
|
||||
const cartService = req.scope.resolve<ICartModuleService>(
|
||||
ModuleRegistrationName.CART
|
||||
@@ -0,0 +1,16 @@
|
||||
import { z } from "zod"
|
||||
import { createFindParams } from "../../utils/validators"
|
||||
|
||||
export type StoreGetShippingOptionsType = z.infer<
|
||||
typeof StoreGetShippingOptions
|
||||
>
|
||||
export const StoreGetShippingOptions = createFindParams({
|
||||
limit: 20,
|
||||
offset: 0,
|
||||
}).merge(
|
||||
z.object({
|
||||
cart_id: z.string(),
|
||||
$and: z.lazy(() => StoreGetShippingOptions.array()).optional(),
|
||||
$or: z.lazy(() => StoreGetShippingOptions.array()).optional(),
|
||||
})
|
||||
)
|
||||
Reference in New Issue
Block a user