diff --git a/apps/portal/src/app/features/endorsement/pages/EndorsementPage.tsx b/apps/portal/src/app/features/endorsement/pages/EndorsementPage.tsx
index a74a54be7..c6ce7252d 100644
--- a/apps/portal/src/app/features/endorsement/pages/EndorsementPage.tsx
+++ b/apps/portal/src/app/features/endorsement/pages/EndorsementPage.tsx
@@ -24,6 +24,7 @@ import {
TERMINAL_STATUSES,
extractErrorMessage,
useLocalized,
+ useBypassPaymentMutation,
useGetCertificateUrlMutation,
useGetMyApplicationsQuery,
useGetMyLicensesQuery,
@@ -31,6 +32,7 @@ import {
import { useCurrentProfile } from '@ema-platform/auth';
import { AdvancedTable, PageLoader, notify, useServerTable } from '@ema-platform/ui';
import { useDateDisplayer } from '@ema-platform/shared';
+import { useApplicationPayment } from '../../payments/hooks/useApplicationPayment';
import { endorsementColumns } from './columns';
// ENDORSEMENT_SEAFARER covers CoC and GOC together and is the only type new
@@ -81,6 +83,8 @@ export function EndorsementPage() {
const showDate = useDateDisplayer();
const localized = useLocalized();
const [getCertificateUrl] = useGetCertificateUrlMutation();
+ const { pay, isPaying } = useApplicationPayment();
+ const [bypassPayment, { isLoading: bypassing }] = useBypassPaymentMutation();
const issuedTable = useServerTable();
const registered =
@@ -97,6 +101,22 @@ export function EndorsementPage() {
);
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) {
try {
const result = await getCertificateUrl(licenseId).unwrap();
@@ -182,6 +202,36 @@ export function EndorsementPage() {
{t(`applications.status.${app.status}`, STATUS_LABELS[app.status])}
+ {app.status === 'PAYMENT_PENDING' && (
+ <>
+
+ {/* 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. */}
+
+ >
+ )}