mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 17:38:12 +00:00
52 lines
2.0 KiB
TypeScript
52 lines
2.0 KiB
TypeScript
import { Injectable } from "@nestjs/common";
|
|
import { DMoneyProvider, DMoneyWebhookPayload } from "@edr/payment-providers";
|
|
import { WebhookProcessorService } from "../webhook-processor.service";
|
|
|
|
@Injectable()
|
|
export class DMoneyWebhookService {
|
|
constructor(
|
|
private readonly provider: DMoneyProvider,
|
|
private readonly processor: WebhookProcessorService,
|
|
) {}
|
|
|
|
async handle(payload: DMoneyWebhookPayload): Promise<void> {
|
|
// TODO: re-enable D-Money public-key signature verification — skipped for now.
|
|
// D-Money's onboarding pack only provides the merchant keypair (3072-bit); callbacks
|
|
// are signed with their separate platform notification key (4096-bit), which we don't
|
|
// have yet, so verifyWebhookSignature can never pass. Re-enable once that key is supplied.
|
|
const signatureValid = true;
|
|
|
|
const mapped = this.provider.mapWebhookTradeStatus(payload.trade_status);
|
|
const providerTxnId = payload.transId ?? payload.payment_order_id;
|
|
|
|
await this.processor.process({
|
|
provider: this.provider.method,
|
|
externalEventId: `${payload.payment_order_id}_${payload.trade_status}`,
|
|
merchantOrderId: payload.merch_order_id,
|
|
providerTxnId,
|
|
signatureValid,
|
|
rawStatus: payload.trade_status,
|
|
payload: payload as unknown as Record<string, unknown>,
|
|
result: {
|
|
status: mapped,
|
|
providerTxnId,
|
|
paidAt: this.parseTransEndTime(payload.trans_end_time),
|
|
failureCode: payload.trade_status,
|
|
},
|
|
});
|
|
}
|
|
|
|
/** D-Money sends trans_end_time either as epoch ms/s or "YYYY-MM-DD HH:mm:ss". */
|
|
private parseTransEndTime(raw: string | undefined): Date | undefined {
|
|
if (!raw) return undefined;
|
|
if (/^\d+$/.test(raw)) {
|
|
const n = parseInt(raw, 10);
|
|
if (Number.isNaN(n)) return undefined;
|
|
// 13-digit value is milliseconds, otherwise seconds.
|
|
return new Date(raw.length >= 13 ? n : n * 1000);
|
|
}
|
|
const parsed = new Date(raw.replace(" ", "T"));
|
|
return Number.isNaN(parsed.getTime()) ? undefined : parsed;
|
|
}
|
|
}
|