From c6f28c402dc210348b26149e329764898a516131 Mon Sep 17 00:00:00 2001 From: Oleg Gorbik Date: Tue, 12 Aug 2025 15:13:58 +0300 Subject: [PATCH] Add alternative payment methods support (like Google Pay) --- .github/workflows/maven.yml | 2 +- README.md | 35 +++++++++++++++++-- pom.xml | 24 +++++++++---- .../github/transactpro/gateway/Gateway.java | 1 + .../adapters/PaymentMethodTypeSerializer.java | 15 ++++++++ .../gateway/model/request/data/Command.java | 2 ++ .../model/request/data/PaymentMethod.java | 9 ++--- .../data/command/PaymentMethodType.java | 17 +++++++++ .../data/payment/ExternalTokenData.java | 22 ++++++++++++ .../gateway/operation/Operation.java | 8 ++--- .../operation/transaction/SmsTest.java | 16 +++++++-- 11 files changed, 131 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/github/transactpro/gateway/adapters/PaymentMethodTypeSerializer.java create mode 100644 src/main/java/com/github/transactpro/gateway/model/request/data/command/PaymentMethodType.java create mode 100644 src/main/java/com/github/transactpro/gateway/model/request/data/payment/ExternalTokenData.java diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 7893e8d..84a0918 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [ 11, 17, 21 ] + java: [ 11, 17, 21, 25 ] steps: - uses: actions/checkout@v2 diff --git a/README.md b/README.md index 300a57e..7c4f253 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ This library provide ability to make requests to Transact Pro Gateway API v3. com.github.transactpro gateway - 2.0.1 + 2.0.2 ``` #### Gradle ```groovy -implementation 'com.github.transactpro:gateway:2.0.1' +implementation 'com.github.transactpro:gateway:2.0.2' ``` ## Documentation @@ -214,6 +214,37 @@ Command command = new Command() sms.setCommand(command); ``` +### Using alternative payment methods + +To use an alternative payment method (like Google Pay), send a received token AS-IS or data from a decrypted token. + +```java +// set a corresponding flag that indicates a token provider +Command command = new Command().setPaymentMethodType(PaymentMethodType.PAYMENT_METHOD_TYPE_GOOGLE_PAY); +operation.setCommand(command); + +// option 1: send received token AS-IS +PaymentMethod paymentMethod = new PaymentMethod().setToken(''); +operation.setPayment(paymentMethod); + +// option 2: send data from decrypted token +ExternalTokenData externalTokenData = new ExternalTokenData() + .setCryptogram("") // if available + .setEci("") // if available + .setTransStatus("") // available for Click to Pay + .setDsTransId("") // available for Click to Pay + .setAcsTransId("") // available for Click to Pay + .setCardHolderAuthenticated(decryptedToken.paymentMethodDetails.assuranceDetails.cardHolderAuthenticated); // for Google Pay + +PaymentMethod paymentMethod = new PaymentMethod() + .setPan("") + .setExpMmYy("") + .setCardHolderName("") // if available + .setExternalTokenData(externalTokenData); + +operation.setPayment(paymentMethod); +``` + ### Callback validation ```java diff --git a/pom.xml b/pom.xml index 5eba0b1..7d1167f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.transactpro gateway - 2.0.1 + 2.0.2 Transact Pro Gateway v3 Java client library A library that provide ability to make requests to Transact Pro Gateway API v3. @@ -36,6 +36,8 @@ UTF-8 + 11 + 1.18.42 @@ -53,10 +55,18 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.14.1 - 1.8 - 1.8 + ${maven.release} + + + org.projectlombok + lombok + + + + -proc:full + @@ -94,7 +104,7 @@ jar - 1.8 + 11 @@ -147,7 +157,7 @@ org.mockito mockito-core - 5.7.0 + 5.20.0 test @@ -179,7 +189,7 @@ org.projectlombok lombok - 1.18.30 + ${lombok.version} provided diff --git a/src/main/java/com/github/transactpro/gateway/Gateway.java b/src/main/java/com/github/transactpro/gateway/Gateway.java index e02ee97..b835eb7 100644 --- a/src/main/java/com/github/transactpro/gateway/Gateway.java +++ b/src/main/java/com/github/transactpro/gateway/Gateway.java @@ -33,6 +33,7 @@ public class Gateway { private String url; @Getter private final Authorization authorization; + @Setter private CloseableHttpClient httpClient; private Validator validator; diff --git a/src/main/java/com/github/transactpro/gateway/adapters/PaymentMethodTypeSerializer.java b/src/main/java/com/github/transactpro/gateway/adapters/PaymentMethodTypeSerializer.java new file mode 100644 index 0000000..d2a8aae --- /dev/null +++ b/src/main/java/com/github/transactpro/gateway/adapters/PaymentMethodTypeSerializer.java @@ -0,0 +1,15 @@ +package com.github.transactpro.gateway.adapters; + +import com.github.transactpro.gateway.model.request.data.command.PaymentMethodType; +import com.google.gson.JsonElement; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; + +public class PaymentMethodTypeSerializer implements JsonSerializer { + @Override + public JsonElement serialize(PaymentMethodType paymentMethodType, Type type, JsonSerializationContext jsonSerializationContext) { + return jsonSerializationContext.serialize(paymentMethodType.getValue()); + } +} diff --git a/src/main/java/com/github/transactpro/gateway/model/request/data/Command.java b/src/main/java/com/github/transactpro/gateway/model/request/data/Command.java index fc20980..c20479d 100644 --- a/src/main/java/com/github/transactpro/gateway/model/request/data/Command.java +++ b/src/main/java/com/github/transactpro/gateway/model/request/data/Command.java @@ -3,6 +3,7 @@ import com.github.transactpro.gateway.model.request.data.command.CardVerificationMode; import com.github.transactpro.gateway.model.request.data.command.PaymentMethodDataSource; +import com.github.transactpro.gateway.model.request.data.command.PaymentMethodType; import com.github.transactpro.gateway.validation.base.CommandTransactionIdGroup; import jakarta.validation.constraints.NotNull; import lombok.Getter; @@ -23,4 +24,5 @@ public class Command { private CardVerificationMode cardVerification; private PaymentMethodDataSource paymentMethodDataSource; private String paymentMethodDataToken; + private PaymentMethodType paymentMethodType; } \ No newline at end of file diff --git a/src/main/java/com/github/transactpro/gateway/model/request/data/PaymentMethod.java b/src/main/java/com/github/transactpro/gateway/model/request/data/PaymentMethod.java index 3d306e5..dc64f8b 100644 --- a/src/main/java/com/github/transactpro/gateway/model/request/data/PaymentMethod.java +++ b/src/main/java/com/github/transactpro/gateway/model/request/data/PaymentMethod.java @@ -1,9 +1,8 @@ package com.github.transactpro.gateway.model.request.data; import com.github.transactpro.gateway.model.request.data.payment.ExternalMPIData; -import com.github.transactpro.gateway.validation.base.PaymentMethodPanExpGroup; +import com.github.transactpro.gateway.model.request.data.payment.ExternalTokenData; import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -15,13 +14,15 @@ public class PaymentMethod { @CreditCardNumber(ignoreNonDigitCharacters = true) - @NotNull(groups = PaymentMethodPanExpGroup.class) private String pan; - @NotNull(groups = PaymentMethodPanExpGroup.class) private String expMmYy; private String cvv; private String cardholderName; + private String token; @Valid private ExternalMPIData externalMpiData; + + @Valid + private ExternalTokenData externalTokenData; } diff --git a/src/main/java/com/github/transactpro/gateway/model/request/data/command/PaymentMethodType.java b/src/main/java/com/github/transactpro/gateway/model/request/data/command/PaymentMethodType.java new file mode 100644 index 0000000..415e368 --- /dev/null +++ b/src/main/java/com/github/transactpro/gateway/model/request/data/command/PaymentMethodType.java @@ -0,0 +1,17 @@ +package com.github.transactpro.gateway.model.request.data.command; + +import lombok.Getter; + +@Getter +public enum PaymentMethodType { + PAYMENT_METHOD_TYPE_CARD("cc"), + PAYMENT_METHOD_TYPE_GOOGLE_PAY("google_pay"), + PAYMENT_METHOD_TYPE_APPLE_PAY("apple_pay"), + PAYMENT_METHOD_TYPE_CLICK2PAY("click2pay"); + + private final String value; + + PaymentMethodType(String value) { + this.value = value; + } +} diff --git a/src/main/java/com/github/transactpro/gateway/model/request/data/payment/ExternalTokenData.java b/src/main/java/com/github/transactpro/gateway/model/request/data/payment/ExternalTokenData.java new file mode 100644 index 0000000..99d1fd8 --- /dev/null +++ b/src/main/java/com/github/transactpro/gateway/model/request/data/payment/ExternalTokenData.java @@ -0,0 +1,22 @@ +package com.github.transactpro.gateway.model.request.data.payment; + +import com.google.gson.annotations.SerializedName; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +@Getter +@Setter +@Accessors(chain = true) +public class ExternalTokenData { + private String cryptogram; + private String eci; + @SerializedName("transStatus") + private String transStatus; + @SerializedName("dsTransID") + private String dsTransID; + @SerializedName("acsTransID") + private String acsTransID; + @SerializedName("cardHolderAuthenticated") + private Boolean cardHolderAuthenticated; +} diff --git a/src/main/java/com/github/transactpro/gateway/operation/Operation.java b/src/main/java/com/github/transactpro/gateway/operation/Operation.java index 8d10bbb..4f9183e 100644 --- a/src/main/java/com/github/transactpro/gateway/operation/Operation.java +++ b/src/main/java/com/github/transactpro/gateway/operation/Operation.java @@ -2,10 +2,12 @@ import com.github.transactpro.gateway.adapters.CardVerificationModeSerializer; import com.github.transactpro.gateway.adapters.PaymentMethodDataSourceSerializer; +import com.github.transactpro.gateway.adapters.PaymentMethodTypeSerializer; import com.github.transactpro.gateway.model.Request; import com.github.transactpro.gateway.model.Response; import com.github.transactpro.gateway.model.request.data.command.CardVerificationMode; import com.github.transactpro.gateway.model.request.data.command.PaymentMethodDataSource; +import com.github.transactpro.gateway.model.request.data.command.PaymentMethodType; import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -21,6 +23,7 @@ public abstract class Operation implements Operable { @Getter protected String requestUri; + @Getter protected Request request; protected Class responseType; @Getter @@ -41,15 +44,12 @@ protected Request buildRequest() { return new Request(); } - public Request getRequest() { - return request; - } - protected Gson buildJsonParser() { return new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES) .registerTypeAdapter(CardVerificationMode.class, new CardVerificationModeSerializer()) .registerTypeAdapter(PaymentMethodDataSource.class, new PaymentMethodDataSourceSerializer()) + .registerTypeAdapter(PaymentMethodType.class, new PaymentMethodTypeSerializer()) .create(); } diff --git a/src/test/java/com/github/transactpro/gateway/operation/transaction/SmsTest.java b/src/test/java/com/github/transactpro/gateway/operation/transaction/SmsTest.java index 5b7dc46..3e39180 100644 --- a/src/test/java/com/github/transactpro/gateway/operation/transaction/SmsTest.java +++ b/src/test/java/com/github/transactpro/gateway/operation/transaction/SmsTest.java @@ -8,10 +8,12 @@ import com.github.transactpro.gateway.model.request.data.System; import com.github.transactpro.gateway.model.request.data.command.CardVerificationMode; import com.github.transactpro.gateway.model.request.data.command.PaymentMethodDataSource; +import com.github.transactpro.gateway.model.request.data.command.PaymentMethodType; import com.github.transactpro.gateway.model.request.data.general.Customer; import com.github.transactpro.gateway.model.request.data.general.Order; import com.github.transactpro.gateway.model.request.data.general.customer.Address; import com.github.transactpro.gateway.model.request.data.payment.ExternalMPIData; +import com.github.transactpro.gateway.model.request.data.payment.ExternalTokenData; import com.github.transactpro.gateway.model.response.PaymentResponse; import com.github.transactpro.gateway.model.response.constants.ErrorCode; import com.github.transactpro.gateway.model.response.constants.Status; @@ -75,7 +77,8 @@ void validOperationAllFields() { Command command = new Command() .setCardVerification(CardVerificationMode.VERIFY) .setPaymentMethodDataSource(PaymentMethodDataSource.DATA_SOURCE_USE_MERCHANT_SAVED_CARDHOLDER_INITIATED) - .setPaymentMethodDataToken("some-test-id"); + .setPaymentMethodDataToken("some-test-id") + .setPaymentMethodType(PaymentMethodType.PAYMENT_METHOD_TYPE_GOOGLE_PAY); Address address = new Address() .setCity("Chalon-sur-SaƓne") @@ -136,12 +139,21 @@ void validOperationAllFields() { .setCavv("kBMI/uGZvlKCygBkcQIlLJeBTPLG") .setTransStatus("Y"); + ExternalTokenData externalTokenData = new ExternalTokenData() + .setCryptogram("AAMI/uGZvlKCygBkcQIlLJeBTPLG") + .setEci("05") + .setTransStatus("Y") + .setDsTransID("ad7d1791-11d4-45da-aa16-077cd8f6935c") + .setAcsTransID("be65a56e-66dc-448e-8f38-d78ee70cc6c9") + .setCardHolderAuthenticated(true); + PaymentMethod paymentMethod = new PaymentMethod() .setCardholderName("John Smith") .setCvv("000") .setExpMmYy("12/18") .setPan("0000000000000000") - .setExternalMpiData(externalMpiData); + .setExternalMpiData(externalMpiData) + .setExternalTokenData(externalTokenData); operation.setCommand(command) .setCustomer(customer)