diff --git a/packages/payments-plugin/src/mollie/mollie.controller.ts b/packages/payments-plugin/src/mollie/mollie.controller.ts index 42f57cc44a..be41ca78c5 100644 --- a/packages/payments-plugin/src/mollie/mollie.controller.ts +++ b/packages/payments-plugin/src/mollie/mollie.controller.ts @@ -1,17 +1,16 @@ import { Body, Controller, Param, Post } from '@nestjs/common'; -import { Ctx, Logger, RequestContext, Transaction } from '@vendure/core'; +import { Ctx, Logger, RequestContext, Transaction, ChannelService, LanguageCode } from '@vendure/core'; import { loggerCtx } from './constants'; import { MollieService } from './mollie.service'; @Controller('payments') export class MollieController { - constructor(private mollieService: MollieService) {} + constructor(private mollieService: MollieService, private channelService: ChannelService) {} @Post('mollie/:channelToken/:paymentMethodId') @Transaction() async webhook( - @Ctx() ctx: RequestContext, @Param('channelToken') channelToken: string, @Param('paymentMethodId') paymentMethodId: string, @Body() body: any, @@ -20,8 +19,10 @@ export class MollieController { return Logger.warn(' Ignoring incoming webhook, because it has no body.id.', loggerCtx); } try { + // We need to construct a RequestContext based on the channelToken, + // because this is an incoming webhook, not a graphql request with a valid Ctx + const ctx = await this.createContext(channelToken); await this.mollieService.handleMollieStatusUpdate(ctx, { - channelToken, paymentMethodId, orderId: body.id, }); @@ -34,4 +35,15 @@ export class MollieController { throw error; } } + + private async createContext(channelToken: string): Promise { + const channel = await this.channelService.getChannelFromToken(channelToken); + return new RequestContext({ + apiType: 'admin', + isAuthorized: true, + authorizedAsOwnerOnly: false, + channel, + languageCode: LanguageCode.en, + }); + } } diff --git a/packages/payments-plugin/src/mollie/mollie.service.ts b/packages/payments-plugin/src/mollie/mollie.service.ts index dd7401b5ec..31eeea9846 100644 --- a/packages/payments-plugin/src/mollie/mollie.service.ts +++ b/packages/payments-plugin/src/mollie/mollie.service.ts @@ -33,7 +33,6 @@ import { amountToCents, getLocale, toAmount, toMollieAddress, toMollieOrderLines import { MolliePluginOptions } from './mollie.plugin'; interface OrderStatusInput { - channelToken: string; paymentMethodId: string; orderId: string; } @@ -199,10 +198,10 @@ export class MollieService { */ async handleMollieStatusUpdate( ctx: RequestContext, - { channelToken, paymentMethodId, orderId }: OrderStatusInput, + { paymentMethodId, orderId }: OrderStatusInput, ): Promise { Logger.info( - `Received status update for channel ${channelToken} for Mollie order ${orderId}`, + `Received status update for channel ${ctx.channel.token} for Mollie order ${orderId}`, loggerCtx, ); const paymentMethod = await this.paymentMethodService.findOne(ctx, paymentMethodId); @@ -213,12 +212,12 @@ export class MollieService { const apiKey = paymentMethod.handler.args.find(a => a.name === 'apiKey')?.value; const autoCapture = paymentMethod.handler.args.find(a => a.name === 'autoCapture')?.value === 'true'; if (!apiKey) { - throw Error(`No apiKey found for payment ${paymentMethod.id} for channel ${channelToken}`); + throw Error(`No apiKey found for payment ${paymentMethod.id} for channel ${ctx.channel.token}`); } const client = createMollieClient({ apiKey }); const mollieOrder = await client.orders.get(orderId); Logger.info( - `Processing status '${mollieOrder.status}' for order ${mollieOrder.orderNumber} for channel ${channelToken} for Mollie order ${orderId}`, + `Processing status '${mollieOrder.status}' for order ${mollieOrder.orderNumber} for channel ${ctx.channel.token} for Mollie order ${orderId}`, loggerCtx, ); let order = await this.orderService.findOneByCode(ctx, mollieOrder.orderNumber, ['payments']);