feat: Create payment sessions (#6549)
~~Opening a draft PR to discuss a couple of implementation details that we should align on~~ **What** Add workflow and API endpoint for creating payment sessions for a payment collection. Endpoint is currently `POST /store/payment-collection/:id/payment-sessions`. I suggested an alternative in a comment below. Please note, we intentionally do not want to support creating payment sessions in bulk, as this would become a mess when having to manage multiple calls to third-party providers.
This commit is contained in:
1 parent
908b1dc3a2
commit
84208aafc1
30 files changed
+603
-182
No files matched your search
@@ -1,22 +1,19 @@
|
||||
import { createCartWorkflow } from "@medusajs/core-flows"
|
||||
import { CreateCartWorkflowInputDTO } from "@medusajs/types"
|
||||
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../types/routing"
|
||||
|
||||
import { createCartWorkflow } from "@medusajs/core-flows"
|
||||
import { CreateCartWorkflowInputDTO } from "@medusajs/types"
|
||||
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
||||
import { defaultStoreCartFields } from "../carts/query-config"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<CreateCartWorkflowInputDTO>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const workflowInput = req.validatedBody
|
||||
|
||||
// If the customer is logged in, we auto-assign them to the cart
|
||||
if (req.auth?.actor_id) {
|
||||
workflowInput.customer_id = req.auth.actor_id
|
||||
const workflowInput = {
|
||||
...req.validatedBody,
|
||||
customer_id: req.auth?.actor_id,
|
||||
}
|
||||
|
||||
const { result, errors } = await createCartWorkflow(req.scope).run({
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
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)],
|
||||
},
|
||||
]
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
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,
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
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"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<StorePostPaymentCollectionsPaymentSessionReq>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const { id } = req.params
|
||||
const { context, provider_id, data } = 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,
|
||||
id: req.auth.actor_id,
|
||||
}
|
||||
}
|
||||
|
||||
const workflowInput = {
|
||||
payment_collection_id: id,
|
||||
provider_id: provider_id,
|
||||
data,
|
||||
context,
|
||||
}
|
||||
|
||||
const { errors } = await createPaymentSessionsWorkflow(req.scope).run({
|
||||
input: workflowInput as any,
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const remoteQuery = req.scope.resolve("remoteQuery")
|
||||
|
||||
const query = remoteQueryObjectFromString({
|
||||
entryPoint: "payment_collection",
|
||||
variables: { cart: { id } },
|
||||
fields: defaultStorePaymentCollectionFields,
|
||||
})
|
||||
|
||||
const [result] = await remoteQuery(query)
|
||||
|
||||
res.status(200).json({ payment_collection: result })
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import { PaymentProviderContext } from "@medusajs/types"
|
||||
|
||||
export class StorePostPaymentCollectionsPaymentSessionReq {
|
||||
provider_id: string
|
||||
context?: PaymentProviderContext
|
||||
data?: Record<string, unknown>
|
||||
}
|
||||
Reference in new issue
Block a user