Skip to content

Commit 3eaddb4

Browse files
ROC-6905 Add cancel payment operation
2 parents 1f3e1ea + 1f9ec81 commit 3eaddb4

7 files changed

Lines changed: 196 additions & 39 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class PaymentsService {
3232
public PaymentDTO retrievePayment(String authorisation, String paymentReference) {
3333
return paymentsClient.retrievePayment(authorisation, paymentReference);
3434
}
35+
36+
public void cancelPayment(String authorisation, String paymentReference) {
37+
paymentsClient.cancelPayment(authorisation, paymentReference);
38+
}
3539
}
3640

3741
```

src/functionalTest/java/uk/gov/hmcts/reform/payments/client/functional/CreatePaymentTest.java

Lines changed: 126 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class CreatePaymentTest extends BaseTest {
3232
private static final String FEE_VERSION = "version";
3333
private static final Integer FEE_VOLUME = 1;
3434
private static final String INITIATED_STATUS = "Initiated";
35+
private static final String FAILED_STATUS = "Failed";
3536
private static final String JURISDICTION_1 = "jurisdiction 1";
3637
private static final String JURISDICTION_2 = "jurisdiction 2";
3738
private static final String MEMO_LINE = "Memo line";
@@ -45,44 +46,63 @@ class CreatePaymentTest extends BaseTest {
4546
private static final String SERVICE_NAME = "Civil Money Claims";
4647
private static final String SITE_ID = "AA00";
4748

49+
private static final CardPaymentRequest CARD_PAYMENT_REQUEST = CardPaymentRequest.builder()
50+
.caseReference(UUID.randomUUID().toString())
51+
.ccdCaseNumber(CCD_CASE_NUMBER)
52+
.description(PAYMENT_DESCRIPTION)
53+
.service(SERVICE)
54+
.currency(CURRENCY)
55+
.siteId(SITE_ID)
56+
.fees(new FeeDto[]{
57+
FeeDto.builder()
58+
.id(1)
59+
.calculatedAmount(FEE_AMOUNT)
60+
.ccdCaseNumber(CCD_CASE_NUMBER)
61+
.code(FEE_CODE)
62+
.description(FEE_DESCRIPTION)
63+
.jurisdiction1(JURISDICTION_1)
64+
.jurisdiction2(JURISDICTION_2)
65+
.memoLine(MEMO_LINE)
66+
.naturalAccountCode(NATURAL_ACCOUNT_CODE)
67+
.netAmount(NET_FEE_AMOUNT)
68+
.reference(FEE_REFERENCE)
69+
.version(FEE_VERSION)
70+
.volume(FEE_VOLUME)
71+
.build()
72+
})
73+
.amount(PAYMENT_AMOUNT)
74+
.build();
75+
4876
@Test
49-
void canCreateAndRetrievePayments() {
77+
void canCreateRetrieveAndCancelPayments() {
5078
User citizen = createCitizen();
5179
PaymentDto createdPayment = paymentsClient.createPayment(
52-
citizen.getAuthToken(),
53-
CardPaymentRequest.builder()
54-
.caseReference(UUID.randomUUID().toString())
55-
.ccdCaseNumber(CCD_CASE_NUMBER)
56-
.description(PAYMENT_DESCRIPTION)
57-
.service(SERVICE)
58-
.currency(CURRENCY)
59-
.siteId(SITE_ID)
60-
.fees(new FeeDto[]{
61-
FeeDto.builder()
62-
.id(1)
63-
.calculatedAmount(FEE_AMOUNT)
64-
.ccdCaseNumber(CCD_CASE_NUMBER)
65-
.code(FEE_CODE)
66-
.description(FEE_DESCRIPTION)
67-
.jurisdiction1(JURISDICTION_1)
68-
.jurisdiction2(JURISDICTION_2)
69-
.memoLine(MEMO_LINE)
70-
.naturalAccountCode(NATURAL_ACCOUNT_CODE)
71-
.netAmount(NET_FEE_AMOUNT)
72-
.reference(FEE_REFERENCE)
73-
.version(FEE_VERSION)
74-
.volume(FEE_VOLUME)
75-
.build()
76-
})
77-
.amount(PAYMENT_AMOUNT)
78-
.build(),
79-
"https://www.google.com"
80+
citizen.getAuthToken(),
81+
CARD_PAYMENT_REQUEST,
82+
"https://www.google.com"
8083
);
84+
verifyCreatedPayment(createdPayment);
8185

82-
assertNotNull(createdPayment);
8386
final String paymentGroupReference = createdPayment.getPaymentGroupReference();
8487
final String reference = createdPayment.getReference();
8588

89+
PaymentDto retrievedPayment = paymentsClient.retrievePayment(
90+
citizen.getAuthToken(),
91+
reference
92+
);
93+
verifyRetrievedPayment(retrievedPayment, paymentGroupReference, reference);
94+
95+
paymentsClient.cancelPayment(citizen.getAuthToken(), reference);
96+
97+
PaymentDto cancelledPayment = paymentsClient.retrievePayment(
98+
citizen.getAuthToken(),
99+
reference
100+
);
101+
verifyCancelledPayment(cancelledPayment, paymentGroupReference, reference);
102+
}
103+
104+
private PaymentDto verifyCreatedPayment(PaymentDto createdPayment) {
105+
assertNotNull(createdPayment);
86106
assertAll("created payment",
87107
() -> assertAll("links",
88108
() -> assertNotNull(createdPayment.getLinks()),
@@ -122,16 +142,19 @@ void canCreateAndRetrievePayments() {
122142
() -> assertNotNull(createdPayment.getExternalReference())
123143
),
124144
() -> assertAll("expected matching values",
125-
() -> assertNotNull(paymentGroupReference),
126-
() -> assertNotNull(reference)
145+
() -> assertNotNull(createdPayment.getPaymentGroupReference()),
146+
() -> assertNotNull(createdPayment.getReference())
127147
)
128148
);
129149

130-
PaymentDto retrievedPayment = paymentsClient.retrievePayment(
131-
citizen.getAuthToken(),
132-
createdPayment.getReference()
133-
);
150+
return createdPayment;
151+
}
134152

153+
private void verifyRetrievedPayment(
154+
PaymentDto retrievedPayment,
155+
String expectedPaymentGroupReference,
156+
String expectedReference
157+
) {
135158
assertNotNull(retrievedPayment);
136159

137160
assertAll("retrieved payment",
@@ -168,8 +191,72 @@ void canCreateAndRetrievePayments() {
168191
() -> assertEquals(INITIATED_STATUS, retrievedPayment.getStatus())
169192
),
170193
() -> assertAll("expected matching values",
171-
() -> assertEquals(paymentGroupReference, retrievedPayment.getPaymentGroupReference()),
172-
() -> assertEquals(reference, retrievedPayment.getReference())
194+
() -> assertEquals(expectedPaymentGroupReference, retrievedPayment.getPaymentGroupReference()),
195+
() -> assertEquals(expectedReference, retrievedPayment.getReference())
196+
),
197+
() -> assertAll("fees",
198+
() -> assertNotNull(retrievedPayment.getFees()),
199+
() -> assertEquals(1, retrievedPayment.getFees().length),
200+
() -> assertEquals(FEE_AMOUNT, retrievedPayment.getFees()[0].getCalculatedAmount()),
201+
() -> assertEquals(CCD_CASE_NUMBER, retrievedPayment.getFees()[0].getCcdCaseNumber()),
202+
() -> assertEquals(FEE_CODE, retrievedPayment.getFees()[0].getCode()),
203+
() -> assertNull(retrievedPayment.getFees()[0].getDescription()),
204+
() -> assertNotNull(retrievedPayment.getFees()[0].getId()),
205+
() -> assertNull(retrievedPayment.getFees()[0].getJurisdiction1()),
206+
() -> assertNull(retrievedPayment.getFees()[0].getJurisdiction2()),
207+
() -> assertNull(retrievedPayment.getFees()[0].getMemoLine()),
208+
() -> assertNull(retrievedPayment.getFees()[0].getNaturalAccountCode()),
209+
() -> assertNull(retrievedPayment.getFees()[0].getNetAmount()),
210+
() -> assertEquals(FEE_REFERENCE, retrievedPayment.getFees()[0].getReference()),
211+
() -> assertEquals(FEE_VERSION, retrievedPayment.getFees()[0].getVersion()),
212+
() -> assertEquals(FEE_VOLUME, retrievedPayment.getFees()[0].getVolume())
213+
)
214+
);
215+
}
216+
217+
private void verifyCancelledPayment(
218+
PaymentDto retrievedPayment,
219+
String expectedPaymentGroupReference,
220+
String expectedReference
221+
) {
222+
assertNotNull(retrievedPayment);
223+
224+
assertAll("retrieved payment",
225+
() -> assertAll("links",
226+
() -> assertNotNull(retrievedPayment.getLinks()),
227+
() -> assertNull(retrievedPayment.getLinks().getNextUrl()),
228+
() -> assertNotNull(retrievedPayment.getLinks().getSelf()),
229+
() -> assertNotNull(retrievedPayment.getLinks().getSelf().getHref()),
230+
() -> assertEquals(RequestMethod.GET, retrievedPayment.getLinks().getSelf().getMethod()),
231+
() -> assertNull(retrievedPayment.getLinks().getCancel())
232+
),
233+
() -> assertAll("expected to be null",
234+
() -> assertNull(retrievedPayment.getAccountNumber()),
235+
() -> assertNull(retrievedPayment.getCustomerReference()),
236+
() -> assertNull(retrievedPayment.getDateCreated()),
237+
() -> assertNull(retrievedPayment.getDateUpdated()),
238+
() -> assertNull(retrievedPayment.getGiroSlipNo()),
239+
() -> assertNull(retrievedPayment.getId()),
240+
() -> assertNull(retrievedPayment.getOrganisationName()),
241+
() -> assertNull(retrievedPayment.getPaymentReference()),
242+
() -> assertNull(retrievedPayment.getReportedDateOffline()),
243+
() -> assertNull(retrievedPayment.getStatusHistories())
244+
),
245+
() -> assertAll("expected known values",
246+
() -> assertEquals(BigDecimal.TEN, retrievedPayment.getAmount()),
247+
() -> assertEquals(CCD_CASE_NUMBER, retrievedPayment.getCcdCaseNumber()),
248+
() -> assertEquals(ONLINE_CHANNEL, retrievedPayment.getChannel()),
249+
() -> assertEquals(CURRENCY, retrievedPayment.getCurrency()),
250+
() -> assertEquals(PAYMENT_DESCRIPTION, retrievedPayment.getDescription()),
251+
() -> assertEquals(EXTERNAL_PROVIDER, retrievedPayment.getExternalProvider()),
252+
() -> assertEquals(PAYMENT_METHOD, retrievedPayment.getMethod()),
253+
() -> assertEquals(SERVICE_NAME, retrievedPayment.getServiceName()),
254+
() -> assertEquals(SITE_ID, retrievedPayment.getSiteId()),
255+
() -> assertEquals(FAILED_STATUS, retrievedPayment.getStatus())
256+
),
257+
() -> assertAll("expected matching values",
258+
() -> assertEquals(expectedPaymentGroupReference, retrievedPayment.getPaymentGroupReference()),
259+
() -> assertEquals(expectedReference, retrievedPayment.getReference())
173260
),
174261
() -> assertAll("fees",
175262
() -> assertNotNull(retrievedPayment.getFees()),
@@ -183,7 +270,7 @@ void canCreateAndRetrievePayments() {
183270
() -> assertNull(retrievedPayment.getFees()[0].getJurisdiction2()),
184271
() -> assertNull(retrievedPayment.getFees()[0].getMemoLine()),
185272
() -> assertNull(retrievedPayment.getFees()[0].getNaturalAccountCode()),
186-
() -> assertEquals(NET_FEE_AMOUNT, retrievedPayment.getFees()[0].getNetAmount()),
273+
() -> assertNull(retrievedPayment.getFees()[0].getNetAmount()),
187274
() -> assertEquals(FEE_REFERENCE, retrievedPayment.getFees()[0].getReference()),
188275
() -> assertEquals(FEE_VERSION, retrievedPayment.getFees()[0].getVersion()),
189276
() -> assertEquals(FEE_VOLUME, retrievedPayment.getFees()[0].getVolume())

src/main/java/uk/gov/hmcts/reform/payments/client/PaymentsApi.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,11 @@ PaymentDto retrieve(
2828
@RequestHeader("Authorization") String authorization,
2929
@RequestHeader("ServiceAuthorization") String serviceAuthorization
3030
);
31+
32+
@PostMapping(value = "/card-payments/{paymentReference}/cancel")
33+
void cancel(
34+
@PathVariable("paymentReference") String paymentReference,
35+
@RequestHeader("Authorization") String authorization,
36+
@RequestHeader("ServiceAuthorization") String serviceAuthorization
37+
);
3138
}

src/main/java/uk/gov/hmcts/reform/payments/client/PaymentsClient.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,12 @@ public PaymentDto retrievePayment(String authorisation, String paymentReference)
3434
authTokenGenerator.generate()
3535
);
3636
}
37+
38+
public void cancelPayment(String authorisation, String paymentReference) {
39+
paymentsApi.cancel(
40+
paymentReference,
41+
authorisation,
42+
authTokenGenerator.generate()
43+
);
44+
}
3745
}

src/test/java/uk/gov/hmcts/reform/payments/client/PaymentsClientTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
import org.junit.jupiter.api.extension.ExtendWith;
66
import org.mockito.Mock;
77
import org.mockito.junit.jupiter.MockitoExtension;
8+
import org.springframework.http.HttpStatus;
9+
import org.springframework.web.client.HttpClientErrorException;
810
import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator;
911

1012
import java.math.BigDecimal;
1113

1214
import static org.assertj.core.api.Assertions.assertThatThrownBy;
15+
import static org.mockito.ArgumentMatchers.anyString;
16+
import static org.mockito.Mockito.doThrow;
1317
import static org.mockito.Mockito.verify;
1418
import static org.mockito.Mockito.when;
1519

@@ -55,6 +59,13 @@ void retrievePaymentShouldInvokePaymentsApi() {
5559
verify(paymentsApi).retrieve("payment reference", "authorisation", "auth token");
5660
}
5761

62+
@Test
63+
void cancelPaymentShouldInvokePaymentsApi() {
64+
client.cancelPayment("authorisation", "payment reference");
65+
66+
verify(paymentsApi).cancel("payment reference", "authorisation", "auth token");
67+
}
68+
5869
@Test
5970
void createPaymentShouldPropagateExceptions() {
6071
when(authTokenGenerator.generate())
@@ -74,4 +85,14 @@ void retrievePaymentShouldPropagateExceptions() {
7485
.isInstanceOf(RuntimeException.class)
7586
.hasMessage("expected exception for retrieve payment");
7687
}
88+
89+
@Test
90+
void cancelPaymentShouldPropagateExceptions() {
91+
doThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND, "Payment Not found"))
92+
.when(paymentsApi).cancel(anyString(), anyString(), anyString());
93+
94+
assertThatThrownBy(() -> client.cancelPayment("authorisation", "payment reference"))
95+
.isInstanceOf(HttpClientErrorException.class)
96+
.hasMessage("404 Payment Not found");
97+
}
7798
}

src/test/java/uk/gov/hmcts/reform/payments/client/PaymentsClientWiremockTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ void testRetrievePayment() {
102102
);
103103
}
104104

105+
@Test
106+
void testCancelPayment() {
107+
// test passes if no exceptions are thrown
108+
paymentsClient.cancelPayment("Authorisation", "RC-7238-3245-0193-7732");
109+
}
110+
105111
@Service
106112
static class ServiceTestSupportAuthTokenGenerator implements AuthTokenGenerator {
107113
@Override
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"id": "21e5df7c-6afa-404c-a44f-8354e18297c3",
3+
"name": "card-payments_rc-7238-3245-0193-7732",
4+
"request": {
5+
"url": "/card-payments/RC-7238-3245-0193-7732/cancel",
6+
"method": "POST"
7+
},
8+
"response": {
9+
"status": 204,
10+
"body": "{}",
11+
"headers": {
12+
"X-Content-Type-Options": "nosniff",
13+
"X-XSS-Protection": "1; mode=block",
14+
"Cache-Control": "no-cache, no-store, max-age=0, must-revalidate",
15+
"Pragma": "no-cache",
16+
"Expires": "0",
17+
"X-Frame-Options": "DENY",
18+
"Content-Type": "application/json;charset=UTF-8",
19+
"Date": "Mon, 19 Aug 2019 09:46:54 GMT"
20+
}
21+
},
22+
"uuid": "21e5df7c-6afa-404c-a44f-8354e18297c3",
23+
"persistent": true
24+
}

0 commit comments

Comments
 (0)