adding bypass payment

This commit is contained in:
estifanos
2026-08-26 12:17:46 +00:00
parent f20ed670de
commit 3955dab014

View File

@@ -24,6 +24,7 @@ import {
TERMINAL_STATUSES, TERMINAL_STATUSES,
extractErrorMessage, extractErrorMessage,
useLocalized, useLocalized,
useBypassPaymentMutation,
useGetCertificateUrlMutation, useGetCertificateUrlMutation,
useGetMyApplicationsQuery, useGetMyApplicationsQuery,
useGetMyLicensesQuery, useGetMyLicensesQuery,
@@ -31,6 +32,7 @@ import {
import { useCurrentProfile } from '@ema-platform/auth'; import { useCurrentProfile } from '@ema-platform/auth';
import { AdvancedTable, PageLoader, notify, useServerTable } from '@ema-platform/ui'; import { AdvancedTable, PageLoader, notify, useServerTable } from '@ema-platform/ui';
import { useDateDisplayer } from '@ema-platform/shared'; import { useDateDisplayer } from '@ema-platform/shared';
import { useApplicationPayment } from '../../payments/hooks/useApplicationPayment';
import { endorsementColumns } from './columns'; import { endorsementColumns } from './columns';
// ENDORSEMENT_SEAFARER covers CoC and GOC together and is the only type new // ENDORSEMENT_SEAFARER covers CoC and GOC together and is the only type new
@@ -81,6 +83,8 @@ export function EndorsementPage() {
const showDate = useDateDisplayer(); const showDate = useDateDisplayer();
const localized = useLocalized(); const localized = useLocalized();
const [getCertificateUrl] = useGetCertificateUrlMutation(); const [getCertificateUrl] = useGetCertificateUrlMutation();
const { pay, isPaying } = useApplicationPayment();
const [bypassPayment, { isLoading: bypassing }] = useBypassPaymentMutation();
const issuedTable = useServerTable(); const issuedTable = useServerTable();
const registered = const registered =
@@ -97,6 +101,22 @@ export function EndorsementPage() {
); );
const issuedPage = issuedTable.paginate(issued); const issuedPage = issuedTable.paginate(issued);
async function handleBypass(applicationId: string) {
try {
const result = await bypassPayment(applicationId).unwrap();
notify.success(
result.certificateIssued
? t('endorsement.bypassIssued', 'Payment bypassed — the endorsement has been issued.')
: t('endorsement.bypassOk', {
defaultValue: 'Payment bypassed — application is now {{status}}.',
status: result.status.replace(/_/g, ' ').toLowerCase(),
}),
);
} catch (err) {
notify.error(extractErrorMessage(err, t('endorsement.bypassFailed', 'Bypass failed')));
}
}
async function download(licenseId: string) { async function download(licenseId: string) {
try { try {
const result = await getCertificateUrl(licenseId).unwrap(); const result = await getCertificateUrl(licenseId).unwrap();
@@ -182,6 +202,36 @@ export function EndorsementPage() {
<Badge color={STATUS_COLORS[app.status]}> <Badge color={STATUS_COLORS[app.status]}>
{t(`applications.status.${app.status}`, STATUS_LABELS[app.status])} {t(`applications.status.${app.status}`, STATUS_LABELS[app.status])}
</Badge> </Badge>
{app.status === 'PAYMENT_PENDING' && (
<>
<Button
size="compact-sm"
color="yellow"
loading={isPaying}
onClick={() => pay(app.id)}
>
{t('endorsement.pay', {
defaultValue: 'Pay {{amount}} {{currency}}',
amount: Number(app.feeAmount ?? 0).toLocaleString(),
currency: app.feeCurrency,
})}
</Button>
{/* ponytail: shown unconditionally for the testing
phase — the server still refuses it unless
ALLOW_PAYMENT_BYPASS is set and NODE_ENV is not
production. Re-gate on useGetPaymentCapabilitiesQuery
(like MyApplicationsPage) before prod. */}
<Button
size="compact-sm"
variant="default"
loading={bypassing}
onClick={() => handleBypass(app.id)}
title="Testing only — marks the fee paid"
>
{t('endorsement.bypass', 'Bypass payment')}
</Button>
</>
)}
<Button <Button
size="compact-sm" size="compact-sm"
variant="light" variant="light"