mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
feat: ( payment ) integrate the passenger to payment microservice
This commit is contained in:
@@ -75,6 +75,25 @@ export class InitiatePaymentRequestDto implements InitiatePaymentRequest {
|
||||
@MaxLength(32)
|
||||
payerAccount?: string;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description:
|
||||
"Per-transaction browser return URL on success — each calling app passes its own UI " +
|
||||
"(passenger portal vs freight portal). UX only; never confirms payment. Falls back to " +
|
||||
"the provider config when omitted.",
|
||||
})
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(2048)
|
||||
returnUrl?: string;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description: "Failure/cancel counterpart of returnUrl",
|
||||
})
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(2048)
|
||||
failureUrl?: string;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description: "Caller key to dedupe retried initiations",
|
||||
})
|
||||
|
||||
@@ -9,7 +9,6 @@ import { DataSource, QueryFailedError } from "typeorm";
|
||||
import { createMerchantOrderId } from "@edr/payment-providers";
|
||||
import {
|
||||
InitiatePaymentRequest,
|
||||
MERCHANT_ORDER_PREFIX,
|
||||
PaymentIntentSnapshot,
|
||||
PaymentReferenceType,
|
||||
PaymentService,
|
||||
@@ -60,6 +59,7 @@ export class IntentsService {
|
||||
async initiate(
|
||||
request: InitiatePaymentRequest,
|
||||
): Promise<PaymentIntentSnapshot> {
|
||||
|
||||
if (request.idempotencyKey) {
|
||||
const byKey = await this.intentsRepository.findByIdempotencyKey(
|
||||
request.service,
|
||||
@@ -85,7 +85,7 @@ export class IntentsService {
|
||||
);
|
||||
}
|
||||
|
||||
const merchantOrderId = `${MERCHANT_ORDER_PREFIX[request.service]}${createMerchantOrderId()}`;
|
||||
const merchantOrderId = createMerchantOrderId();
|
||||
const result = await provider.initiate({
|
||||
merchantOrderId,
|
||||
orderRef: request.orderRef ?? request.referenceId,
|
||||
@@ -93,6 +93,9 @@ export class IntentsService {
|
||||
currency: request.currency,
|
||||
platform: request.platform,
|
||||
payerAccount: request.payerAccount,
|
||||
returnUrl: request.returnUrl,
|
||||
redirectUrl: request.returnUrl,
|
||||
failureUrl: request.failureUrl,
|
||||
});
|
||||
|
||||
try {
|
||||
@@ -116,8 +119,6 @@ export class IntentsService {
|
||||
);
|
||||
return this.toSnapshot(intent);
|
||||
} catch (err) {
|
||||
// Concurrent initiate for the same reference lost the partial-unique race — return the
|
||||
// winner's intent. The provider session we just opened is simply abandoned.
|
||||
if (
|
||||
err instanceof QueryFailedError &&
|
||||
(err.driverError as { code?: string })?.code === PG_UNIQUE_VIOLATION
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import {
|
||||
MERCHANT_ORDER_PREFIX,
|
||||
PaymentService,
|
||||
ProviderMethod,
|
||||
} from "@edr/types";
|
||||
import { ProviderMethod } from "@edr/types";
|
||||
import { IntentsRepository } from "../intents/intents.repository";
|
||||
import {
|
||||
IntentsService,
|
||||
@@ -81,20 +77,6 @@ export class WebhookProcessorService {
|
||||
return;
|
||||
}
|
||||
|
||||
// Integrity guard (§10): the stateless prefix and the stored discriminator must agree.
|
||||
const expectedPrefix =
|
||||
MERCHANT_ORDER_PREFIX[intent.service as PaymentService];
|
||||
if (expectedPrefix && !merchantOrderId.startsWith(expectedPrefix)) {
|
||||
this.logger.error(
|
||||
`${provider} webhook: merchantOrderId ${merchantOrderId} prefix does not match stored service ${intent.service} — refusing to process`,
|
||||
);
|
||||
await this.webhookEvents.markProcessed(
|
||||
eventRow.id,
|
||||
"service-prefix-mismatch",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.intentsService.applyProviderResult(intent.id, webhook.result);
|
||||
await this.webhookEvents.markProcessed(eventRow.id);
|
||||
|
||||
@@ -112,6 +112,8 @@ export class WebhooksController {
|
||||
@Headers() headers: WaafiWebhookHeaders,
|
||||
@Req() req: { rawBody?: Buffer },
|
||||
) {
|
||||
|
||||
this.logger.log("\n\n\n\nWaafi payment notification callback (Djibouti)\n\n\n\n");
|
||||
this.logger.log(
|
||||
`Waafi webhook hit: event=${payload?.event ?? "unknown"} eventId=${headers["x-webhook-event-id"] ?? "n/a"}`,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user