Skip to content

Commit

Permalink
Merge pull request #21 from hopper/allow-tokenisation-by-the-partner
Browse files Browse the repository at this point in the history
Allow card tokenization from the partner
  • Loading branch information
jpinetHCAP authored Aug 27, 2024
2 parents 64b2c23 + 2299ba2 commit ccbb0ba
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 35 deletions.
24 changes: 12 additions & 12 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ repositories {
mavenCentral()
}
dependencies {
swaggerCodegen 'org.openapitools:openapi-generator-cli:6.0.0'
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'io.swagger:swagger-annotations:1.6.6'
swaggerCodegen 'org.openapitools:openapi-generator-cli:7.8.0'
implementation 'com.google.code.gson:gson:2.11.0'
implementation 'io.swagger:swagger-annotations:1.6.14'
implementation 'javax.annotation:javax.annotation-api:1.3.2'
implementation 'javax.ws.rs:javax.ws.rs-api:2.1.1'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.10.0'
implementation 'com.squareup.okio:okio:3.2.0'
implementation 'org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:1.0.1'
implementation 'org.apache.oltu.oauth2:org.apache.oltu.oauth2.common:1.0.1'
implementation 'io.gsonfire:gson-fire:1.8.5'
implementation 'com.google.code.findbugs:jsr305:3.0.2'
implementation 'com.konghq:unirest-java:3.13.10'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3'
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'
implementation 'com.squareup.okio:okio:3.9.0'
implementation 'org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:1.0.2'
implementation 'org.apache.oltu.oauth2:org.apache.oltu.oauth2.common:1.0.2'
implementation 'io.gsonfire:gson-fire:1.9.0'
implementation 'com.github.spotbugs:spotbugs-annotations:4.8.6'
implementation 'com.konghq:unirest-java:3.14.5'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.2'

}
task printVersionName {
Expand Down
35 changes: 12 additions & 23 deletions src/main/java/com/hopper/cloud/airlines/HopperClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,19 @@ public class HopperClient {
private CancelForAnyReasonCfarApi cfarApi;
private SessionsApi sessionsApi;
private AnalyticsApi analyticsApi;
private String paymentUrl;
private String paymentUsername;
private String paymentPassword;
private HopperPaymentClient hopperPaymentClient;

public HopperClient(String url, String clientId, String clientSecret, Boolean debugging) {
this.initHopperClient(url, clientId, clientSecret, null, null, null, debugging);
this.initHopperClient(url, clientId, clientSecret, debugging);
}

public HopperClient(String url, String clientId, String clientSecret, String paymentUrl, String paymentUsername, String paymentPassword, Boolean debugging) {
this.initHopperClient(url, clientId, clientSecret, paymentUrl, paymentUsername, paymentPassword, debugging);
this(url, clientId, clientSecret, debugging);
hopperPaymentClient = new HopperPaymentClient(paymentUrl, paymentUsername, paymentPassword);
}

private void initHopperClient(String url, String clientId, String clientSecret, String paymentUrl, String paymentUsername, String paymentPassword, Boolean debugging) {
this.paymentUrl = paymentUrl;
this.paymentUsername = paymentUsername;
this.paymentPassword = paymentPassword;

private void initHopperClient(String url, String clientId, String clientSecret, Boolean debugging) {
Map<String, String> params = new HashMap<>();
params.put("audience", String.join("/", Arrays.asList(url.split("/")).subList(0, 3)));
params.put("grant_type", "client_credentials");
Expand Down Expand Up @@ -78,7 +75,7 @@ public <T> T readValue(String value, Class<T> valueType) {
throw new RuntimeException(e);
}
}
}).connectTimeout(60000).socketTimeout(60000);
}).connectTimeout(60000);

}

Expand Down Expand Up @@ -113,7 +110,7 @@ public CreateSessionOffersContractsResponse createSessionOffersAndContracts(Crea
// Create offers
List<CfarOffer> cfarOffers = createOffers(sessionId, createCfarOfferRequest);

// Create a contract for each offers created
// Create a contract for each offer created
List<CfarContract> cfarContracts = new ArrayList<>();
if (cfarOffers != null && !cfarOffers.isEmpty()) {
for (CfarOffer offer : cfarOffers) {
Expand Down Expand Up @@ -170,6 +167,9 @@ public CfarContract getContract(String sessionId, String contractId) throws ApiE

public boolean processCfarPayment(String sessionId, String contractId, ProcessCfarPaymentRequest processCfarPaymentRequest) throws ApiException {
try {
if (hopperPaymentClient == null) {
throw new ApiException("Missing credentials for payment");
}
TokenizationRequest tokenizationRequest = new TokenizationRequest();
tokenizationRequest.setPaymentMethod(new PaymentMethod());
tokenizationRequest.getPaymentMethod().setCreditCard(new CreditCard());
Expand All @@ -193,7 +193,7 @@ public boolean processCfarPayment(String sessionId, String contractId, ProcessCf
tokenizationRequest.getPaymentMethod().getCreditCard().setZip(processCfarPaymentRequest.getPostalCode());
tokenizationRequest.getPaymentMethod().getCreditCard().setCountry(processCfarPaymentRequest.getCountry());
tokenizationRequest.getPaymentMethod().setEmail(processCfarPaymentRequest.getEmailAddress());
HttpResponse<TokenizationResponse> response = getTokenizedPaymentHttpResponse(tokenizationRequest);
HttpResponse<TokenizationResponse> response = hopperPaymentClient.getTokenizedPaymentHttpResponse(tokenizationRequest);

if (response.getStatus() == 201) {
ProcessCfarPaymentTokenRequest processCfarPaymentTokenRequest = new ProcessCfarPaymentTokenRequest();
Expand All @@ -218,17 +218,6 @@ public boolean processCfarPayment(String sessionId, String contractId, ProcessCf
}
}

private HttpResponse<TokenizationResponse> getTokenizedPaymentHttpResponse(TokenizationRequest tokenizationRequest) throws ApiException {
if (StringUtil.isEmpty(paymentUrl) || StringUtil.isEmpty(paymentUsername) || StringUtil.isEmpty(paymentPassword)) {
throw new ApiException("Missing credentials for payment");
}
return Unirest.post(paymentUrl)
.basicAuth(paymentUsername, paymentPassword)
.header("Content-Type", "application/json")
.body(tokenizationRequest)
.asObject(TokenizationResponse.class);
}

public CfarContractExercise createCfarContractExercise(String sessionId, CreateCfarContractExerciseRequest createCfarContractExerciseRequest) throws ApiException {
return cfarApi.postCfarContractExercises(createCfarContractExerciseRequest, sessionId);
}
Expand Down
69 changes: 69 additions & 0 deletions src/main/java/com/hopper/cloud/airlines/HopperPaymentClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.hopper.cloud.airlines;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.hopper.cloud.airlines.model.*;
import com.hopper.cloud.airlines.model.tokenization.TokenizationRequest;
import com.hopper.cloud.airlines.model.tokenization.TokenizationResponse;
import kong.unirest.HttpResponse;
import kong.unirest.ObjectMapper;
import kong.unirest.Unirest;

public class HopperPaymentClient {
private String paymentUrl;
private String paymentUsername;
private String paymentPassword;

public HopperPaymentClient(String paymentUrl, String paymentUsername, String paymentPassword) {
this.initHopperPaymentClient(paymentUrl, paymentUsername, paymentPassword);
}


private void initHopperPaymentClient(String paymentUrl, String paymentUsername, String paymentPassword) {
this.paymentUrl = paymentUrl;
this.paymentUsername = paymentUsername;
this.paymentPassword = paymentPassword;

Unirest.config().setObjectMapper(new ObjectMapper() {
final com.fasterxml.jackson.databind.ObjectMapper mapper
= new com.fasterxml.jackson.databind.ObjectMapper();

public String writeValue(Object value) {
try {
return mapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}

public <T> T readValue(String value, Class<T> valueType) {
try {
return mapper.readValue(value, valueType);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}).connectTimeout(60000);

}


public HttpResponse<TokenizationResponse> getTokenizedPaymentHttpResponse(TokenizationRequest tokenizationRequest) throws ApiException {
if (StringUtil.isEmpty(paymentUrl) || StringUtil.isEmpty(paymentUsername) || StringUtil.isEmpty(paymentPassword)) {
throw new ApiException("Missing credentials for payment");
}
return Unirest.post(paymentUrl)
.basicAuth(paymentUsername, paymentPassword)
.header("Content-Type", "application/json")
.body(tokenizationRequest)
.asObject(TokenizationResponse.class);
}

public String tokenizePaymentCard(PaymentCardDetail paymentCardDetail) throws ApiException {
HttpResponse<TokenizationResponse> response = getTokenizedPaymentHttpResponse(new TokenizationRequest(paymentCardDetail));
if (response.getStatus() == 201) {
return response.getBody().getTransaction().getPaymentMethod().getToken();
} else {
throw new ApiException("Unable to create this specific token, response : " + response.getStatus());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map
response.body().string(),
response.body().contentType().toString(),
response.code(),
null,
responseClass);
} catch (IOException e) {
throw new OAuthSystemException(e);
Expand Down
157 changes: 157 additions & 0 deletions src/main/java/com/hopper/cloud/airlines/model/PaymentCardDetail.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package com.hopper.cloud.airlines.model;

import java.util.Objects;

public class PaymentCardDetail {
private String number;
private String verificationValue;
private String month;
private String year;
private String firstName;
private String lastName;
private String addressLine1;
private String addressLine2;
private String city;
private String postalCode;
private String stateOrProvince;
private String country;
private String emailAddress;

public PaymentCardDetail() {
}

public String getNumber() {
return number;
}

public void setNumber(String number) {
this.number = number;
}

public String getVerificationValue() {
return verificationValue;
}

public void setVerificationValue(String verificationValue) {
this.verificationValue = verificationValue;
}

public String getMonth() {
return month;
}

public void setMonth(String month) {
this.month = month;
}

public String getYear() {
return year;
}

public void setYear(String year) {
this.year = year;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getAddressLine1() {
return addressLine1;
}

public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}

public String getAddressLine2() {
return addressLine2;
}

public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getPostalCode() {
return postalCode;
}

public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}

public String getStateOrProvince() {
return stateOrProvince;
}

public void setStateOrProvince(String stateOrProvince) {
this.stateOrProvince = stateOrProvince;
}

public String getCountry() {
return country;
}

public void setCountry(String country) {
this.country = country;
}

public String getEmailAddress() {
return emailAddress;
}

public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
PaymentCardDetail processCfarPayment = (PaymentCardDetail) o;
return Objects.equals(this.number, processCfarPayment.number) &&
Objects.equals(this.verificationValue, processCfarPayment.verificationValue) &&
Objects.equals(this.month, processCfarPayment.month) &&
Objects.equals(this.year, processCfarPayment.year) &&
Objects.equals(this.firstName, processCfarPayment.firstName) &&
Objects.equals(this.lastName, processCfarPayment.lastName) &&
Objects.equals(this.addressLine1, processCfarPayment.addressLine1) &&
Objects.equals(this.addressLine2, processCfarPayment.addressLine2) &&
Objects.equals(this.postalCode, processCfarPayment.postalCode) &&
Objects.equals(this.city, processCfarPayment.city) &&
Objects.equals(this.stateOrProvince, processCfarPayment.stateOrProvince) &&
Objects.equals(this.country, processCfarPayment.country) &&
Objects.equals(this.emailAddress, processCfarPayment.emailAddress);
}

@Override
public int hashCode() {
return Objects.hash(number, verificationValue, month, year, firstName, lastName, addressLine1, addressLine2, postalCode, city, stateOrProvince, country, emailAddress);
}

}

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.hopper.cloud.airlines.model.tokenization;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.hopper.cloud.airlines.model.PaymentCardDetail;

import java.util.Objects;

Expand All @@ -11,6 +12,26 @@ public class TokenizationRequest {
public TokenizationRequest() {
}

public TokenizationRequest(PaymentCardDetail paymentCardDetail) {
PaymentMethod paymentMethod = new PaymentMethod();
paymentMethod.setEmail(paymentCardDetail.getEmailAddress());
CreditCard creditCard = new CreditCard();
creditCard.setVerificationValue(paymentCardDetail.getVerificationValue());
creditCard.setMonth(paymentCardDetail.getMonth());
creditCard.setYear(paymentCardDetail.getYear());
creditCard.setAddress1(paymentCardDetail.getAddressLine1());
creditCard.setAddress2(paymentCardDetail.getAddressLine2());
creditCard.setCity(paymentCardDetail.getCity());
creditCard.setState(paymentCardDetail.getStateOrProvince());
creditCard.setZip(paymentCardDetail.getPostalCode());
creditCard.setCountry(paymentCardDetail.getCountry());
creditCard.setLastName(paymentCardDetail.getLastName());
creditCard.setFirstName(paymentCardDetail.getFirstName());
creditCard.setNumber(paymentCardDetail.getNumber());
paymentMethod.setCreditCard(creditCard);
this.setPaymentMethod(paymentMethod);
}

public PaymentMethod getPaymentMethod() {
return paymentMethod;
}
Expand Down

0 comments on commit ccbb0ba

Please sign in to comment.