diff --git a/src/main/java/io/craftgate/adapter/PaymentAdapter.java b/src/main/java/io/craftgate/adapter/PaymentAdapter.java index 4c1f68d..304eeee 100644 --- a/src/main/java/io/craftgate/adapter/PaymentAdapter.java +++ b/src/main/java/io/craftgate/adapter/PaymentAdapter.java @@ -50,6 +50,12 @@ public InitCheckoutPaymentResponse initCheckoutPayment(InitCheckoutPaymentReques initCheckoutPaymentRequest, InitCheckoutPaymentResponse.class); } + public InitCheckoutCardVerifyResponse initCheckoutCardVerify(InitCheckoutCardVerifyRequest initCheckoutCardVerifyRequest) { + String path = "/payment/v1/checkout-card-verify/init"; + return HttpClient.post(requestOptions.getBaseUrl() + path, createHeaders(initCheckoutCardVerifyRequest, path, requestOptions), + initCheckoutCardVerifyRequest, InitCheckoutCardVerifyResponse.class); + } + public PaymentResponse retrieveCheckoutPayment(String token) { String path = "/payment/v1/checkout-payments/" + token; return HttpClient.get(requestOptions.getBaseUrl() + path, createHeaders(path, requestOptions), PaymentResponse.class); @@ -201,6 +207,12 @@ public void deleteStoredCard(DeleteStoredCardRequest deleteStoredCardRequest) { deleteStoredCardRequest, Void.class); } + public VerifyCardResponse verifyCard(VerifyCardRequest verifyCardRequest) { + String path = "/payment/v1/cards/verify"; + return HttpClient.post(requestOptions.getBaseUrl() + path, createHeaders(verifyCardRequest, path, requestOptions), + verifyCardRequest, VerifyCardResponse.class); + } + public PaymentTransactionApprovalListResponse approvePaymentTransactions(ApprovePaymentTransactionsRequest approvePaymentTransactionsRequest) { String path = "/payment/v1/payment-transactions/approve"; return HttpClient.post(requestOptions.getBaseUrl() + path, createHeaders(approvePaymentTransactionsRequest, path, requestOptions), diff --git a/src/main/java/io/craftgate/model/CardVerificationAuthType.java b/src/main/java/io/craftgate/model/CardVerificationAuthType.java new file mode 100644 index 0000000..a72af95 --- /dev/null +++ b/src/main/java/io/craftgate/model/CardVerificationAuthType.java @@ -0,0 +1,8 @@ +package io.craftgate.model; + +public enum CardVerificationAuthType { + + NON_THREE_DS, + THREE_DS, + NONE +} diff --git a/src/main/java/io/craftgate/model/CardVerifyStatus.java b/src/main/java/io/craftgate/model/CardVerifyStatus.java new file mode 100644 index 0000000..b1a2583 --- /dev/null +++ b/src/main/java/io/craftgate/model/CardVerifyStatus.java @@ -0,0 +1,8 @@ +package io.craftgate.model; + +public enum CardVerifyStatus { + + SUCCESS, + FAILURE, + THREE_DS_PENDING +} diff --git a/src/main/java/io/craftgate/request/InitCheckoutCardVerifyRequest.java b/src/main/java/io/craftgate/request/InitCheckoutCardVerifyRequest.java new file mode 100644 index 0000000..b36fcb0 --- /dev/null +++ b/src/main/java/io/craftgate/request/InitCheckoutCardVerifyRequest.java @@ -0,0 +1,22 @@ +package io.craftgate.request; + +import io.craftgate.model.CardVerificationAuthType; +import io.craftgate.model.Currency; +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@Builder +public class InitCheckoutCardVerifyRequest { + + private BigDecimal verificationPrice; + private Currency currency; + private String conversationId; + private String callbackUrl; + private String cardUserKey; + private CardVerificationAuthType paymentAuthenticationType; + private Long ttl; + +} \ No newline at end of file diff --git a/src/main/java/io/craftgate/request/VerifyCardRequest.java b/src/main/java/io/craftgate/request/VerifyCardRequest.java new file mode 100644 index 0000000..0909d97 --- /dev/null +++ b/src/main/java/io/craftgate/request/VerifyCardRequest.java @@ -0,0 +1,22 @@ +package io.craftgate.request; + +import io.craftgate.model.CardVerificationAuthType; +import io.craftgate.model.Currency; +import io.craftgate.request.dto.VerifyCard; +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@Builder +public class VerifyCardRequest { + + private VerifyCard card; + private CardVerificationAuthType paymentAuthenticationType; + private BigDecimal verificationPrice; + private Currency currency; + private String clientIp; + private String conversationId; + private String callbackUrl; +} diff --git a/src/main/java/io/craftgate/request/dto/VerifyCard.java b/src/main/java/io/craftgate/request/dto/VerifyCard.java new file mode 100644 index 0000000..3aab8c5 --- /dev/null +++ b/src/main/java/io/craftgate/request/dto/VerifyCard.java @@ -0,0 +1,16 @@ +package io.craftgate.request.dto; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class VerifyCard { + private String cardHolderName; + private String cardNumber; + private String expireYear; + private String expireMonth; + private String cvc; + private String cardAlias; + private String cardUserKey; +} diff --git a/src/main/java/io/craftgate/response/InitCheckoutCardVerifyResponse.java b/src/main/java/io/craftgate/response/InitCheckoutCardVerifyResponse.java new file mode 100644 index 0000000..f8f76b8 --- /dev/null +++ b/src/main/java/io/craftgate/response/InitCheckoutCardVerifyResponse.java @@ -0,0 +1,13 @@ +package io.craftgate.response; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class InitCheckoutCardVerifyResponse { + + private String token; + private String pageUrl; + private LocalDateTime tokenExpireDate; +} diff --git a/src/main/java/io/craftgate/response/VerifyCardResponse.java b/src/main/java/io/craftgate/response/VerifyCardResponse.java new file mode 100644 index 0000000..72f9661 --- /dev/null +++ b/src/main/java/io/craftgate/response/VerifyCardResponse.java @@ -0,0 +1,20 @@ +package io.craftgate.response; + +import io.craftgate.model.CardVerifyStatus; +import io.craftgate.model.RefundStatus; +import lombok.Data; + +@Data +public class VerifyCardResponse { + + + private String cardUserKey; + private String cardToken; + private String htmlContent; + private String redirectUrl; + private String merchantCallbackUrl; + private RefundStatus refundStatus; + private CardVerifyStatus cardVerifyStatus; + + +} diff --git a/src/test/java/io/craftgate/sample/PaymentSample.java b/src/test/java/io/craftgate/sample/PaymentSample.java index 4e3b848..3928092 100644 --- a/src/test/java/io/craftgate/sample/PaymentSample.java +++ b/src/test/java/io/craftgate/sample/PaymentSample.java @@ -7,6 +7,7 @@ import io.craftgate.request.dto.Card; import io.craftgate.request.dto.GarantiPayInstallment; import io.craftgate.request.dto.PaymentItem; +import io.craftgate.request.dto.VerifyCard; import io.craftgate.response.*; import org.junit.jupiter.api.Test; @@ -2269,4 +2270,49 @@ void should_not_validate_3D_secure_callback_when_hashes_are_not_equal() { //then assertFalse(isVerified); } + + @Test + void init_checkout_card_verify_with_non_3ds_auth_type() { + InitCheckoutCardVerifyRequest request = InitCheckoutCardVerifyRequest.builder() + .callbackUrl("https://www.your-website.com/craftgate-checkout-card-verify-callback") + .conversationId("456d1297-908e-4bd6-a13b-4be31a6e47d5") + .paymentAuthenticationType(CardVerificationAuthType.NON_THREE_DS) + .verificationPrice(BigDecimal.TEN) + .currency(Currency.TRY) + .build(); + + InitCheckoutCardVerifyResponse response = craftgate.payment().initCheckoutCardVerify(request); + + assertNotNull(response); + assertNotNull(response.getPageUrl()); + assertNotNull(response.getToken()); + assertNotNull(response.getTokenExpireDate()); + } + + @Test + void verify_card_with_3ds() { + VerifyCardRequest request = VerifyCardRequest.builder() + .card(VerifyCard.builder() + .cardHolderName("Haluk Demir") + .cardNumber("5258640000000001") + .expireYear("2044") + .expireMonth("07") + .cvc("000") + .cardAlias("My YKB Card") + .build()) + + .paymentAuthenticationType(CardVerificationAuthType.THREE_DS) + .callbackUrl("https://www.your-website.com/craftgate-3DSecure-card-verify-callback") + .conversationId("456d1297-908e-4bd6-a13b-4be31a6e47d5") + .verificationPrice(BigDecimal.TEN) + .currency(Currency.TRY) + .clientIp("127.0.0.1") + .build(); + + VerifyCardResponse response = craftgate.payment().verifyCard(request); + + assertNotNull(response); + assertEquals(CardVerifyStatus.THREE_DS_PENDING, response.getCardVerifyStatus()); + assertNotNull(response.getHtmlContent()); + } }