Skip to content

Commit fc4c4f7

Browse files
authored
fix(DF-626): payment formatting and add test (#305)
* ix: payment formatting and add test * chore: update payment-test.yaml to change payment amount from 300 to 10000 * refactor: improve currency formatting and add tests
1 parent 2322ed2 commit fc4c4f7

9 files changed

Lines changed: 42 additions & 26 deletions

File tree

src/server/forms/payment-test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pages:
2727
type: PaymentField
2828
options:
2929
required: true
30-
amount: 300
30+
amount: 10000
3131
description: Processing fee for your application.
3232
next:
3333
- path: '/summary'

src/server/plugins/engine/components/PaymentField.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ describe('PaymentField', () => {
196196
label: { text: def.title },
197197
name: 'myComponent',
198198
id: 'myComponent',
199-
amount: '100.00',
199+
amount: '£100.00',
200200
attributes: {},
201201
description: 'Test payment description'
202202
})
@@ -220,7 +220,7 @@ describe('PaymentField', () => {
220220
label: { text: def.title },
221221
name: 'myComponent',
222222
id: 'myComponent',
223-
amount: '100.00',
223+
amount: '£100.00',
224224
attributes: {},
225225
description: 'Test payment description'
226226
})

src/server/plugins/engine/components/PaymentField.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ import {
2929
type FormSubmissionError,
3030
type FormSubmissionState
3131
} from '~/src/server/plugins/engine/types.js'
32-
import { createPaymentService } from '~/src/server/plugins/payment/helper.js'
32+
import {
33+
createPaymentService,
34+
formatCurrency
35+
} from '~/src/server/plugins/payment/helper.js'
3336

3437
export class PaymentField extends FormComponent {
3538
declare options: PaymentFieldComponent['options']
@@ -91,7 +94,7 @@ export class PaymentField extends FormComponent {
9194
return ''
9295
}
9396

94-
return `£${value.amount.toFixed(2)} - ${value.description}`
97+
return `${formatCurrency(value.amount)} - ${value.description}`
9598
}
9699

97100
getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {
@@ -105,11 +108,9 @@ export class PaymentField extends FormComponent {
105108
// When user initially visits the payment page, there is no payment state yet so the amount is read form the form definition.
106109
const amount = paymentState?.amount ?? this.options.amount
107110

108-
const formattedAmount = amount.toFixed(2)
109-
110111
return {
111112
...viewModel,
112-
amount: formattedAmount,
113+
amount: formatCurrency(amount),
113114
description: this.options.description,
114115
paymentState
115116
}
@@ -153,7 +154,7 @@ export class PaymentField extends FormComponent {
153154

154155
getContextValueFromState(state: FormSubmissionState) {
155156
return this.isPaymentState(state)
156-
? `Reference: ${state.reference}\nAmount: ${state.amount.toFixed(2)}`
157+
? `Reference: ${state.reference}\nAmount: ${formatCurrency(state.amount)}`
157158
: ''
158159
}
159160

src/server/plugins/engine/outputFormatters/human/v1.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
} from '~/src/server/plugins/engine/models/types.js'
1717
import { type FormContext } from '~/src/server/plugins/engine/types.js'
1818
import {
19-
formatPaymentAmount,
19+
formatCurrency,
2020
formatPaymentDate
2121
} from '~/src/server/plugins/payment/helper.js'
2222

@@ -115,7 +115,7 @@ function appendPaymentSection(paymentItems: DetailItem[], lines: string[]) {
115115
return
116116
}
117117

118-
const formattedAmount = formatPaymentAmount(paymentState.amount)
118+
const formattedAmount = formatCurrency(paymentState.amount)
119119
const dateOfPayment = paymentState.preAuth?.createdAt
120120
? formatPaymentDate(paymentState.preAuth.createdAt)
121121
: ''

src/server/plugins/engine/pageControllers/SummaryPageController.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import {
4646
} from '~/src/server/plugins/engine/types.js'
4747
import {
4848
DEFAULT_PAYMENT_HELP_URL,
49-
formatPaymentAmount,
49+
formatCurrency,
5050
formatPaymentDate
5151
} from '~/src/server/plugins/payment/helper.js'
5252
import {
@@ -125,7 +125,7 @@ export class SummaryPageController extends QuestionPageController {
125125
},
126126
{
127127
key: { text: 'Total amount' },
128-
value: { text: formatPaymentAmount(paymentState.amount) }
128+
value: { text: formatCurrency(paymentState.amount) }
129129
},
130130
{
131131
key: { text: 'Reference' },

src/server/plugins/engine/pageControllers/helpers/submission.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
type DetailItemField
88
} from '~/src/server/plugins/engine/models/types.js'
99
import {
10-
formatPaymentAmount,
10+
formatCurrency,
1111
formatPaymentDate
1212
} from '~/src/server/plugins/payment/helper.js'
1313

@@ -71,7 +71,7 @@ export function buildPaymentRecords(item: DetailItemField): SubmitRecord[] {
7171
{
7272
name: `${item.name}_paymentAmount`,
7373
title: 'Payment amount',
74-
value: formatPaymentAmount(paymentState.amount)
74+
value: formatCurrency(paymentState.amount)
7575
},
7676
{
7777
name: `${item.name}_paymentReference`,

src/server/plugins/engine/views/components/paymentfield.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ <h2 class="govuk-heading-m">{{ model.label.text if model.label and model.label.t
2828
<p class="govuk-body">You can submit the form after you have added your payment details.</p>
2929

3030
<p class="govuk-body govuk-!-margin-bottom-1">Total amount:</p>
31-
<p class="govuk-heading-l govuk-!-margin-bottom-4 govuk-!-padding-top-0">£{{ amount }}</p>
31+
<p class="govuk-heading-l govuk-!-margin-bottom-4 govuk-!-padding-top-0">{{ amount }}</p>
3232

3333
{{ govukButton({
3434
text: "Add payment details",

src/server/plugins/payment/helper.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,17 @@ export function formatPaymentDate(isoString) {
4747
}
4848

4949
/**
50-
* Formats a payment amount with two decimal places
50+
* Formats a currency amount with thousand separators and two decimal places
5151
* @param {number} amount - amount in pounds
52-
* @returns {string} Formatted amount (e.g., "£10.00")
52+
* @param {'en-GB'} [locale] - locale for formatting
53+
* @param {'GBP'} [currency] - currency code
54+
* @returns {string} Formatted amount (e.g., "£1,234.56")
5355
*/
54-
export function formatPaymentAmount(amount) {
55-
return ${amount.toFixed(2)}`
56+
export function formatCurrency(amount, locale = 'en-GB', currency = 'GBP') {
57+
const formatter = new Intl.NumberFormat(locale, {
58+
style: 'currency',
59+
currency
60+
})
61+
62+
return formatter.format(amount)
5663
}

src/server/plugins/payment/helper.test.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { config } from '~/src/config/index.js'
22
import {
3-
formatPaymentAmount,
3+
formatCurrency,
44
formatPaymentDate,
55
getPaymentApiKey
66
} from '~/src/server/plugins/payment/helper.js'
@@ -41,12 +41,20 @@ describe('formatPaymentDate', () => {
4141
})
4242
})
4343

44-
describe('formatPaymentAmount', () => {
45-
it('should format whole number with two decimal places', () => {
46-
expect(formatPaymentAmount(10)).toBe('£10.00')
44+
describe('formatCurrency', () => {
45+
it('should format whole number with currency symbol', () => {
46+
expect(formatCurrency(10)).toBe('£10.00')
4747
})
4848

49-
it('should format decimal amount', () => {
50-
expect(formatPaymentAmount(99.5)).toBe('£99.50')
49+
it('should format decimal amount with currency symbol', () => {
50+
expect(formatCurrency(99.5)).toBe('£99.50')
51+
})
52+
53+
it('should format large amounts with thousand separators', () => {
54+
expect(formatCurrency(1234.56)).toBe('£1,234.56')
55+
})
56+
57+
it('should format very large amounts with thousand separators', () => {
58+
expect(formatCurrency(20000)).toBe('£20,000.00')
5159
})
5260
})

0 commit comments

Comments
 (0)