From df716d962ddf77e66416a05da7773e2a918dc099 Mon Sep 17 00:00:00 2001 From: deryacakmak <97deryacakmak@gmail.com> Date: Wed, 24 Jun 2026 16:21:37 +0300 Subject: [PATCH 1/4] Add support for generating BKM Express tokens --- .../adapter/BkmExpressPaymentAdapter.java | 7 +++++++ .../BkmExpressGenerateTokenRequest.java | 19 +++++++++++++++++++ .../BkmExpressGenerateTokenResponse.java | 13 +++++++++++++ .../io/craftgate/sample/BkmExpressSample.java | 12 ++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java create mode 100644 src/main/java/io/craftgate/response/BkmExpressGenerateTokenResponse.java diff --git a/src/main/java/io/craftgate/adapter/BkmExpressPaymentAdapter.java b/src/main/java/io/craftgate/adapter/BkmExpressPaymentAdapter.java index e6cf7eb4..7474b07c 100644 --- a/src/main/java/io/craftgate/adapter/BkmExpressPaymentAdapter.java +++ b/src/main/java/io/craftgate/adapter/BkmExpressPaymentAdapter.java @@ -32,4 +32,11 @@ public PaymentResponse retrievePaymentByToken(String token) { String path = "/payment/v1/bkm-express/" + token; return HttpClient.get(requestOptions.getBaseUrl() + path, createHeaders(path, requestOptions), PaymentResponse.class); } + + public BkmExpressGenerateTokenResponse generateToken(BkmExpressGenerateTokenRequest bkmExpressGenerateTokenRequest) { + String path = "/payment/v2/bkm-express/generate-token"; + return HttpClient.post(requestOptions.getBaseUrl() + path, createHeaders(bkmExpressGenerateTokenRequest, path, requestOptions), + bkmExpressGenerateTokenRequest, BkmExpressGenerateTokenResponse.class); + } + } \ No newline at end of file diff --git a/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java b/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java new file mode 100644 index 00000000..44588b4d --- /dev/null +++ b/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java @@ -0,0 +1,19 @@ +package io.craftgate.request; + +import io.craftgate.model.Currency; +import io.craftgate.model.PaymentGroup; +import io.craftgate.model.PaymentPhase; +import io.craftgate.request.dto.PaymentItem; +import lombok.Builder; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +@Builder +public class BkmExpressGenerateTokenRequest { + + private String gsmNumber; + private String userId; +} diff --git a/src/main/java/io/craftgate/response/BkmExpressGenerateTokenResponse.java b/src/main/java/io/craftgate/response/BkmExpressGenerateTokenResponse.java new file mode 100644 index 00000000..8f7279b4 --- /dev/null +++ b/src/main/java/io/craftgate/response/BkmExpressGenerateTokenResponse.java @@ -0,0 +1,13 @@ +package io.craftgate.response; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class BkmExpressGenerateTokenResponse { + + private String token; + private String errorCode; + private String errorMessage; +} diff --git a/src/test/java/io/craftgate/sample/BkmExpressSample.java b/src/test/java/io/craftgate/sample/BkmExpressSample.java index 53c743b3..04250d83 100644 --- a/src/test/java/io/craftgate/sample/BkmExpressSample.java +++ b/src/test/java/io/craftgate/sample/BkmExpressSample.java @@ -105,4 +105,16 @@ void retrieve_bkm_express_payment_by_token() { PaymentResponse response = craftgate.bkmExpressPaymentAdapter().retrievePaymentByToken(bkmExpressPaymentToken); assertNotNull(response); } + + @Test + void generate_bkm_express_token() { + + BkmExpressGenerateTokenRequest request = BkmExpressGenerateTokenRequest.builder() + .userId("userId") + .gsmNumber("905551111111") + .build(); + + BkmExpressGenerateTokenResponse response = craftgate.bkmExpressPaymentAdapter().generateToken(request); + assertNotNull(response); + } } From ed89516f27592ed212da6c8e980000d2f6a75752 Mon Sep 17 00:00:00 2001 From: deryacakmak <97deryacakmak@gmail.com> Date: Mon, 5 Oct 2026 17:11:15 +0300 Subject: [PATCH 2/4] Add support for BKM Express tokenized card payments --- .../adapter/BkmExpressPaymentAdapter.java | 1 - .../io/craftgate/model/TokenizedCardType.java | 1 + .../BkmExpressGenerateTokenRequest.java | 7 -- .../BkmExpressGenerateTokenResponse.java | 2 - .../io/craftgate/sample/BkmExpressSample.java | 98 ++++++++++++++++++- 5 files changed, 96 insertions(+), 13 deletions(-) diff --git a/src/main/java/io/craftgate/adapter/BkmExpressPaymentAdapter.java b/src/main/java/io/craftgate/adapter/BkmExpressPaymentAdapter.java index 7474b07c..5f73beba 100644 --- a/src/main/java/io/craftgate/adapter/BkmExpressPaymentAdapter.java +++ b/src/main/java/io/craftgate/adapter/BkmExpressPaymentAdapter.java @@ -38,5 +38,4 @@ public BkmExpressGenerateTokenResponse generateToken(BkmExpressGenerateTokenRequ return HttpClient.post(requestOptions.getBaseUrl() + path, createHeaders(bkmExpressGenerateTokenRequest, path, requestOptions), bkmExpressGenerateTokenRequest, BkmExpressGenerateTokenResponse.class); } - } \ No newline at end of file diff --git a/src/main/java/io/craftgate/model/TokenizedCardType.java b/src/main/java/io/craftgate/model/TokenizedCardType.java index 726615c1..39e57280 100644 --- a/src/main/java/io/craftgate/model/TokenizedCardType.java +++ b/src/main/java/io/craftgate/model/TokenizedCardType.java @@ -2,4 +2,5 @@ public enum TokenizedCardType { APPLE_PAY, + BKM_EXPRESS } diff --git a/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java b/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java index 44588b4d..bcdbed0d 100644 --- a/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java +++ b/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java @@ -1,15 +1,8 @@ package io.craftgate.request; -import io.craftgate.model.Currency; -import io.craftgate.model.PaymentGroup; -import io.craftgate.model.PaymentPhase; -import io.craftgate.request.dto.PaymentItem; import lombok.Builder; import lombok.Data; -import java.math.BigDecimal; -import java.util.List; - @Data @Builder public class BkmExpressGenerateTokenRequest { diff --git a/src/main/java/io/craftgate/response/BkmExpressGenerateTokenResponse.java b/src/main/java/io/craftgate/response/BkmExpressGenerateTokenResponse.java index 8f7279b4..6ff163aa 100644 --- a/src/main/java/io/craftgate/response/BkmExpressGenerateTokenResponse.java +++ b/src/main/java/io/craftgate/response/BkmExpressGenerateTokenResponse.java @@ -8,6 +8,4 @@ public class BkmExpressGenerateTokenResponse { private String token; - private String errorCode; - private String errorMessage; } diff --git a/src/test/java/io/craftgate/sample/BkmExpressSample.java b/src/test/java/io/craftgate/sample/BkmExpressSample.java index 04250d83..d365993a 100644 --- a/src/test/java/io/craftgate/sample/BkmExpressSample.java +++ b/src/test/java/io/craftgate/sample/BkmExpressSample.java @@ -4,14 +4,20 @@ import io.craftgate.model.Currency; import io.craftgate.model.PaymentGroup; import io.craftgate.model.PaymentPhase; +import io.craftgate.model.PaymentProvider; +import io.craftgate.model.TokenizedCardType; import io.craftgate.request.*; +import io.craftgate.request.dto.Card; import io.craftgate.request.dto.PaymentItem; +import io.craftgate.request.dto.TokenizedCard; import io.craftgate.response.*; import org.junit.jupiter.api.Test; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; @@ -108,13 +114,99 @@ void retrieve_bkm_express_payment_by_token() { @Test void generate_bkm_express_token() { - BkmExpressGenerateTokenRequest request = BkmExpressGenerateTokenRequest.builder() .userId("userId") - .gsmNumber("905551111111") + .gsmNumber("5551111111") .build(); BkmExpressGenerateTokenResponse response = craftgate.bkmExpressPaymentAdapter().generateToken(request); - assertNotNull(response); + assertNotNull(response.getToken()); + } + + @Test + void create_payment_with_bkm_express_tokenized_card() { + List items = new ArrayList<>(); + + items.add(PaymentItem.builder() + .name("item 1") + .externalId(UUID.randomUUID().toString()) + .price(BigDecimal.valueOf(0.6)) + .build()); + + items.add(PaymentItem.builder() + .name("item 2") + .externalId(UUID.randomUUID().toString()) + .price(BigDecimal.valueOf(0.4)) + .build()); + + CreatePaymentRequest request = CreatePaymentRequest.builder() + .price(BigDecimal.ONE) + .paidPrice(BigDecimal.ONE) + .walletPrice(BigDecimal.ZERO) + .installment(1) + .currency(Currency.TRY) + .conversationId("456d1297-908e-4bd6-a13b-4be31a6e47d5") + .paymentGroup(PaymentGroup.LISTING_OR_SUBSCRIPTION) + .paymentPhase(PaymentPhase.AUTH) + .card(Card.builder() + .tokenizedCard(bkmExpressTokenizedCard()) + .build()) + .items(items) + .build(); + + PaymentResponse response = craftgate.payment().createPayment(request); + assertNotNull(response.getId()); + assertEquals(PaymentProvider.BKM_EXPRESS, response.getPaymentProvider()); + } + + @Test + void init_3DS_payment_with_bkm_express_tokenized_card() { + List items = new ArrayList<>(); + + items.add(PaymentItem.builder() + .name("item 1") + .externalId(UUID.randomUUID().toString()) + .price(BigDecimal.valueOf(0.6)) + .build()); + + items.add(PaymentItem.builder() + .name("item 2") + .externalId(UUID.randomUUID().toString()) + .price(BigDecimal.valueOf(0.4)) + .build()); + + InitThreeDSPaymentRequest request = InitThreeDSPaymentRequest.builder() + .price(BigDecimal.ONE) + .paidPrice(BigDecimal.ONE) + .walletPrice(BigDecimal.ZERO) + .installment(1) + .currency(Currency.TRY) + .callbackUrl("https://www.your-website.com/craftgate-3DSecure-callback") + .conversationId("456d1297-908e-4bd6-a13b-4be31a6e47d5") + .paymentGroup(PaymentGroup.LISTING_OR_SUBSCRIPTION) + .paymentPhase(PaymentPhase.AUTH) + .card(Card.builder() + .tokenizedCard(bkmExpressTokenizedCard()) + .build()) + .items(items) + .build(); + + InitThreeDSPaymentResponse response = craftgate.payment().init3DSPayment(request); + assertNotNull(response.getPaymentId()); + assertNotNull(response.getHtmlContent()); + } + + private TokenizedCard bkmExpressTokenizedCard() { + // cardId is returned by the BKM Express client SDK after the buyer selects a card; + // gsmNumber and userId must match the values sent to generateToken. + Map data = new HashMap<>(); + data.put("cardId", "bkm-express-card-id"); + data.put("gsmNumber", "5551111111"); + data.put("userId", "userId"); + + return TokenizedCard.builder() + .type(TokenizedCardType.BKM_EXPRESS) + .data(data) + .build(); } } From f73bcaa1693d001fd73a07bd54cd57bcf91bdccb Mon Sep 17 00:00:00 2001 From: deryacakmak <97deryacakmak@gmail.com> Date: Mon, 5 Oct 2026 17:17:17 +0300 Subject: [PATCH 3/4] Extend `BkmExpressGenerateTokenRequest` with `BaseRequest` --- .../io/craftgate/request/BkmExpressGenerateTokenRequest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java b/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java index bcdbed0d..1f4bf9ba 100644 --- a/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java +++ b/src/main/java/io/craftgate/request/BkmExpressGenerateTokenRequest.java @@ -1,11 +1,14 @@ package io.craftgate.request; +import io.craftgate.request.common.BaseRequest; import lombok.Builder; import lombok.Data; +import lombok.experimental.SuperBuilder; +@SuperBuilder @Data @Builder -public class BkmExpressGenerateTokenRequest { +public class BkmExpressGenerateTokenRequest extends BaseRequest { private String gsmNumber; private String userId; From d43fe91129f62cae6732f743f1ce30aa10662f88 Mon Sep 17 00:00:00 2001 From: deryacakmak <97deryacakmak@gmail.com> Date: Tue, 6 Oct 2026 01:24:00 +0300 Subject: [PATCH 4/4] Extend `InitCheckoutPaymentRequest` with BEX user details --- .../java/io/craftgate/request/InitCheckoutPaymentRequest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/io/craftgate/request/InitCheckoutPaymentRequest.java b/src/main/java/io/craftgate/request/InitCheckoutPaymentRequest.java index bb65d565..7f8d7202 100644 --- a/src/main/java/io/craftgate/request/InitCheckoutPaymentRequest.java +++ b/src/main/java/io/craftgate/request/InitCheckoutPaymentRequest.java @@ -41,6 +41,9 @@ public class InitCheckoutPaymentRequest extends BaseRequest { protected String masterpassGsmNumber; protected String masterpassUserId; + protected String bexGsmNumber; + protected String bexUserId; + protected String cardUserKey; protected Long buyerMemberId;