Skip to content

Commit e73b5c8

Browse files
committed
feat(ACL-251): Adds method to generate SU+ Authentication URI for FI payments
1 parent 653cd57 commit e73b5c8

File tree

9 files changed

+130
-18
lines changed

9 files changed

+130
-18
lines changed

src/main/java/com/truelayer/java/signupplus/ISignupPlusApi.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
import com.truelayer.java.entities.RequestScopes;
44
import com.truelayer.java.http.entities.ApiResponse;
5+
import com.truelayer.java.signupplus.entities.GenerateAuthUriRequest;
6+
import com.truelayer.java.signupplus.entities.GenerateAuthUriResponse;
57
import com.truelayer.java.signupplus.entities.UserData;
68
import java.util.concurrent.CompletableFuture;
7-
import retrofit2.http.GET;
8-
import retrofit2.http.Query;
9-
import retrofit2.http.Tag;
9+
import retrofit2.http.*;
1010

1111
public interface ISignupPlusApi {
1212

@@ -20,4 +20,8 @@ public interface ISignupPlusApi {
2020
@GET("/signup-plus/payments")
2121
CompletableFuture<ApiResponse<UserData>> getUserDataByPayment(
2222
@Tag RequestScopes scopes, @Query("payment_id") String paymentId);
23+
24+
@POST("/signup-plus/authuri")
25+
CompletableFuture<ApiResponse<GenerateAuthUriResponse>> generateAuthUri(
26+
@Tag RequestScopes scopes, @Body GenerateAuthUriRequest request);
2327
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.truelayer.java.signupplus;
22

33
import com.truelayer.java.http.entities.ApiResponse;
4+
import com.truelayer.java.signupplus.entities.GenerateAuthUriRequest;
5+
import com.truelayer.java.signupplus.entities.GenerateAuthUriResponse;
46
import com.truelayer.java.signupplus.entities.UserData;
57
import java.util.concurrent.CompletableFuture;
68

79
public interface ISignupPlusHandler {
810

911
CompletableFuture<ApiResponse<UserData>> getUserDataByPayment(String paymentId);
12+
13+
CompletableFuture<ApiResponse<GenerateAuthUriResponse>> generateAuthUri(GenerateAuthUriRequest request);
1014
}

src/main/java/com/truelayer/java/signupplus/SignupPlusHandler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.truelayer.java.IAuthenticatedHandler;
66
import com.truelayer.java.entities.RequestScopes;
77
import com.truelayer.java.http.entities.ApiResponse;
8+
import com.truelayer.java.signupplus.entities.GenerateAuthUriRequest;
9+
import com.truelayer.java.signupplus.entities.GenerateAuthUriResponse;
810
import com.truelayer.java.signupplus.entities.UserData;
911
import java.util.concurrent.CompletableFuture;
1012
import lombok.Builder;
@@ -26,4 +28,9 @@ public RequestScopes getRequestScopes() {
2628
public CompletableFuture<ApiResponse<UserData>> getUserDataByPayment(String paymentId) {
2729
return signupPlusApi.getUserDataByPayment(getRequestScopes(), paymentId);
2830
}
31+
32+
@Override
33+
public CompletableFuture<ApiResponse<GenerateAuthUriResponse>> generateAuthUri(GenerateAuthUriRequest request) {
34+
return signupPlusApi.generateAuthUri(getRequestScopes(), request);
35+
}
2936
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.truelayer.java.signupplus.entities;
2+
3+
import lombok.Builder;
4+
import lombok.EqualsAndHashCode;
5+
import lombok.Getter;
6+
import lombok.ToString;
7+
8+
@Builder
9+
@Getter
10+
@ToString
11+
@EqualsAndHashCode
12+
public class GenerateAuthUriRequest {
13+
private String paymentId;
14+
15+
private String state;
16+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.truelayer.java.signupplus.entities;
2+
3+
import java.net.URI;
4+
import lombok.ToString;
5+
import lombok.Value;
6+
7+
@ToString
8+
@Value
9+
public class GenerateAuthUriResponse {
10+
URI authUri;
11+
}

src/test/java/com/truelayer/java/acceptance/SignupPlusAcceptanceTests.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import com.truelayer.java.TestUtils;
77
import com.truelayer.java.entities.*;
8+
import com.truelayer.java.entities.accountidentifier.AccountIdentifier;
9+
import com.truelayer.java.entities.accountidentifier.IbanAccountIdentifier;
810
import com.truelayer.java.entities.accountidentifier.SortCodeAccountNumberAccountIdentifier;
911
import com.truelayer.java.http.entities.ApiResponse;
1012
import com.truelayer.java.merchantaccounts.entities.MerchantAccount;
@@ -14,6 +16,8 @@
1416
import com.truelayer.java.payments.entities.paymentmethod.PaymentMethod;
1517
import com.truelayer.java.payments.entities.providerselection.ProviderSelection;
1618
import com.truelayer.java.payments.entities.schemeselection.preselected.SchemeSelection;
19+
import com.truelayer.java.signupplus.entities.GenerateAuthUriRequest;
20+
import com.truelayer.java.signupplus.entities.GenerateAuthUriResponse;
1721
import com.truelayer.java.signupplus.entities.UserData;
1822
import java.net.URI;
1923
import java.time.LocalDate;
@@ -45,10 +49,36 @@ public void itShouldAuthorizeAUkPaymentAndThenQueryTheAssociatedIdentityData() {
4549
assertNotError(userDataResponse);
4650
}
4751

52+
@Test
53+
@DisplayName("It should create a payment and generate an auth URI via Signup+ in FI")
54+
@SneakyThrows
55+
public void itShouldAuthorizeAFinPaymentAndThenGenerateAnAuthUri() {
56+
// Create and authorize a payment
57+
String paymentId = createAndAuthorizePayment("mock-payments-fi-redirect", CurrencyCode.EUR, RETURN_URI);
58+
// wait for its settlement
59+
waitForPaymentStatusUpdate(tlClient, paymentId, Status.EXECUTED);
60+
61+
// get the identity data associated with that
62+
ApiResponse<GenerateAuthUriResponse> generateAuthUriResponse = tlClient.signupPlus()
63+
.generateAuthUri(
64+
GenerateAuthUriRequest.builder().paymentId(paymentId).build())
65+
.get();
66+
assertNotError(generateAuthUriResponse);
67+
}
68+
4869
@SneakyThrows
4970
private String createAndAuthorizePayment(String providerId, CurrencyCode currencyCode, URI returnUri) {
5071
MerchantAccount account = getMerchantAccount(currencyCode);
5172

73+
AccountIdentifier accountIdentifier = SortCodeAccountNumberAccountIdentifier.builder()
74+
.accountNumber("31510604")
75+
.sortCode("100000")
76+
.build();
77+
if (currencyCode == CurrencyCode.EUR) {
78+
accountIdentifier =
79+
IbanAccountIdentifier.iban().iban("FI4950009420028730").build();
80+
}
81+
5282
CreatePaymentRequest paymentRequest = CreatePaymentRequest.builder()
5383
.amountInMinor(ThreadLocalRandom.current().nextInt(50, 500))
5484
.currency(currencyCode)
@@ -58,11 +88,8 @@ private String createAndAuthorizePayment(String providerId, CurrencyCode currenc
5888
.schemeSelection(
5989
SchemeSelection.instantPreferred().build())
6090
.remitter(Remitter.builder()
61-
.accountHolderName("Andrea Di Lisio")
62-
.accountIdentifier(SortCodeAccountNumberAccountIdentifier.builder()
63-
.accountNumber("12345678")
64-
.sortCode("123456")
65-
.build())
91+
.accountHolderName("John Doe")
92+
.accountIdentifier(accountIdentifier)
6693
.build())
6794
.build())
6895
.beneficiary(Beneficiary.merchantAccount()

src/test/java/com/truelayer/java/integration/SignupPlusIntegrationTests.java

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
44
import static com.truelayer.java.Constants.Scopes.SIGNUP_PLUS;
55
import static com.truelayer.java.TestUtils.assertNotError;
6+
import static org.junit.jupiter.api.Assertions.assertNotNull;
7+
import static org.junit.jupiter.api.Assertions.assertTrue;
68

79
import com.truelayer.java.TestUtils.RequestStub;
810
import com.truelayer.java.http.entities.ApiResponse;
9-
import com.truelayer.java.signupplus.entities.Address;
10-
import com.truelayer.java.signupplus.entities.Sex;
11-
import com.truelayer.java.signupplus.entities.UserData;
11+
import com.truelayer.java.signupplus.entities.*;
1212
import java.util.Collections;
1313
import lombok.SneakyThrows;
1414
import org.junit.jupiter.api.Assertions;
@@ -51,9 +51,8 @@ public void shouldGetUserDataByPaymentUk() {
5151
Assertions.assertEquals("Holmes", response.getData().getLastName().orElseThrow());
5252
Assertions.assertEquals(
5353
"1854-01-06", response.getData().getDateOfBirth().orElseThrow());
54-
Assertions.assertTrue(response.getData().getSex().isEmpty());
55-
Assertions.assertTrue(
56-
response.getData().getNationalIdentificationNumber().isEmpty());
54+
assertTrue(response.getData().getSex().isEmpty());
55+
assertTrue(response.getData().getNationalIdentificationNumber().isEmpty());
5756
Address address = response.getData().getAddress().orElseThrow();
5857
Assertions.assertEquals("221B Baker St", address.getAddressLine1().orElseThrow());
5958
Assertions.assertEquals("Flat 2", address.getAddressLine2().orElseThrow());
@@ -89,7 +88,7 @@ public void shouldGetUserDataByPaymentFinland() {
8988
verifyGeneratedToken(Collections.singletonList(SIGNUP_PLUS));
9089
assertNotError(response);
9190

92-
Assertions.assertTrue(response.getData().getTitle().isEmpty());
91+
assertTrue(response.getData().getTitle().isEmpty());
9392
Assertions.assertEquals("Väinö", response.getData().getFirstName().orElseThrow());
9493
Assertions.assertEquals("Tunnistus", response.getData().getLastName().orElseThrow());
9594
Assertions.assertEquals(
@@ -100,10 +99,40 @@ public void shouldGetUserDataByPaymentFinland() {
10099
response.getData().getNationalIdentificationNumber().orElseThrow());
101100
Address address = response.getData().getAddress().orElseThrow();
102101
Assertions.assertEquals("Sepänkatu 11 A 5", address.getAddressLine1().orElseThrow());
103-
Assertions.assertTrue(address.getAddressLine2().isEmpty());
102+
assertTrue(address.getAddressLine2().isEmpty());
104103
Assertions.assertEquals("KUOPIO", address.getCity().orElseThrow());
105-
Assertions.assertTrue(address.getState().isEmpty());
104+
assertTrue(address.getState().isEmpty());
106105
Assertions.assertEquals("70100", address.getZip().orElseThrow());
107106
Assertions.assertEquals("FI", address.getCountry().orElseThrow());
108107
}
108+
109+
@Test
110+
@DisplayName("It should generate an auth URI for a payment in Finland")
111+
@SneakyThrows
112+
public void shouldGenerateAuthUriByPaymentFinland() {
113+
String jsonResponseFile = "signup_plus/200.generate_auth_uri.json";
114+
RequestStub.New()
115+
.method("post")
116+
.path(urlPathEqualTo("/connect/token"))
117+
.status(200)
118+
.bodyFile("auth/200.access_token.json")
119+
.build();
120+
RequestStub.New()
121+
.method("post")
122+
.path(urlPathEqualTo("/signup-plus/authuri"))
123+
.withAuthorization()
124+
.status(200)
125+
.bodyFile(jsonResponseFile)
126+
.build();
127+
128+
ApiResponse<GenerateAuthUriResponse> response = tlClient.signupPlus()
129+
.generateAuthUri(
130+
GenerateAuthUriRequest.builder().paymentId(A_PAYMENT_ID).build())
131+
.get();
132+
133+
verifyGeneratedToken(Collections.singletonList(SIGNUP_PLUS));
134+
assertNotError(response);
135+
assertNotNull(response.getData().getAuthUri());
136+
assertTrue(response.getData().getAuthUri().toString().contains("truelayer.com"));
137+
}
109138
}

src/test/java/com/truelayer/java/signupplus/SignupPlusHandlerTests.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import com.truelayer.java.Constants;
77
import com.truelayer.java.entities.RequestScopes;
8+
import com.truelayer.java.signupplus.entities.GenerateAuthUriRequest;
89
import org.junit.jupiter.api.BeforeEach;
910
import org.junit.jupiter.api.DisplayName;
1011
import org.junit.jupiter.api.Test;
@@ -32,9 +33,19 @@ public void setup() {
3233

3334
@Test
3435
@DisplayName("It should call the get user data by payment endpoint")
35-
public void shouldCallCreatePayoutEndpoint() {
36+
public void shouldCallGetUserDataByPaymentEndpoint() {
3637
sut.getUserDataByPayment(A_PAYMENT_ID);
3738

3839
verify(signupPlusApiMock, times(1)).getUserDataByPayment(SCOPES, A_PAYMENT_ID);
3940
}
41+
42+
@Test
43+
@DisplayName("It should call the generate auth URI endpoint")
44+
public void shouldCallGenerateAuthUriEndpoint() {
45+
var generateAuthUriRequest =
46+
GenerateAuthUriRequest.builder().paymentId(A_PAYMENT_ID).build();
47+
sut.generateAuthUri(generateAuthUriRequest);
48+
49+
verify(signupPlusApiMock, times(1)).generateAuthUri(SCOPES, generateAuthUriRequest);
50+
}
4051
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"auth_uri": "https://truelayer.com/redirect?id=863619242079485953&uuid=b912cc0d-149b-40a2-8a24-79a9d1f0913e"
3+
}

0 commit comments

Comments
 (0)