Skip to content

Commit

Permalink
[NFDIV-4314] Use payment service requests created by case-api (Part 1) (
Browse files Browse the repository at this point in the history
#3911)

* Pass payment callback URL to backend

* Remove unused import

* Update tests

* Formatting changes

* Adjust backend PR reference

* Remove references to backend PR
  • Loading branch information
adamg-hmcts authored Oct 4, 2024
1 parent d91e5e8 commit 2f75d71
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 18 deletions.
2 changes: 2 additions & 0 deletions src/main/app/case/case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ export const formFieldsToCaseMapping: Partial<Record<keyof Case, keyof CaseData>
applicant1CanIntendToSwitchToSoleFo: 'applicant1CanIntendToSwitchToSoleFo',
applicant2CanIntendToSwitchToSoleFo: 'applicant2CanIntendToSwitchToSoleFo',
isFinalOrderOverdue: 'isFinalOrderOverdue',
citizenPaymentCallbackUrl: 'citizenPaymentCallbackUrl',
};

export function formatCase<OutputFormat>(fields: FieldFormats, data: Partial<Case> | CaseData): OutputFormat {
Expand Down Expand Up @@ -397,6 +398,7 @@ export interface Case {
applicant1CanIntendToSwitchToSoleFo: YesOrNo;
applicant2CanIntendToSwitchToSoleFo: YesOrNo;
isFinalOrderOverdue: YesOrNo;
citizenPaymentCallbackUrl: string;
}

export interface CaseWithId extends Case {
Expand Down
1 change: 1 addition & 0 deletions src/main/app/case/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,7 @@ export interface CaseData {
evidenceHandled: YesOrNo;
generalLetters: ListValue<GeneralLetterDetails>[];
sentNotifications: SentNotifications;
citizenPaymentCallbackUrl: string;
}

export interface CaseDocuments {
Expand Down
6 changes: 1 addition & 5 deletions src/main/app/controller/BasePaymentCallbackGetController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Logger } from '@hmcts/nodejs-logging';
import autobind from 'autobind-decorator';
import config from 'config';
import { Response } from 'express';

import { CaseData, State } from '../case/definition';
Expand All @@ -18,11 +17,8 @@ export default abstract class BasePaymentCallbackGetController {
if (req.session.userCase.state !== this.awaitingPaymentState()) {
return res.redirect(this.noPaymentRequiredUrl(req));
}
const protocol = req.app.locals.developmentMode ? 'http://' : 'https://';
const port = req.app.locals.developmentMode ? `:${config.get('port')}` : '';
const returnUrl = `${protocol}${res.locals.host}${port}${getPaymentCallbackUrl(req)}`;

const paymentClient = new PaymentClient(req.session, returnUrl);
const paymentClient = new PaymentClient(req.session, getPaymentCallbackUrl(req, res));

const payments = new PaymentModel(req.session.userCase[this.paymentsCaseField()] || []);
if (!payments.hasPayment) {
Expand Down
22 changes: 12 additions & 10 deletions src/main/app/controller/BasePaymentPostController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@ export default abstract class BasePaymentPostController {
if (req.session.userCase.state !== this.awaitingPaymentState()) {
req.session.userCase = await req.locals.api.triggerEvent(
req.session.userCase.id,
{},
{ citizenPaymentCallbackUrl: getPaymentCallbackUrl(req, res) },
this.awaitingPaymentEvent()
);
}

const payments = new PaymentModel(req.session.userCase[this.paymentsCaseField()] || []);

if (payments.isPaymentInProgress()) {
return this.saveAndRedirect(req, res, getPaymentCallbackUrl(req));
return this.saveAndRedirect(req, res, getPaymentCallbackPath(req));
}

const paymentClient = this.getPaymentClient(req, res);
const paymentClient = this.getPaymentClient(req, getPaymentCallbackUrl(req, res));
const payment = await this.createServiceRefAndTakePayment(req, paymentClient, payments);

this.saveAndRedirect(req, res, payment.next_url);
Expand All @@ -57,12 +57,8 @@ export default abstract class BasePaymentPostController {
});
}

private getPaymentClient(req: AppRequest, res: Response) {
const protocol = req.app.locals.developmentMode ? 'http://' : 'https://';
const port = req.app.locals.developmentMode ? `:${config.get('port')}` : '';
const returnUrl = `${protocol}${res.locals.host}${port}${getPaymentCallbackUrl(req)}`;

return new PaymentClient(req.session, returnUrl);
private getPaymentClient(req: AppRequest, callbackUrl: string) {
return new PaymentClient(req.session, callbackUrl);
}

private async createServiceRefAndTakePayment(
Expand Down Expand Up @@ -115,7 +111,13 @@ export default abstract class BasePaymentPostController {
protected abstract getResponsiblePartyName(req: AppRequest<AnyObject>): string | undefined;
}

export function getPaymentCallbackUrl(req: AppRequest): string {
export function getPaymentCallbackUrl(req: AppRequest, res: Response): string {
const protocol = req.app.locals.developmentMode ? 'http://' : 'https://';
const port = req.app.locals.developmentMode ? `:${config.get('port')}` : '';
return `${protocol}${res.locals.host}${port}${getPaymentCallbackPath(req)}`;
}

export function getPaymentCallbackPath(req: AppRequest): string {
const isRespondent: boolean =
req.session.isApplicant2 && req.session.userCase.applicationType === ApplicationType.SOLE_APPLICATION;

Expand Down
11 changes: 10 additions & 1 deletion src/main/app/controller/PostController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { Response } from 'express';
import { getNextStepUrl } from '../../steps';
import { SAVE_AND_SIGN_OUT } from '../../steps/urls';
import { Case, CaseWithId } from '../case/case';
import { CITIZEN_APPLICANT2_UPDATE, CITIZEN_SAVE_AND_CLOSE, CITIZEN_UPDATE } from '../case/definition';
import { CITIZEN_APPLICANT2_UPDATE, CITIZEN_SAVE_AND_CLOSE, CITIZEN_SUBMIT, CITIZEN_UPDATE } from '../case/definition';
import { Form, FormFields, FormFieldsFn } from '../form/Form';

import { AppRequest } from './AppRequest';
import { getPaymentCallbackUrl } from './BasePaymentPostController';

@autobind
export class PostController<T extends AnyObject> {
Expand Down Expand Up @@ -75,6 +76,8 @@ export class PostController<T extends AnyObject> {

if (req.session.errors.length === 0) {
try {
this.setPaymentCallbackUrlIfPaymentRequired(req, res, formData);

req.session.userCase = await this.save(req, formData, this.getEventName(req));
} catch (err) {
req.locals.logger.error('Error saving', err);
Expand All @@ -96,6 +99,12 @@ export class PostController<T extends AnyObject> {
return CITIZEN_UPDATE;
}
}

private setPaymentCallbackUrlIfPaymentRequired(req: AppRequest<T>, res: Response, formData: Partial<Case>) {
if (this.getEventName(req) === CITIZEN_SUBMIT) {
formData.citizenPaymentCallbackUrl = getPaymentCallbackUrl(req, res);
}
}
}

export type AnyObject = Record<string, unknown>;
2 changes: 2 additions & 0 deletions src/main/steps/applicant1/check-your-answers/post.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe('CheckYourAnswersPostController', () => {
applicationType: ApplicationType.SOLE_APPLICATION,
applicant1IConfirmPrayer: Checkbox.Checked,
applicant1StatementOfTruth: Checkbox.Checked,
citizenPaymentCallbackUrl: 'https://undefined/payment-callback',
};
const checkYourAnswerPostController = new CheckYourAnswersPostController(mockFormContent.fields);

Expand Down Expand Up @@ -112,6 +113,7 @@ describe('CheckYourAnswersPostController', () => {
state: State.Draft,
applicant1IConfirmPrayer: Checkbox.Checked,
applicant1StatementOfTruth: Checkbox.Checked,
citizenPaymentCallbackUrl: 'https://undefined/payment-callback',
};
const checkYourAnswerPostController = new CheckYourAnswersPostController(mockFormContent.fields);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ describe('Applicant1ConfirmYourJointApplicationPostController', () => {
const body = {
applicant1IConfirmPrayer: Checkbox.Checked,
applicant1StatementOfTruth: Checkbox.Checked,
citizenPaymentCallbackUrl: 'https://undefined/payment-callback',
};
const mockFormContent = {
fields: {
Expand All @@ -38,6 +39,7 @@ describe('Applicant1ConfirmYourJointApplicationPostController', () => {
const body = {
applicant1IConfirmPrayer: Checkbox.Checked,
applicant1StatementOfTruth: Checkbox.Checked,
citizenPaymentCallbackUrl: 'https://undefined/payment-callback',
};
const mockFormContent = {
fields: {
Expand Down
6 changes: 5 additions & 1 deletion src/main/steps/applicant1/pay-your-fee/post.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ describe('PaymentPostController', () => {

await paymentController.post(req, res);

expect(req.locals.api.triggerEvent).toHaveBeenCalledWith('1234', {}, CITIZEN_SUBMIT);
expect(req.locals.api.triggerEvent).toHaveBeenCalledWith(
'1234',
{ citizenPaymentCallbackUrl: 'https://undefined/payment-callback' },
CITIZEN_SUBMIT
);
});

it('redirects to the check your answers page if last payment is in progress', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ describe('PaymentPostController', () => {

await paymentController.post(req, res);

expect(req.locals.api.triggerEvent).toHaveBeenCalledWith('1234', {}, RESPONDENT_APPLY_FOR_FINAL_ORDER);
expect(req.locals.api.triggerEvent).toHaveBeenCalledWith(
'1234',
{ citizenPaymentCallbackUrl: 'https://undefined/payment-callback' },
RESPONDENT_APPLY_FOR_FINAL_ORDER
);
});

it('redirects to hub page if last payment is in progress', async () => {
Expand Down

0 comments on commit 2f75d71

Please sign in to comment.