feat(payment, payment-stripe): Add Stripe module provider (#6311)
This commit is contained in:
1 parent
ac829fc67f
commit
ce39b9b66e
49 files changed
+1256
-119
No files matched your search
@@ -0,0 +1,9 @@
|
||||
import { MiddlewareRoute } from "../../types/middlewares"
|
||||
|
||||
export const hooksRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
{
|
||||
method: ["POST"],
|
||||
bodyParser: { preserveRawBody: true },
|
||||
matcher: "/hooks/payment/:provider",
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,32 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { PaymentWebhookEvents } from "@medusajs/utils"
|
||||
import { PaymentModuleOptions } from "@medusajs/types"
|
||||
|
||||
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||
|
||||
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
try {
|
||||
const { provider } = req.params
|
||||
|
||||
const options: PaymentModuleOptions =
|
||||
req.scope.resolve(ModuleRegistrationName.PAYMENT).options || {}
|
||||
|
||||
const event = {
|
||||
provider,
|
||||
payload: { data: req.body, rawData: req.rawBody, headers: req.headers },
|
||||
}
|
||||
|
||||
const eventBus = req.scope.resolve("eventBusService")
|
||||
|
||||
// we delay the processing of the event to avoid a conflict caused by a race condition
|
||||
await eventBus.emit(PaymentWebhookEvents.WebhookReceived, event, {
|
||||
delay: options.webhook_delay || 5000,
|
||||
attempts: options.webhook_retries || 3,
|
||||
})
|
||||
} catch (err) {
|
||||
res.status(400).send(`Webhook Error: ${err.message}`)
|
||||
return
|
||||
}
|
||||
|
||||
res.sendStatus(200)
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import { authRoutesMiddlewares } from "./auth/middlewares"
|
||||
import { storeCartRoutesMiddlewares } from "./store/carts/middlewares"
|
||||
import { storeCustomerRoutesMiddlewares } from "./store/customers/middlewares"
|
||||
import { storeRegionRoutesMiddlewares } from "./store/regions/middlewares"
|
||||
import { hooksRoutesMiddlewares } from "./hooks/middlewares"
|
||||
|
||||
export const config: MiddlewaresConfig = {
|
||||
routes: [
|
||||
@@ -29,5 +30,6 @@ export const config: MiddlewaresConfig = {
|
||||
...adminUserRoutesMiddlewares,
|
||||
...adminInviteRoutesMiddlewares,
|
||||
...adminApiKeyRoutesMiddlewares,
|
||||
...hooksRoutesMiddlewares,
|
||||
],
|
||||
}
|
||||
@@ -33,8 +33,6 @@ export default async ({
|
||||
next()
|
||||
})
|
||||
|
||||
app.use(bodyParser.json())
|
||||
|
||||
if (featureFlagRouter?.isFeatureEnabled(FeatureFlagUtils.MedusaV2Flag.key)) {
|
||||
// TODO: Figure out why this is causing issues with test when placed inside ./api.ts
|
||||
// Adding this here temporarily
|
||||
@@ -52,6 +50,7 @@ export default async ({
|
||||
throw Error("An error occurred while registering Medusa Core API Routes")
|
||||
}
|
||||
} else {
|
||||
app.use(bodyParser.json())
|
||||
app.use("/", routes(container, configModule.projectConfig))
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ import {
|
||||
RouteConfig,
|
||||
RouteDescriptor,
|
||||
RouteVerb,
|
||||
ParserConfigArgs,
|
||||
} from "./types"
|
||||
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
|
||||
|
||||
const log = ({
|
||||
activityId,
|
||||
@@ -150,9 +152,18 @@ function findMatch(
|
||||
* Returns an array of body parser middlewares that are applied on routes
|
||||
* out-of-the-box.
|
||||
*/
|
||||
function getBodyParserMiddleware(sizeLimit?: string | number | undefined) {
|
||||
function getBodyParserMiddleware(args?: ParserConfigArgs) {
|
||||
const sizeLimit = args?.sizeLimit
|
||||
const preserveRawBody = args?.preserveRawBody
|
||||
return [
|
||||
json({ limit: sizeLimit }),
|
||||
json({
|
||||
limit: sizeLimit,
|
||||
verify: preserveRawBody
|
||||
? (req: MedusaRequest, res: MedusaResponse, buf: Buffer) => {
|
||||
req.rawBody = buf
|
||||
}
|
||||
: undefined,
|
||||
}),
|
||||
text({ limit: sizeLimit }),
|
||||
urlencoded({ limit: sizeLimit, extended: true }),
|
||||
]
|
||||
@@ -556,7 +567,7 @@ export class RoutesLoader {
|
||||
|
||||
this.router[method.toLowerCase()](
|
||||
path,
|
||||
...getBodyParserMiddleware(sizeLimit)
|
||||
...getBodyParserMiddleware(mostSpecificConfig?.bodyParser)
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
@@ -55,11 +55,12 @@ export type MedusaErrorHandlerFunction = (
|
||||
next: MedusaNextFunction
|
||||
) => Promise<void> | void
|
||||
|
||||
type ParserConfig =
|
||||
| false
|
||||
| {
|
||||
sizeLimit?: string | number | undefined
|
||||
}
|
||||
export type ParserConfigArgs = {
|
||||
sizeLimit?: string | number | undefined
|
||||
preserveRawBody?: boolean
|
||||
}
|
||||
|
||||
type ParserConfig = false | ParserConfigArgs
|
||||
|
||||
export type MiddlewareRoute = {
|
||||
method?: MiddlewareVerb | MiddlewareVerb[]
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { PaymentWebhookEvents } from "@medusajs/utils"
|
||||
|
||||
import {
|
||||
IEventBusService,
|
||||
IPaymentModuleService,
|
||||
ProviderWebhookPayload,
|
||||
Subscriber,
|
||||
} from "@medusajs/types"
|
||||
import { EventBusService } from "../services"
|
||||
|
||||
type SerializedBuffer = {
|
||||
data: ArrayBuffer
|
||||
type: "Buffer"
|
||||
}
|
||||
|
||||
type InjectedDependencies = {
|
||||
paymentModuleService: IPaymentModuleService
|
||||
eventBusService: EventBusService
|
||||
}
|
||||
|
||||
class PaymentWebhookSubscriber {
|
||||
private readonly eventBusService_: IEventBusService
|
||||
private readonly paymentModuleService_: IPaymentModuleService
|
||||
|
||||
constructor({ eventBusService, paymentModuleService }: InjectedDependencies) {
|
||||
this.eventBusService_ = eventBusService
|
||||
this.paymentModuleService_ = paymentModuleService
|
||||
|
||||
this.eventBusService_.subscribe(
|
||||
PaymentWebhookEvents.WebhookReceived,
|
||||
this.processEvent as Subscriber
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: consider moving this to a workflow
|
||||
*/
|
||||
processEvent = async (data: ProviderWebhookPayload): Promise<void> => {
|
||||
if (
|
||||
(data.payload.rawData as unknown as SerializedBuffer).type === "Buffer"
|
||||
) {
|
||||
data.payload.rawData = Buffer.from(
|
||||
(data.payload.rawData as unknown as SerializedBuffer).data
|
||||
)
|
||||
}
|
||||
await this.paymentModuleService_.processEvent(data)
|
||||
}
|
||||
}
|
||||
|
||||
export default PaymentWebhookSubscriber
|
||||
@@ -7,6 +7,7 @@ export interface MedusaRequest extends Request {
|
||||
user?: (User | Customer) & { customer_id?: string; userId?: string }
|
||||
scope: MedusaContainer
|
||||
session?: any
|
||||
rawBody?: any
|
||||
requestId?: string
|
||||
auth_user?: { id: string; app_metadata: Record<string, any>; scope: string }
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user