mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Merge branch 'dev' of https://github.com/Tria-plc/edr-platform into alpha
This commit is contained in:
3
.github/workflows/deploy.yml
vendored
3
.github/workflows/deploy.yml
vendored
@@ -8,6 +8,9 @@ on:
|
||||
- staging
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: deploy-${{ github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
@@ -43,6 +43,14 @@ const NON_TERMINAL_STATUSES: PaymentIntentStatus[] = [
|
||||
export class PaymentsService {
|
||||
private readonly logger = new Logger(PaymentsService.name);
|
||||
|
||||
/**
|
||||
* DEMO ONLY: when true, a WALLET "payment" is treated as instantly successful — the wallet
|
||||
* balance check and debit are skipped and the booking is confirmed + ticket issued as if fully
|
||||
* paid. Lets the happy-path be demoed while a real provider (e.g. Telebirr) is unavailable.
|
||||
* Never enable in production. Toggle with WALLET_DEMO_AUTO_SUCCEED in the env.
|
||||
*/
|
||||
private readonly walletDemoAutoSucceed = true;
|
||||
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private seatsService: SeatsService,
|
||||
@@ -196,6 +204,35 @@ export class PaymentsService {
|
||||
private async initiateWalletPayment(
|
||||
booking: Prisma.BookingGetPayload<{ include: { seats: true } }>,
|
||||
): Promise<InitiateResponseDto> {
|
||||
// DEMO ONLY (WALLET_DEMO_AUTO_SUCCEED): pretend the payment succeeded — no balance check,
|
||||
// no debit — and run the exact same finalize path a real successful payment uses
|
||||
// (booking → CONFIRMED, seats confirmed, ticket issued). Remove once a real provider works.
|
||||
if (this.walletDemoAutoSucceed) {
|
||||
this.logger.warn(
|
||||
`WALLET_DEMO_AUTO_SUCCEED enabled — faking a successful WALLET payment for booking ${booking.bookingRef} (${booking.id})`,
|
||||
);
|
||||
const demoIntent = await this.prisma.paymentIntent.upsert({
|
||||
where: { bookingId: booking.id },
|
||||
update: {
|
||||
status: PaymentIntentStatus.PROCESSING,
|
||||
failureCode: null,
|
||||
method: PaymentMethodType.WALLET,
|
||||
},
|
||||
create: {
|
||||
bookingId: booking.id,
|
||||
amountMinor: booking.totalMinor,
|
||||
method: PaymentMethodType.WALLET,
|
||||
status: PaymentIntentStatus.PROCESSING,
|
||||
providerRef: `WALLET-DEMO-${Date.now()}`,
|
||||
},
|
||||
});
|
||||
await this.finalizePaymentSuccess({ intentId: demoIntent.id });
|
||||
const settled = await this.prisma.paymentIntent.findUniqueOrThrow({
|
||||
where: { id: demoIntent.id },
|
||||
});
|
||||
return this.formatIntentResponse(settled);
|
||||
}
|
||||
|
||||
const debitResult = await this.prisma.$transaction(async (tx) => {
|
||||
const wallet = await tx.walletAccount.findUnique({
|
||||
where: { passengerId: booking.passengerId },
|
||||
|
||||
@@ -17,6 +17,7 @@ export function buildCanonicalString(requestObject: Record<string, unknown>): st
|
||||
|
||||
for (const key of Object.keys(requestObject)) {
|
||||
if (EXCLUDE_FIELDS.has(key)) continue;
|
||||
if (requestObject[key] === undefined) continue;
|
||||
fieldMap[key] = requestObject[key];
|
||||
}
|
||||
|
||||
@@ -24,7 +25,9 @@ export function buildCanonicalString(requestObject: Record<string, unknown>): st
|
||||
if (biz && typeof biz === 'object') {
|
||||
for (const key of Object.keys(biz as Record<string, unknown>)) {
|
||||
if (EXCLUDE_FIELDS.has(key)) continue;
|
||||
fieldMap[key] = (biz as Record<string, unknown>)[key];
|
||||
const value = (biz as Record<string, unknown>)[key];
|
||||
if (value === undefined) continue;
|
||||
fieldMap[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ export class TelebirrProvider implements PaymentProvider {
|
||||
total_amount: totalAmount,
|
||||
trans_currency: input.currency,
|
||||
timeout_express: this.timeoutExpress,
|
||||
redirect_url: input.redirectUrl,
|
||||
...(input.redirectUrl ? { redirect_url: input.redirectUrl } : {}),
|
||||
},
|
||||
};
|
||||
const sign = signRequestObject(
|
||||
|
||||
Reference in New Issue
Block a user