From c6ca5ed8e8f6c44f324f0d401a59860083accc42 Mon Sep 17 00:00:00 2001 From: Abubeker Yasin Date: Thu, 16 Jul 2026 12:05:47 +0300 Subject: [PATCH] add provider detail on the --- .../src/modules/payments/payments.dto.ts | 7 +++++++ .../src/modules/payments/payments.service.ts | 7 +++++++ .../src/modules/intents/intents.service.ts | 13 +++++++++++++ packages/types/src/common/payments.ts | 7 +++++++ 4 files changed, 34 insertions(+) diff --git a/apps/edr-passenger-api/src/modules/payments/payments.dto.ts b/apps/edr-passenger-api/src/modules/payments/payments.dto.ts index 825fa114e..e0b594fd2 100644 --- a/apps/edr-passenger-api/src/modules/payments/payments.dto.ts +++ b/apps/edr-passenger-api/src/modules/payments/payments.dto.ts @@ -154,6 +154,13 @@ export class IntentStatusDto { @ApiPropertyOptional() paidAt?: string; @ApiPropertyOptional() failureCode?: string; @ApiPropertyOptional() failureMessage?: string; + @ApiPropertyOptional({ + type: "object", + additionalProperties: true, + description: + "Raw provider payload (initiation response merged with the latest status query) for inspection/debugging. Provider-specific shape; never trusted for state.", + }) + providerResponse?: Record; } export class BookingAmountResponseDto { diff --git a/apps/edr-passenger-api/src/modules/payments/payments.service.ts b/apps/edr-passenger-api/src/modules/payments/payments.service.ts index 5bd068255..458175fe2 100644 --- a/apps/edr-passenger-api/src/modules/payments/payments.service.ts +++ b/apps/edr-passenger-api/src/modules/payments/payments.service.ts @@ -432,6 +432,9 @@ export class PaymentsService { expiresAt: snapshot.expiresAt ? new Date(snapshot.expiresAt) : null, failureCode: snapshot.failureCode ?? null, failureMessage: snapshot.failureMessage ?? null, + rawInitiation: snapshot.providerResponse + ? (snapshot.providerResponse as unknown as Prisma.InputJsonValue) + : Prisma.DbNull, }; return this.prisma.paymentIntent.upsert({ where: { bookingId }, @@ -589,6 +592,10 @@ export class PaymentsService { paidAt: intent.paidAt?.toISOString(), failureCode: intent.failureCode ?? undefined, failureMessage: intent.failureMessage ?? undefined, + providerResponse: + intent.rawInitiation && typeof intent.rawInitiation === "object" + ? (intent.rawInitiation as Record) + : undefined, }; } diff --git a/apps/edr-payment-api/src/modules/intents/intents.service.ts b/apps/edr-payment-api/src/modules/intents/intents.service.ts index 0ebaaad05..a14469dd1 100644 --- a/apps/edr-payment-api/src/modules/intents/intents.service.ts +++ b/apps/edr-payment-api/src/modules/intents/intents.service.ts @@ -41,6 +41,8 @@ export interface ProviderResultInput { confirmedAmountMinor?: number; failureCode?: string; failureMessage?: string; + /** Raw provider status-query body, merged into the intent's audit payload when present. */ + rawResponse?: Record; } @Injectable() @@ -357,6 +359,7 @@ export class IntentsService { providerTxnId: status.providerTxnId, failureCode: status.failureCode, failureMessage: status.failureMessage, + rawResponse: status.rawResponse, }; } @@ -388,6 +391,15 @@ export class IntentsService { return { alreadyTerminal: true }; } + // Keep the audit payload current with the latest provider status body (surfaced as + // `providerResponse` in the snapshot). Merged so the initiation keys are preserved. + if (result.rawResponse) { + intent.rawInitiation = { + ...(intent.rawInitiation ?? {}), + statusResponse: result.rawResponse, + }; + } + if (result.status === ProviderPaymentStatus.SUCCEEDED) { const paidAt = result.paidAt ?? new Date(); intent.status = ProviderPaymentStatus.SUCCEEDED; @@ -482,6 +494,7 @@ export class IntentsService { failureCode: intent.failureCode ?? undefined, failureMessage: intent.failureMessage ?? undefined, expiresAt: intent.expiresAt?.toISOString(), + providerResponse: intent.rawInitiation ?? undefined, }; } } diff --git a/packages/types/src/common/payments.ts b/packages/types/src/common/payments.ts index ebc6e34dd..fc7769db7 100644 --- a/packages/types/src/common/payments.ts +++ b/packages/types/src/common/payments.ts @@ -153,6 +153,13 @@ export type PaymentIntentSnapshot ={ failureCode?: string; failureMessage?: string; expiresAt?: string; + /** + * Raw provider payload for inspection/debugging — the audit copy of the provider + * initiation response merged with the latest status-query response (secrets redacted + * upstream). Not a contract with the provider; shape is provider-specific. Never trusted + * for state decisions — the state machine drives `status`. + */ + providerResponse?: Record; } export type PaymentEventType = "payment.succeeded" | "payment.failed";