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:
Oli Juhl authored and GitHub committed 2024-03-05 08:40:47 +00:00
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({
@@ -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)],
},
]
@@ -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 })
}
@@ -0,0 +1,7 @@
import { PaymentProviderContext } from "@medusajs/types"
export class StorePostPaymentCollectionsPaymentSessionReq {
provider_id: string
context?: PaymentProviderContext
data?: Record<string, unknown>
}