diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..7f24d4b
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,20 @@
+repos:
+ - repo: local
+ hooks:
+ - id: spotless-apply
+ name: Spotless Code Formatter (Apply)
+ entry: mvn spotless:apply
+ language: system
+ pass_filenames: false
+ stages: [pre-commit]
+ verbose: true
+
+ # some complex rules like missing parentheses in a if, loop statements for a single line are not applied by
+ # mvn spotless:apply so added another check that will block the commit
+ - id: spotless-check
+ name: Spotless Code Formatter (Check)
+ entry: mvn spotless:check
+ language: system
+ pass_filenames: false
+ stages: [pre-commit]
+ verbose: true
diff --git a/README.md b/README.md
index c50e5eb..c025da0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# PhonePe B2B Payment Gateway SDK for Java
-[](https://maven-badges.herokuapp.com/maven-central/com.phonepe/pg-sdk-java)
+[](https://maven-badges.herokuapp.com/maven-central/com.phonepe/pg-sdk-java)

[](LICENSE)
@@ -36,7 +36,7 @@ Add the dependency to your project's POM file:
com.phonepe
pg-sdk-java
- 2.1.7
+ 2.1.8
```
@@ -46,7 +46,7 @@ Add the following to your project's build.gradle file:
```gradle
dependencies {
- implementation 'com.phonepe:pg-sdk-java:2.1.7'
+ implementation 'com.phonepe:pg-sdk-java:2.1.8'
}
```
diff --git a/formatter.xml b/formatter.xml
new file mode 100644
index 0000000..bd267b4
--- /dev/null
+++ b/formatter.xml
@@ -0,0 +1,380 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 3c355cf..72ed3ba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.phonepe
pg-sdk-java
- 2.1.7
+ 2.1.8
B2B JAVA SDK
https://github.com/PhonePe/phonepe-pg-sdk-java
Phonepe PG JAVA SDK
@@ -97,6 +97,11 @@
Aditi Billore
aditi.billore3@gmail.com
+
+ Yogesh-Kamble
+ Yogesh Kamble
+ ypk282000@gmail.com
+
@@ -133,7 +138,39 @@
+
+
+ src/main/resources
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.4.0
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
com.diffplug.spotless
spotless-maven-plugin
@@ -141,6 +178,11 @@
origin/main
+
+
+ ${project.basedir}/formatter.xml
+ 4.26
+
src/main/java/**/*.java
src/test/java/**/*.java
@@ -170,6 +212,25 @@
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.11
+
+
+
+ prepare-agent
+
+
+
+ report
+ test
+
+ report
+
+
+
+
@@ -316,6 +377,12 @@
+
+
+ src/main/resources
+ true
+
+
org.sonatype.central
diff --git a/src/main/java/com/phonepe/sdk/pg/common/constants/Headers.java b/src/main/java/com/phonepe/sdk/pg/common/constants/Headers.java
index b879b75..89ee09d 100644
--- a/src/main/java/com/phonepe/sdk/pg/common/constants/Headers.java
+++ b/src/main/java/com/phonepe/sdk/pg/common/constants/Headers.java
@@ -15,15 +15,34 @@
*/
package com.phonepe.sdk.pg.common.constants;
+import java.io.InputStream;
+import java.util.Properties;
import lombok.experimental.UtilityClass;
+import lombok.extern.slf4j.Slf4j;
@UtilityClass
+@Slf4j
public class Headers {
+ private final Properties properties = new Properties();
+ private final String PROPERTIES_FILE_NAME = "/sdk.properties";
+
+ static {
+ try (InputStream input = Headers.class.getResourceAsStream(PROPERTIES_FILE_NAME)) {
+ if (input == null) {
+ log.error("Could not find {}", PROPERTIES_FILE_NAME);
+ } else {
+ properties.load(input);
+ }
+ } catch (Exception e) {
+ log.error("Failed to load SDK properties: {}", e.getMessage());
+ }
+ }
+
public static final String API_VERSION = "V2";
- public static final String SUBSCRIPTION_API_VERSION = "2.1.7";
+ public static final String SUBSCRIPTION_API_VERSION = properties.getProperty("sdk.version");
public static final String INTEGRATION = "API";
- public static final String SDK_VERSION = "2.1.7";
+ public static final String SDK_VERSION = properties.getProperty("sdk.version");
public static final String SDK_TYPE = "BACKEND_JAVA_SDK";
public static final String SOURCE = "x-source";
public static final String SOURCE_VERSION = "x-source-version";
@@ -32,4 +51,4 @@ public class Headers {
public static final String OAUTH_AUTHORIZATION = "Authorization";
public static final String CONTENT_TYPE = "Content-Type";
public static final String ACCEPT = "Accept";
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/phonepe/sdk/pg/common/http/HttpCommand.java b/src/main/java/com/phonepe/sdk/pg/common/http/HttpCommand.java
index 0dfaf2b..d72f6c6 100644
--- a/src/main/java/com/phonepe/sdk/pg/common/http/HttpCommand.java
+++ b/src/main/java/com/phonepe/sdk/pg/common/http/HttpCommand.java
@@ -99,7 +99,7 @@ private HttpUrl prepareHttpURL(String url) {
/**
* Executes the HTTP request and returns the response.
*
- * @return the response object
+ * @return the response object
*/
@SneakyThrows
public T execute() {
diff --git a/src/main/java/com/phonepe/sdk/pg/payments/v2/CustomCheckoutClient.java b/src/main/java/com/phonepe/sdk/pg/payments/v2/CustomCheckoutClient.java
index 1e3ea54..1cec884 100644
--- a/src/main/java/com/phonepe/sdk/pg/payments/v2/CustomCheckoutClient.java
+++ b/src/main/java/com/phonepe/sdk/pg/payments/v2/CustomCheckoutClient.java
@@ -42,13 +42,10 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
import lombok.SneakyThrows;
public class CustomCheckoutClient extends BaseClient {
- private static final ConcurrentHashMap cachedInstances =
- new ConcurrentHashMap<>();
private List headers;
private CustomCheckoutClient(
@@ -102,20 +99,8 @@ public static CustomCheckoutClient getInstance(
boolean shouldPublishEvents)
throws PhonePeException {
final boolean shouldPublishInProd = shouldPublishEvents && env == Env.PRODUCTION;
- final String requestedClientSHA =
- CommonUtils.calculateSha256(
- clientId,
- clientSecret,
- clientVersion,
- env,
- shouldPublishInProd,
- FlowType.PG);
-
- return cachedInstances.computeIfAbsent(
- requestedClientSHA,
- key ->
- new CustomCheckoutClient(
- clientId, clientSecret, clientVersion, env, shouldPublishInProd));
+ return new CustomCheckoutClient(
+ clientId, clientSecret, clientVersion, env, shouldPublishInProd);
}
/**
diff --git a/src/main/java/com/phonepe/sdk/pg/payments/v2/StandardCheckoutClient.java b/src/main/java/com/phonepe/sdk/pg/payments/v2/StandardCheckoutClient.java
index 1ec1c38..a22405c 100644
--- a/src/main/java/com/phonepe/sdk/pg/payments/v2/StandardCheckoutClient.java
+++ b/src/main/java/com/phonepe/sdk/pg/payments/v2/StandardCheckoutClient.java
@@ -42,14 +42,11 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
import lombok.SneakyThrows;
/** The StandardCheckout client class provides methods for interacting with the PhonePe APIs. */
public class StandardCheckoutClient extends BaseClient {
- private static final ConcurrentHashMap cachedInstances =
- new ConcurrentHashMap<>();
private List headers;
private StandardCheckoutClient(
@@ -103,20 +100,8 @@ public static StandardCheckoutClient getInstance(
boolean shouldPublishEvents)
throws PhonePeException {
final boolean shouldPublishInProd = shouldPublishEvents && env == Env.PRODUCTION;
- final String requestedClientSHA =
- CommonUtils.calculateSha256(
- clientId,
- clientSecret,
- clientVersion,
- env,
- shouldPublishInProd,
- FlowType.PG_CHECKOUT);
-
- return cachedInstances.computeIfAbsent(
- requestedClientSHA,
- key ->
- new StandardCheckoutClient(
- clientId, clientSecret, clientVersion, env, shouldPublishInProd));
+ return new StandardCheckoutClient(
+ clientId, clientSecret, clientVersion, env, shouldPublishInProd);
}
/**
diff --git a/src/main/java/com/phonepe/sdk/pg/payments/v2/models/request/CreateSdkOrderRequest.java b/src/main/java/com/phonepe/sdk/pg/payments/v2/models/request/CreateSdkOrderRequest.java
index cbbd59b..066236c 100644
--- a/src/main/java/com/phonepe/sdk/pg/payments/v2/models/request/CreateSdkOrderRequest.java
+++ b/src/main/java/com/phonepe/sdk/pg/payments/v2/models/request/CreateSdkOrderRequest.java
@@ -35,6 +35,7 @@ public class CreateSdkOrderRequest {
private PaymentFlow paymentFlow;
private Long expireAfter;
private List constraints;
+ private Boolean disablePaymentRetry;
/**
* Builds SDK order Request
@@ -54,11 +55,13 @@ public CreateSdkOrderRequest(
MetaInfo metaInfo,
String message,
String redirectUrl,
- Long expireAfter) {
+ Long expireAfter,
+ Boolean disablePaymentRetry) {
this.merchantOrderId = merchantOrderId;
this.amount = amount;
this.metaInfo = metaInfo;
this.expireAfter = expireAfter;
+ this.disablePaymentRetry = disablePaymentRetry;
MerchantUrls merchantUrls = MerchantUrls.builder().redirectUrl(redirectUrl).build();
this.setPaymentFlow(
PgCheckoutPaymentFlow.builder()
@@ -83,12 +86,14 @@ public CreateSdkOrderRequest(
long amount,
MetaInfo metaInfo,
List constraints,
- Long expireAfter) {
+ Long expireAfter,
+ Boolean disablePaymentRetry) {
this.merchantOrderId = merchantOrderId;
this.amount = amount;
this.metaInfo = metaInfo;
this.expireAfter = expireAfter;
this.constraints = constraints;
+ this.disablePaymentRetry = disablePaymentRetry;
this.setPaymentFlow(PgPaymentFlow.builder().build());
}
}
diff --git a/src/main/java/com/phonepe/sdk/pg/subscription/v2/SubscriptionClient.java b/src/main/java/com/phonepe/sdk/pg/subscription/v2/SubscriptionClient.java
index 3640064..165f65c 100644
--- a/src/main/java/com/phonepe/sdk/pg/subscription/v2/SubscriptionClient.java
+++ b/src/main/java/com/phonepe/sdk/pg/subscription/v2/SubscriptionClient.java
@@ -41,13 +41,10 @@
import com.phonepe.sdk.pg.subscription.v2.models.response.SubscriptionStatusResponseV2;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
import lombok.SneakyThrows;
public class SubscriptionClient extends BaseClient {
- private static final ConcurrentHashMap cachedInstances =
- new ConcurrentHashMap<>();
private List headers;
private SubscriptionClient(
@@ -102,20 +99,8 @@ public static SubscriptionClient getInstance(
boolean shouldPublishEvents)
throws PhonePeException {
final boolean shouldPublishInProd = shouldPublishEvents && env == Env.PRODUCTION;
- final String requestedClientSHA =
- CommonUtils.calculateSha256(
- clientId,
- clientSecret,
- clientVersion,
- env,
- shouldPublishInProd,
- FlowType.SUBSCRIPTION);
-
- return cachedInstances.computeIfAbsent(
- requestedClientSHA,
- key ->
- new SubscriptionClient(
- clientId, clientSecret, clientVersion, env, shouldPublishInProd));
+ return new SubscriptionClient(
+ clientId, clientSecret, clientVersion, env, shouldPublishInProd);
}
/**
diff --git a/src/main/resources/sdk.properties b/src/main/resources/sdk.properties
new file mode 100644
index 0000000..325bf76
--- /dev/null
+++ b/src/main/resources/sdk.properties
@@ -0,0 +1 @@
+sdk.version=${project.version}
\ No newline at end of file
diff --git a/src/test/CreateOrderTest.java b/src/test/CreateOrderTest.java
index 92eb03d..de78503 100644
--- a/src/test/CreateOrderTest.java
+++ b/src/test/CreateOrderTest.java
@@ -123,4 +123,197 @@ void testCreateOrderBadRequest() {
Assertions.assertEquals(400, phonePeException.getHttpStatusCode());
Assertions.assertEquals("Bad Request", phonePeException.getCode());
}
+
+ @Test
+ void testCreateOrderWithDisablePaymentRetryTrue() {
+ String redirectUrl = "https://google.com";
+
+ CreateSdkOrderRequest createSdkOrderRequest =
+ CreateSdkOrderRequest.StandardCheckoutBuilder()
+ .merchantOrderId(merchantOrderId)
+ .amount(amount)
+ .redirectUrl(redirectUrl)
+ .disablePaymentRetry(true)
+ .build();
+ final String url = StandardCheckoutConstants.CREATE_ORDER_API;
+ CreateSdkOrderResponse createSdkOrderResponse =
+ CreateSdkOrderResponse.builder()
+ .expireAt(1432423)
+ .orderId("orderId")
+ .token("token")
+ .state("PENDING")
+ .build();
+
+ addStubForPostRequest(
+ url,
+ getHeaders(),
+ createSdkOrderRequest,
+ HttpStatus.SC_OK,
+ Maps.newHashMap(),
+ createSdkOrderResponse);
+
+ CreateSdkOrderResponse actual =
+ standardCheckoutClient.createSdkOrder(createSdkOrderRequest);
+ Assertions.assertEquals(actual, createSdkOrderResponse);
+ Assertions.assertTrue(createSdkOrderRequest.getDisablePaymentRetry());
+ }
+
+ @Test
+ void testCreateOrderWithDisablePaymentRetryFalse() {
+ String redirectUrl = "https://google.com";
+
+ CreateSdkOrderRequest createSdkOrderRequest =
+ CreateSdkOrderRequest.StandardCheckoutBuilder()
+ .merchantOrderId(merchantOrderId)
+ .amount(amount)
+ .redirectUrl(redirectUrl)
+ .disablePaymentRetry(false)
+ .build();
+ final String url = StandardCheckoutConstants.CREATE_ORDER_API;
+ CreateSdkOrderResponse createSdkOrderResponse =
+ CreateSdkOrderResponse.builder()
+ .expireAt(1432423)
+ .orderId("orderId")
+ .token("token")
+ .state("PENDING")
+ .build();
+
+ addStubForPostRequest(
+ url,
+ getHeaders(),
+ createSdkOrderRequest,
+ HttpStatus.SC_OK,
+ Maps.newHashMap(),
+ createSdkOrderResponse);
+
+ CreateSdkOrderResponse actual =
+ standardCheckoutClient.createSdkOrder(createSdkOrderRequest);
+ Assertions.assertEquals(actual, createSdkOrderResponse);
+ Assertions.assertFalse(createSdkOrderRequest.getDisablePaymentRetry());
+ }
+
+ @Test
+ void testCreateOrderWithDisablePaymentRetryNull() {
+ String redirectUrl = "https://google.com";
+
+ CreateSdkOrderRequest createSdkOrderRequest =
+ CreateSdkOrderRequest.StandardCheckoutBuilder()
+ .merchantOrderId(merchantOrderId)
+ .amount(amount)
+ .redirectUrl(redirectUrl)
+ .build();
+ final String url = StandardCheckoutConstants.CREATE_ORDER_API;
+ CreateSdkOrderResponse createSdkOrderResponse =
+ CreateSdkOrderResponse.builder()
+ .expireAt(1432423)
+ .orderId("orderId")
+ .token("token")
+ .state("PENDING")
+ .build();
+
+ addStubForPostRequest(
+ url,
+ getHeaders(),
+ createSdkOrderRequest,
+ HttpStatus.SC_OK,
+ Maps.newHashMap(),
+ createSdkOrderResponse);
+
+ CreateSdkOrderResponse actual =
+ standardCheckoutClient.createSdkOrder(createSdkOrderRequest);
+ Assertions.assertEquals(actual, createSdkOrderResponse);
+ Assertions.assertNull(createSdkOrderRequest.getDisablePaymentRetry());
+ }
+
+ @Test
+ void testCreateOrderCustomCheckoutWithDisablePaymentRetryTrue() {
+
+ CreateSdkOrderRequest createSdkOrderRequest =
+ CreateSdkOrderRequest.CustomCheckoutBuilder()
+ .merchantOrderId(merchantOrderId)
+ .amount(amount)
+ .disablePaymentRetry(true)
+ .build();
+ final String url = CustomCheckoutConstants.CREATE_ORDER_API;
+ CreateSdkOrderResponse createSdkOrderResponse =
+ CreateSdkOrderResponse.builder()
+ .expireAt(1432423)
+ .orderId("orderId")
+ .token("token")
+ .state("PENDING")
+ .build();
+
+ addStubForPostRequest(
+ url,
+ getHeaders(),
+ createSdkOrderRequest,
+ HttpStatus.SC_OK,
+ Maps.newHashMap(),
+ createSdkOrderResponse);
+
+ CreateSdkOrderResponse actual = customCheckoutClient.createSdkOrder(createSdkOrderRequest);
+ Assertions.assertEquals(actual, createSdkOrderResponse);
+ Assertions.assertTrue(createSdkOrderRequest.getDisablePaymentRetry());
+ }
+
+ @Test
+ void testCreateOrderCustomCheckoutWithDisablePaymentRetryFalse() {
+
+ CreateSdkOrderRequest createSdkOrderRequest =
+ CreateSdkOrderRequest.CustomCheckoutBuilder()
+ .merchantOrderId(merchantOrderId)
+ .amount(amount)
+ .disablePaymentRetry(false)
+ .build();
+ final String url = CustomCheckoutConstants.CREATE_ORDER_API;
+ CreateSdkOrderResponse createSdkOrderResponse =
+ CreateSdkOrderResponse.builder()
+ .expireAt(1432423)
+ .orderId("orderId")
+ .token("token")
+ .state("PENDING")
+ .build();
+
+ addStubForPostRequest(
+ url,
+ getHeaders(),
+ createSdkOrderRequest,
+ HttpStatus.SC_OK,
+ Maps.newHashMap(),
+ createSdkOrderResponse);
+
+ CreateSdkOrderResponse actual = customCheckoutClient.createSdkOrder(createSdkOrderRequest);
+ Assertions.assertEquals(actual, createSdkOrderResponse);
+ Assertions.assertFalse(createSdkOrderRequest.getDisablePaymentRetry());
+ }
+
+ @Test
+ void testCreateOrderCustomCheckoutWithDisablePaymentRetryNull() {
+
+ CreateSdkOrderRequest createSdkOrderRequest =
+ CreateSdkOrderRequest.CustomCheckoutBuilder()
+ .merchantOrderId(merchantOrderId)
+ .amount(amount)
+ .build();
+ final String url = CustomCheckoutConstants.CREATE_ORDER_API;
+ CreateSdkOrderResponse createSdkOrderResponse =
+ CreateSdkOrderResponse.builder()
+ .expireAt(1432423)
+ .orderId("orderId")
+ .token("token")
+ .state("PENDING")
+ .build();
+
+ addStubForPostRequest(
+ url,
+ getHeaders(),
+ createSdkOrderRequest,
+ HttpStatus.SC_OK,
+ Maps.newHashMap(),
+ createSdkOrderResponse);
+
+ CreateSdkOrderResponse actual = customCheckoutClient.createSdkOrder(createSdkOrderRequest);
+ Assertions.assertEquals(actual, createSdkOrderResponse);
+ Assertions.assertNull(createSdkOrderRequest.getDisablePaymentRetry());
+ }
}
diff --git a/src/test/SingletonCustomCheckoutTest.java b/src/test/SingletonCustomCheckoutTest.java
deleted file mode 100644
index a2c9198..0000000
--- a/src/test/SingletonCustomCheckoutTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2025 Original Author(s), PhonePe India Pvt. Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
-
-import com.google.common.collect.Maps;
-import com.phonepe.sdk.pg.Env;
-import com.phonepe.sdk.pg.common.models.request.PgPaymentRequest;
-import com.phonepe.sdk.pg.common.models.response.PgPaymentResponse;
-import com.phonepe.sdk.pg.common.tokenhandler.OAuthResponse;
-import com.phonepe.sdk.pg.payments.v2.CustomCheckoutClient;
-import com.phonepe.sdk.pg.payments.v2.customcheckout.CustomCheckoutConstants;
-import okhttp3.FormBody;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import wiremock.org.apache.http.HttpStatus;
-
-public class SingletonCustomCheckoutTest extends BaseSetup {
-
- FormBody formBody =
- new FormBody.Builder()
- .add("client_id", clientId)
- .add("client_secret", clientSecret)
- .add("grant_type", "client_credentials")
- .add("client_version", String.valueOf(clientVersion))
- .build();
-
- @Test
- void testSingletonViaGetInstance() {
- CustomCheckoutClient customCheckoutClient1 =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- CustomCheckoutClient customCheckoutClient2 =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
-
- Assertions.assertEquals(customCheckoutClient1, customCheckoutClient2);
- }
-
- @Test
- void testSingletonWithDiffParameters() {
- CustomCheckoutClient customCheckoutClient1 =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- CustomCheckoutClient customCheckoutClient2 = CustomCheckoutClient.getInstance(
- "clientId2", "clientSecret2", 1, Env.TEST);
- Assertions.assertNotEquals(customCheckoutClient1, customCheckoutClient2);
- Assertions.assertNotNull(customCheckoutClient2);
- }
-
- @Test
- void testMultipleSameClientSingleAuthCall() {
- wireMockServer.resetRequests();
- customCheckoutClient.getTokenService().setOAuthResponse(null);
- PgPaymentRequest pgPaymentRequest =
- PgPaymentRequest.UpiQrRequestBuilder()
- .merchantOrderId("MerchantOrderId")
- .amount(100)
- .build();
-
- PgPaymentResponse pgPaymentResponse =
- PgPaymentResponse.builder()
- .orderId(String.valueOf(java.time.Instant.now().getEpochSecond()))
- .state("PENDING")
- .expireAt(java.time.Instant.now().getEpochSecond())
- .qrData("qrData")
- .build();
-
- long currentTime = java.time.Instant.now().getEpochSecond();
- OAuthResponse oAuthResponse =
- OAuthResponse.builder()
- .accessToken("accessToken")
- .encryptedAccessToken("encryptedAccessToken")
- .expiresAt(currentTime + 200)
- .expiresIn(453543)
- .issuedAt(currentTime)
- .refreshToken("refreshToken")
- .tokenType("O-Bearer")
- .sessionExpiresAt(currentTime + 200)
- .build();
-
- CustomCheckoutClient customCheckoutClient1 =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- CustomCheckoutClient customCheckoutClient2 =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- CustomCheckoutClient customCheckoutClient3 =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- CustomCheckoutClient customCheckoutClient4 =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
-
- final String url = CustomCheckoutConstants.PAY_API;
- addStubForPostRequest(
- url,
- getHeaders(),
- pgPaymentRequest,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- pgPaymentResponse);
- addStubForFormDataPostRequest(
- authUrl,
- getAuthHeaders(),
- formBody,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- oAuthResponse);
- PgPaymentResponse actual = customCheckoutClient1.pay(pgPaymentRequest);
- actual = customCheckoutClient2.pay(pgPaymentRequest);
- actual = customCheckoutClient3.pay(pgPaymentRequest);
- actual = customCheckoutClient4.pay(pgPaymentRequest);
-
- wireMockServer.verify(1, postRequestedFor(urlPathMatching(authUrl)));
- }
-
- @Test
- void testMultipleDifferentClientMultipleAuthCall() {
- String clientId = "clientId_for_auth1";
- String clientSecret = "clientSecret_for_auth1";
- int clientVersion = 1;
-
- String clientId1 = "clientId1";
- String clientSecret1 = "clientSecret1";
-
- FormBody mockFormBody =
- new FormBody.Builder()
- .add("client_id", clientId)
- .add("client_secret", clientSecret)
- .add("grant_type", "client_credentials")
- .add("client_version", String.valueOf(clientVersion))
- .build();
-
- wireMockServer.resetRequests();
- String redirectUrl = "https://redirectUrl.com";
- PgPaymentRequest pgPaymentRequest =
- PgPaymentRequest.UpiQrRequestBuilder()
- .merchantOrderId("MerchantOrderId")
- .amount(100)
- .build();
-
- PgPaymentResponse pgPaymentResponse =
- PgPaymentResponse.builder()
- .orderId(String.valueOf(java.time.Instant.now().getEpochSecond()))
- .state("PENDING")
- .expireAt(java.time.Instant.now().getEpochSecond())
- .qrData("qrData")
- .build();
-
- long currentTime = java.time.Instant.now().getEpochSecond();
- OAuthResponse oAuthResponse =
- OAuthResponse.builder()
- .accessToken("accessToken")
- .encryptedAccessToken("encryptedAccessToken")
- .expiresAt(currentTime + 200)
- .expiresIn(453543)
- .issuedAt(currentTime)
- .refreshToken("refreshToken")
- .tokenType("O-Bearer")
- .sessionExpiresAt(currentTime + 200)
- .build();
-
- CustomCheckoutClient customCheckoutClient1 =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- CustomCheckoutClient customCheckoutClient2 =
- CustomCheckoutClient.getInstance(clientId1, clientSecret1, clientVersion, env);
-
- final String url = CustomCheckoutConstants.PAY_API;
- addStubForPostRequest(
- url,
- getHeaders(),
- pgPaymentRequest,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- pgPaymentResponse);
-
- FormBody mockFormBody1 =
- new FormBody.Builder()
- .add("client_id", clientId1)
- .add("client_secret", clientSecret1)
- .add("grant_type", "client_credentials")
- .add("client_version", String.valueOf(clientVersion))
- .build();
-
- addStubForFormDataPostRequest(
- authUrl,
- getAuthHeaders(),
- mockFormBody,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- oAuthResponse);
-
- addStubForFormDataPostRequest(
- authUrl,
- getAuthHeaders(),
- mockFormBody1,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- oAuthResponse);
-
- customCheckoutClient1.pay(pgPaymentRequest);
- customCheckoutClient2.pay(pgPaymentRequest);
-
- wireMockServer.verify(2, postRequestedFor(urlPathMatching(authUrl)));
- }
-
- @Test
- void testSingletonWithDifferentEnvironments() {
- CustomCheckoutClient customCheckoutClientProd =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, Env.PRODUCTION);
- CustomCheckoutClient customCheckoutClientSandbox =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, Env.SANDBOX);
-
- Assertions.assertNotEquals(customCheckoutClientProd, customCheckoutClientSandbox);
-
- CustomCheckoutClient customCheckoutClientProd2 =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, Env.PRODUCTION);
- Assertions.assertEquals(customCheckoutClientProd, customCheckoutClientProd2);
-
- CustomCheckoutClient customCheckoutClientSandbox2 =
- CustomCheckoutClient.getInstance(clientId, clientSecret, clientVersion, Env.SANDBOX);
- Assertions.assertEquals(customCheckoutClientSandbox, customCheckoutClientSandbox2);
- }
-}
diff --git a/src/test/SingletonStandardCheckoutTest.java b/src/test/SingletonStandardCheckoutTest.java
deleted file mode 100644
index 0ce88af..0000000
--- a/src/test/SingletonStandardCheckoutTest.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (c) 2025 Original Author(s), PhonePe India Pvt. Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.phonepe.sdk.pg.Env;
-import com.phonepe.sdk.pg.common.constants.Headers;
-import com.phonepe.sdk.pg.common.tokenhandler.OAuthResponse;
-import com.phonepe.sdk.pg.payments.v2.StandardCheckoutClient;
-import com.phonepe.sdk.pg.payments.v2.models.request.StandardCheckoutPayRequest;
-import com.phonepe.sdk.pg.payments.v2.models.response.StandardCheckoutPayResponse;
-import com.phonepe.sdk.pg.payments.v2.standardcheckout.StandardCheckoutConstants;
-import java.util.Map;
-import okhttp3.FormBody;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import wiremock.org.apache.http.HttpStatus;
-
-public class SingletonStandardCheckoutTest extends BaseSetup {
-
- FormBody formBody =
- new FormBody.Builder()
- .add("client_id", clientId)
- .add("client_secret", clientSecret)
- .add("grant_type", "client_credentials")
- .add("client_version", String.valueOf(clientVersion))
- .build();
-
- @Test
- void testSingletonViaGetInstance() {
- StandardCheckoutClient standardCheckoutClient1 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient2 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
-
- Assertions.assertEquals(standardCheckoutClient1, standardCheckoutClient2);
- }
-
- @Test
- void testSingletonWithDiffParameters() {
- StandardCheckoutClient standardCheckoutClient1 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient2 =
- StandardCheckoutClient.getInstance("clientId2", "clientSecret2", 1, Env.TEST);
- Assertions.assertNotEquals(standardCheckoutClient1, standardCheckoutClient2);
- Assertions.assertNotNull(standardCheckoutClient1);
- Assertions.assertNotNull(standardCheckoutClient2);
- }
-
- @Test
- void testMultipleSameClientSingleAuthCall() {
- wireMockServer.resetRequests();
- standardCheckoutClient.getTokenService().setOAuthResponse(null);
- String redirectUrl = "https://redirectUrl.com";
- StandardCheckoutPayRequest standardCheckoutPayRequest =
- StandardCheckoutPayRequest.builder()
- .merchantOrderId("merchantOrderId")
- .amount(100)
- .redirectUrl(redirectUrl)
- .build();
-
- StandardCheckoutPayResponse standardCheckoutResponse =
- StandardCheckoutPayResponse.builder()
- .orderId(String.valueOf(java.time.Instant.now().getEpochSecond()))
- .state("PENDING")
- .expireAt(java.time.Instant.now().getEpochSecond())
- .redirectUrl("https://google.com")
- .build();
-
- long currentTime = java.time.Instant.now().getEpochSecond();
- OAuthResponse oAuthResponse =
- OAuthResponse.builder()
- .accessToken("accessToken")
- .encryptedAccessToken("encryptedAccessToken")
- .expiresAt(currentTime + 200)
- .expiresIn(453543)
- .issuedAt(currentTime)
- .refreshToken("refreshToken")
- .tokenType("O-Bearer")
- .sessionExpiresAt(currentTime + 200)
- .build();
-
- StandardCheckoutClient standardCheckoutClient1 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient2 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient3 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient4 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
-
- final String url = StandardCheckoutConstants.PAY_API;
- addStubForPostRequest(
- url,
- getHeaders(),
- standardCheckoutPayRequest,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- standardCheckoutResponse);
- addStubForFormDataPostRequest(
- authUrl,
- getAuthHeaders(),
- formBody,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- oAuthResponse);
- StandardCheckoutPayResponse actual =
- standardCheckoutClient1.pay(standardCheckoutPayRequest);
- actual = standardCheckoutClient2.pay(standardCheckoutPayRequest);
- actual = standardCheckoutClient3.pay(standardCheckoutPayRequest);
- actual = standardCheckoutClient4.pay(standardCheckoutPayRequest);
-
- wireMockServer.verify(1, postRequestedFor(urlPathMatching(authUrl)));
- }
-
- @Test
- void testMultipleDifferentClientSingleAuthCall() {
- String clientId = "clientId_for_auth1";
- String clientSecret = "clientSecret_for_auth1";
- String clientId1 = "clientId_for_auth2";
- String clientSecret1 = "clientSecret_for_auth2";
- int clientVersion = 1;
-
- FormBody mockFormBody =
- new FormBody.Builder()
- .add("client_id", clientId)
- .add("client_secret", clientSecret)
- .add("grant_type", "client_credentials")
- .add("client_version", String.valueOf(clientVersion))
- .build();
-
- FormBody mockFormBody1 =
- new FormBody.Builder()
- .add("client_id", clientId1)
- .add("client_secret", clientSecret1)
- .add("grant_type", "client_credentials")
- .add("client_version", String.valueOf(clientVersion))
- .build();
-
- wireMockServer.resetRequests();
- String redirectUrl = "https://redirectUrl.com";
- StandardCheckoutPayRequest standardCheckoutPayRequest =
- StandardCheckoutPayRequest.builder()
- .merchantOrderId("merchantOrderId")
- .amount(100)
- .redirectUrl(redirectUrl)
- .build();
-
- StandardCheckoutPayResponse standardCheckoutResponse =
- StandardCheckoutPayResponse.builder()
- .orderId(String.valueOf(java.time.Instant.now().getEpochSecond()))
- .state("PENDING")
- .expireAt(java.time.Instant.now().getEpochSecond())
- .redirectUrl("https://google.com")
- .build();
-
- long currentTime = java.time.Instant.now().getEpochSecond();
- OAuthResponse oAuthResponse =
- OAuthResponse.builder()
- .accessToken("accessToken")
- .encryptedAccessToken("encryptedAccessToken")
- .expiresAt(currentTime + 200)
- .expiresIn(453543)
- .issuedAt(currentTime)
- .refreshToken("refreshToken")
- .tokenType("O-Bearer")
- .sessionExpiresAt(currentTime + 200)
- .build();
-
- StandardCheckoutClient standardCheckoutClient1 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient2 =
- StandardCheckoutClient.getInstance(clientId1, clientSecret1, clientVersion, env);
-
- final String url = StandardCheckoutConstants.PAY_API;
- addStubForPostRequest(
- url,
- getHeaders(),
- standardCheckoutPayRequest,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- standardCheckoutResponse);
- addStubForFormDataPostRequest(
- authUrl,
- getAuthHeaders(),
- mockFormBody,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- oAuthResponse);
- addStubForFormDataPostRequest(
- authUrl,
- getAuthHeaders(),
- mockFormBody1,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- oAuthResponse);
- standardCheckoutClient1.pay(standardCheckoutPayRequest);
- standardCheckoutClient2.pay(standardCheckoutPayRequest);
-
- wireMockServer.verify(2, postRequestedFor(urlPathMatching(authUrl)));
- }
-
- public Map getHeaders() {
- return ImmutableMap.builder()
- .put(Headers.CONTENT_TYPE, APPLICATION_JSON)
- .put(Headers.SOURCE, Headers.INTEGRATION)
- .put(Headers.SOURCE_VERSION, Headers.API_VERSION)
- .put(Headers.SOURCE_PLATFORM, Headers.SDK_TYPE)
- .put(Headers.SOURCE_PLATFORM_VERSION, Headers.SDK_VERSION)
- .put(Headers.OAUTH_AUTHORIZATION, "O-Bearer accessToken")
- .build();
- }
-
- @Test
- void testSingletonWithDifferentEnvironments() {
- StandardCheckoutClient standardCheckoutClientProd =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, Env.PRODUCTION);
- StandardCheckoutClient standardCheckoutClientSandbox =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, Env.SANDBOX);
-
- Assertions.assertNotEquals(standardCheckoutClientProd, standardCheckoutClientSandbox);
-
- StandardCheckoutClient standardCheckoutClientProd2 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, Env.PRODUCTION);
- Assertions.assertEquals(standardCheckoutClientProd, standardCheckoutClientProd2);
-
- StandardCheckoutClient standardCheckoutClientSandbox2 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, Env.SANDBOX);
- Assertions.assertEquals(standardCheckoutClientSandbox, standardCheckoutClientSandbox2);
- }
-}
diff --git a/src/test/SingletonSubscriptionClientTest.java b/src/test/SingletonSubscriptionClientTest.java
deleted file mode 100644
index 76ad08d..0000000
--- a/src/test/SingletonSubscriptionClientTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/*
- * Copyright (c) 2025 Original Author(s), PhonePe India Pvt. Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import com.phonepe.sdk.pg.Env;
-import com.phonepe.sdk.pg.subscription.v2.SubscriptionClient;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-class SingletonSubscriptionClientTest extends BaseSetup {
-
- @Test
- void testSingletonViaGetInstance() {
- SubscriptionClient subscriptionClient1 =
- SubscriptionClient.getInstance(clientId, clientSecret, clientVersion, env);
- SubscriptionClient subscriptionClient2 =
- SubscriptionClient.getInstance(clientId, clientSecret, clientVersion, env);
-
- Assertions.assertEquals(subscriptionClient1, subscriptionClient2);
- }
-
- @Test
- void testSingletonWithDiffParameters() {
- SubscriptionClient subscriptionClient1 =
- SubscriptionClient.getInstance(clientId, clientSecret, clientVersion, env);
- SubscriptionClient subscriptionClient2 = SubscriptionClient.getInstance(
- "clientId2", "clientSecret2", 1, Env.TEST);
- Assertions.assertNotEquals(subscriptionClient1, subscriptionClient2);
- Assertions.assertNotNull(subscriptionClient2);
- }
-
- @Test
- void testSingletonWithDifferentEnvironments() {
- SubscriptionClient subscriptionClientProd =
- SubscriptionClient.getInstance(clientId, clientSecret, clientVersion, Env.PRODUCTION);
- SubscriptionClient subscriptionClientSandbox =
- SubscriptionClient.getInstance(clientId, clientSecret, clientVersion, Env.SANDBOX);
-
- Assertions.assertNotEquals(subscriptionClientProd, subscriptionClientSandbox);
-
- SubscriptionClient subscriptionClientProd2 =
- SubscriptionClient.getInstance(clientId, clientSecret, clientVersion, Env.PRODUCTION);
- Assertions.assertEquals(subscriptionClientProd, subscriptionClientProd2);
-
- SubscriptionClient subscriptionClientSandbox2 =
- SubscriptionClient.getInstance(clientId, clientSecret, clientVersion, Env.SANDBOX);
- Assertions.assertEquals(subscriptionClientSandbox, subscriptionClientSandbox2);
- }
-}
diff --git a/src/test/SingletonTest.java b/src/test/SingletonTest.java
deleted file mode 100644
index 9b94cb6..0000000
--- a/src/test/SingletonTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2025 Original Author(s), PhonePe India Pvt. Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
-
-import com.google.common.collect.Maps;
-import com.phonepe.sdk.pg.Env;
-import com.phonepe.sdk.pg.common.tokenhandler.OAuthResponse;
-import com.phonepe.sdk.pg.payments.v2.StandardCheckoutClient;
-import com.phonepe.sdk.pg.payments.v2.models.request.StandardCheckoutPayRequest;
-import com.phonepe.sdk.pg.payments.v2.models.response.StandardCheckoutPayResponse;
-import com.phonepe.sdk.pg.payments.v2.standardcheckout.StandardCheckoutConstants;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import wiremock.org.apache.http.HttpStatus;
-
-public class SingletonTest extends BaseSetupWithOAuth {
-
- @Test
- void testSingletonViaGetInstance() {
- StandardCheckoutClient standardCheckoutClient1 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient2 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
-
- Assertions.assertEquals(standardCheckoutClient1, standardCheckoutClient2);
- }
-
- @Test
- void testSingletonWithDiffParameters() {
- StandardCheckoutClient standardCheckoutClient1 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient2 = StandardCheckoutClient.getInstance(
- "clientId2", "clientSecret2", 1, Env.TEST);
- Assertions.assertNotNull(standardCheckoutClient2);
- Assertions.assertNotEquals(standardCheckoutClient1, standardCheckoutClient2);
- }
-
- @Test
- void testMultipleClientSingleAuthCall() {
- wireMockServer.resetRequests();
- standardCheckoutClient.getTokenService().setOAuthResponse(null);
- String redirectUrl = "https://redirectUrl.com";
- StandardCheckoutPayRequest standardCheckoutPayRequest =
- StandardCheckoutPayRequest.builder()
- .merchantOrderId("merchantOrderId")
- .amount(100)
- .redirectUrl(redirectUrl)
- .build();
-
- StandardCheckoutPayResponse standardCheckoutResponse =
- StandardCheckoutPayResponse.builder()
- .orderId(String.valueOf(java.time.Instant.now().getEpochSecond()))
- .state("PENDING")
- .expireAt(java.time.Instant.now().getEpochSecond())
- .redirectUrl("https://google.com")
- .build();
-
- long currentTime = java.time.Instant.now().getEpochSecond();
- OAuthResponse oAuthResponse =
- OAuthResponse.builder()
- .accessToken("accessToken")
- .encryptedAccessToken("encryptedAccessToken")
- .expiresAt(currentTime + 200)
- .expiresIn(453543)
- .issuedAt(currentTime)
- .refreshToken("refreshToken")
- .tokenType("O-Bearer")
- .sessionExpiresAt(currentTime + 200)
- .build();
-
- StandardCheckoutClient standardCheckoutClient1 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient2 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient3 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
- StandardCheckoutClient standardCheckoutClient4 =
- StandardCheckoutClient.getInstance(clientId, clientSecret, clientVersion, env);
-
- final String url = StandardCheckoutConstants.PAY_API;
- addStubForPostRequest(
- url,
- getHeaders(),
- standardCheckoutPayRequest,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- standardCheckoutResponse);
- addStubForFormDataPostRequest(
- authUrl,
- getAuthHeaders(),
- formBody,
- HttpStatus.SC_OK,
- Maps.newHashMap(),
- oAuthResponse);
- standardCheckoutClient1.pay(standardCheckoutPayRequest);
- standardCheckoutClient2.pay(standardCheckoutPayRequest);
- standardCheckoutClient3.pay(standardCheckoutPayRequest);
- standardCheckoutClient4.pay(standardCheckoutPayRequest);
-
- wireMockServer.verify(1, postRequestedFor(urlPathMatching(authUrl)));
- }
-}
diff --git a/src/test/headers/HeadersTest.java b/src/test/headers/HeadersTest.java
new file mode 100644
index 0000000..97dd23e
--- /dev/null
+++ b/src/test/headers/HeadersTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2025 Original Author(s), PhonePe India Pvt. Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package headers;
+
+import org.junit.jupiter.api.Assertions;
+
+import com.phonepe.sdk.pg.common.constants.Headers;
+import java.io.InputStream;
+import java.util.Properties;
+import org.junit.jupiter.api.Test;
+
+class HeadersTest {
+
+ /**
+ * Test that SDK_VERSION is loaded from properties file and not null
+ */
+ @Test
+ void testSDKVersionIsLoadedFromProperties() {
+ Assertions.assertNotNull(Headers.SDK_VERSION, "SDK_VERSION should not be null");
+ Assertions.assertFalse(Headers.SDK_VERSION.isEmpty(), "SDK_VERSION should not be empty");
+ }
+
+ /**
+ * Test that SDK_VERSION follows semantic versioning format (e.g., 2.1.8)
+ */
+ @Test
+ void testSDKVersionFormat() {
+ Assertions.assertTrue(
+ Headers.SDK_VERSION.matches("\\d+\\.\\d+\\.\\d+"),
+ "SDK_VERSION should match semantic version format (X.Y.Z). Got: "
+ + Headers.SDK_VERSION);
+ }
+
+ /**
+ * Test that SUBSCRIPTION_API_VERSION is loaded from properties file and not null
+ */
+ @Test
+ void testSubscriptionAPIVersionIsLoadedFromProperties() {
+ Assertions.assertNotNull(
+ Headers.SUBSCRIPTION_API_VERSION, "SUBSCRIPTION_API_VERSION should not be null");
+ Assertions.assertFalse(
+ Headers.SUBSCRIPTION_API_VERSION.isEmpty(),
+ "SUBSCRIPTION_API_VERSION should not be empty");
+ }
+
+ /**
+ * Test that both SDK_VERSION and SUBSCRIPTION_API_VERSION have the same value
+ * since they both load from the same property
+ */
+ @Test
+ void testSDKVersionMatchesSubscriptionAPIVersion() {
+ Assertions.assertEquals(
+ Headers.SDK_VERSION,
+ Headers.SUBSCRIPTION_API_VERSION,
+ "SDK_VERSION and SUBSCRIPTION_API_VERSION should have the same value");
+ }
+
+ /**
+ * Test that properties file exists and is accessible in classpath
+ */
+ @Test
+ void testPropertiesFileExists() {
+ InputStream input = getClass().getResourceAsStream("/sdk.properties");
+ Assertions.assertNotNull(input, "sdk.properties file should exist in classpath");
+ }
+
+ /**
+ * Test that properties file has been filtered by Maven
+ * (i.e., ${project.version} has been replaced with actual version)
+ */
+ @Test
+ void testPropertiesFileIsFiltered() throws Exception {
+ Properties properties = new Properties();
+ try (InputStream input = getClass().getResourceAsStream("/sdk.properties")) {
+ Assertions.assertNotNull(input, "sdk.properties should be available");
+ properties.load(input);
+
+ String version = properties.getProperty("sdk.version");
+ Assertions.assertNotNull(version, "sdk.version property should exist");
+ Assertions.assertFalse(
+ version.contains("${"),
+ "sdk.version should not contain unresolved Maven placeholders like ${project.version}. Got: "
+ + version);
+ Assertions.assertTrue(
+ version.matches("\\d+\\.\\d+\\.\\d+"),
+ "sdk.version should be in semantic version format. Got: " + version);
+ }
+ }
+
+ /**
+ * Test that all header constants are not null
+ */
+ @Test
+ void testAllConstantsAreNotNull() {
+ Assertions.assertNotNull(Headers.API_VERSION, "API_VERSION should not be null");
+ Assertions.assertNotNull(
+ Headers.SUBSCRIPTION_API_VERSION, "SUBSCRIPTION_API_VERSION should not be null");
+ Assertions.assertNotNull(Headers.INTEGRATION, "INTEGRATION should not be null");
+ Assertions.assertNotNull(Headers.SDK_VERSION, "SDK_VERSION should not be null");
+ Assertions.assertNotNull(Headers.SDK_TYPE, "SDK_TYPE should not be null");
+ Assertions.assertNotNull(Headers.SOURCE, "SOURCE should not be null");
+ Assertions.assertNotNull(Headers.SOURCE_VERSION, "SOURCE_VERSION should not be null");
+ Assertions.assertNotNull(Headers.SOURCE_PLATFORM, "SOURCE_PLATFORM should not be null");
+ Assertions.assertNotNull(
+ Headers.SOURCE_PLATFORM_VERSION, "SOURCE_PLATFORM_VERSION should not be null");
+ Assertions.assertNotNull(Headers.OAUTH_AUTHORIZATION, "OAUTH_AUTHORIZATION should not be null");
+ Assertions.assertNotNull(Headers.CONTENT_TYPE, "CONTENT_TYPE should not be null");
+ Assertions.assertNotNull(Headers.ACCEPT, "ACCEPT should not be null");
+ }
+
+ /**
+ * Test that SDK_VERSION matches the expected format and contains valid version parts
+ */
+ @Test
+ void testSDKVersionComponents() {
+ String[] versionParts = Headers.SDK_VERSION.split("\\.");
+ Assertions.assertEquals(
+ 3,
+ versionParts.length,
+ "SDK_VERSION should have 3 parts (major.minor.patch). Got: "
+ + Headers.SDK_VERSION);
+
+ // Each part should be a number
+ for (int i = 0; i < versionParts.length; i++) {
+ Assertions.assertTrue(
+ versionParts[i].matches("\\d+"),
+ "Version part " + i + " should be numeric. Got: " + versionParts[i]);
+ }
+ }
+
+ /**
+ * Test that Header values don't contain common problematic characters
+ */
+ @Test
+ void testHeaderValuesDoNotContainProblematicCharacters() {
+ // Version values should not contain whitespace or special characters
+ Assertions.assertFalse(
+ Headers.SDK_VERSION.contains(" "),
+ "SDK_VERSION should not contain whitespace");
+ Assertions.assertFalse(
+ Headers.SUBSCRIPTION_API_VERSION.contains(" "),
+ "SUBSCRIPTION_API_VERSION should not contain whitespace");
+ Assertions.assertFalse(
+ Headers.API_VERSION.contains(" "), "API_VERSION should not contain whitespace");
+ }
+
+ /**
+ * Integration test: Verify that properties loaded in static block
+ * match what can be read directly from the file
+ */
+ @Test
+ void testStaticBlockPropertiesMatchFileContent() throws Exception {
+ Properties fileProperties = new Properties();
+ try (InputStream input = getClass().getResourceAsStream("/sdk.properties")) {
+ fileProperties.load(input);
+ }
+
+ String fileVersion = fileProperties.getProperty("sdk.version");
+ Assertions.assertEquals(
+ Headers.SDK_VERSION,
+ fileVersion,
+ "SDK_VERSION from Headers should match sdk.version from file");
+ Assertions.assertEquals(
+ Headers.SUBSCRIPTION_API_VERSION,
+ fileVersion,
+ "SUBSCRIPTION_API_VERSION from Headers should match sdk.version from file");
+ }
+}