Java · Maven Central · Java 11+
Overview
The official Java SDK wraps the full SabPaisa Payment Gateway 2.0 API into a single thread-safe client. Drop it into any Java application — no framework lock-in — and you get type-safe builders, automatic checksum generation, idempotent retries, and typed exceptions for every error case.
Type-Safe Builders
Fluent builders for every request and response
Auto Checksum
SDK generates and verifies HMAC checksums for you
Smart Retries
Auto-retries on 429/5xx with exponential backoff
Idempotency Keys
Prevents duplicate payments and refunds on retry
Typed Exceptions
ApiException, ChecksumException, ValidationException
Thread-Safe Client
Create once, reuse across your application
Requirements
Installation
Maven
Add the dependency to your pom.xml.
1<dependency>
2 <groupId>in.sabpaisa</groupId>
3 <artifactId>pg-sdk</artifactId>
4 <version>1.0.1</version>
5</dependency>Gradle
Or add to your build.gradle.
1implementation 'in.sabpaisa:pg-sdk:1.0.1'Quick Start
Configure the client, create a payment session, and redirect the customer to checkout.
1import in.sabpaisa.pg.*;
2import in.sabpaisa.pg.models.*;
3
4// 1. Configure the client
5SabPaisaConfig config = SabPaisaConfig.builder()
6 .apiKey("sp_your_api_key")
7 .merchantId("YOUR_MERCHANT_ID")
8 .secretKey("sec_your_secret_key")
9 .clientCode("YOUR_CLIENT_CODE")
10 .env("production") // or "staging"
11 .build();
12
13SabPaisaClient client = new SabPaisaClient(config);
14
15// 2. Create a payment session
16CreatePaymentResponse payment = client.payments.createSession(
17 CreatePaymentRequest.builder()
18 .merchantTxnId("ORDER_" + System.currentTimeMillis())
19 .amount(50000) // Rs 500.00 in paise
20 .returnUrl("https://yoursite.com/payment/callback")
21 .customerName("John Doe")
22 .customerEmail("[email protected]")
23 .customerMobile("9876543210")
24 .build()
25);
26
27// 3. Redirect customer to checkout
28String checkoutUrl = payment.getCheckoutUrl();
29// Redirect the user's browser to this URL to complete paymentConfiguration
You will receive these credentials from SabPaisa after merchant onboarding.
| Field | Required | Description |
|---|---|---|
| apiKey | Yes | API key provided by SabPaisa |
| merchantId | Yes | Your merchant ID |
| secretKey | Yes | HMAC secret key for checksum generation |
| clientCode | Yes | Your client code (often same as merchantId) |
| env | Yes* | "staging" for testing, "production" for live |
| baseUrl | No | Custom API URL (overrides env if provided) |
*Either env or baseUrl must be provided.
Environments
| Environment | Base URL | Purpose |
|---|---|---|
| Staging | staging-sb-merchant-api.sabpaisa.in | Testing & development |
| Production | merchant-api.sabpaisa.in | Live transactions |
Create Payment Session
Creates a payment session and returns a checkout URL to redirect the customer.
1CreatePaymentRequest request = CreatePaymentRequest.builder()
2 .merchantTxnId("ORDER_123") // your unique order/transaction ID
3 .amount(50000) // amount in paise (50000 = Rs 500.00)
4 .returnUrl("https://yoursite.com/payment/callback")
5 .customerName("John Doe")
6 .customerEmail("[email protected]")
7 .customerMobile("9876543210")
8 .currency("INR") // optional, defaults to "INR"
9 .paymentMode("NB") // optional (NB, UPI, CARD, etc.)
10 .build();
11
12CreatePaymentResponse response = client.payments.createSession(request);
13
14// Redirect the customer to this URL
15String checkoutUrl = response.getCheckoutUrl();
16
17// Other available fields
18response.getPaymentId(); // SabPaisa payment ID
19response.getMerchantTxnId(); // your transaction ID
20response.getAmount(); // amount in paise
21response.getStatus(); // session status
22response.getExpiresAt(); // session expiryWith Idempotency Key
Recommended for production — prevents duplicate payments if the client retries.
1CreatePaymentResponse response = client.payments.createSession(
2 request,
3 RequestOptions.withIdempotencyKey("unique-order-key-123")
4);50000 = Rs 500.00. The SDK does not convert.Verify Return URL
After payment, SabPaisa redirects the customer back to your returnUrl with query parameters. Verify the checksum to ensure the response is authentic.
1// Extract parameters from the callback URL
2ReturnUrlParams params = new ReturnUrlParams(
3 request.getParameter("merchantTxnId"),
4 request.getParameter("sabpaisaTxnId"),
5 request.getParameter("status"),
6 request.getParameter("amount"),
7 request.getParameter("currency"),
8 request.getParameter("timestamp"),
9 request.getParameter("checksum")
10);
11
12boolean isValid = client.payments.verifyReturnUrl(params);
13
14if (isValid) {
15 // Checksum verified — safe to trust the payment status
16 String status = request.getParameter("status");
17 // Update your order status accordingly
18} else {
19 // Checksum mismatch — do not trust this response
20}verifyReturnUrl() returns true.Transaction Enquiry
Look up the status of a transaction using your merchant transaction ID. Optionally pass the SabPaisa transaction ID for a more specific lookup.
1// By merchantTxnId
2TransactionEnquiryResponse response = client.transactions.enquiry("ORDER_123");
3
4// With optional SabPaisa transaction ID for more specific lookup
5TransactionEnquiryResponse response = client.transactions.enquiry("ORDER_123", "sppay_456");
6
7// Access response
8response.getStatus();
9response.getMessage();
10
11TransactionData data = response.getData();
12if (data != null) {
13 data.getTxnId(); // SabPaisa transaction ID
14 data.getMerchantTxnId(); // your transaction ID
15 data.getAmountPaise(); // amount in paise
16 data.getStatus(); // SUCCESS, FAILED, PENDING, etc.
17 data.getPaymentMode(); // UPI, NB, CARD, etc.
18 data.getBankTxnId(); // bank transaction reference
19 data.getBankRrn(); // bank RRN
20 data.getCustomerName();
21 data.getCustomerEmail();
22 data.getCompletedAt(); // completion timestamp
23}Refunds
Initiate refunds, check refund status, and list refunds with optional filters.
1Create Refund
Pass the SabPaisa txnId, refund amount in paise, and an optional reason. Always include an idempotency key.
1CreateRefundRequest refundRequest = CreateRefundRequest.builder()
2 .txnId("SP_TXN_456") // SabPaisa transaction ID
3 .amount(25000) // refund amount in paise (Rs 250.00)
4 .reason("Customer request") // optional
5 .build();
6
7// Always use an idempotency key for refunds to prevent duplicates
8RefundResponse response = client.refunds.create(
9 refundRequest,
10 RequestOptions.withIdempotencyKey("refund-unique-key-789")
11);
12
13RefundData data = response.getData();
14data.getRefundId(); // refund reference ID
15data.getStatus(); // refund status
16data.getAmount(); // refund amount in paise2Get Refund Status
Check the status of a previously created refund.
1RefundResponse response = client.refunds.getStatus("RFD_123");
2
3response.getData().getRefundId();
4response.getData().getStatus();
5response.getData().getAmount();
6response.getData().getCreatedAt();3List Refunds
List refunds with optional filters and pagination.
1// List all refunds
2RefundListResponse response = client.refunds.list();
3
4// With filters
5RefundListResponse response = client.refunds.list(
6 RefundListParams.builder()
7 .txnId("SP_TXN_456") // filter by transaction ID
8 .status("completed") // filter by status
9 .page(0) // page number (0-indexed)
10 .size(20) // results per page (1-100)
11 .build()
12);
13
14// Iterate results
15for (RefundData refund : response.getData()) {
16 System.out.println(refund.getRefundId() + " - " + refund.getStatus());
17}
18
19// Pagination
20RefundListResponse.Pagination page = response.getPagination();
21if (page != null) {
22 System.out.println("Page " + (page.getPage() + 1) + " of " + page.getTotalPages());
23 System.out.println("Total refunds: " + page.getTotal());
24}Error Handling
The SDK throws typed exceptions so you can handle each error case explicitly.
| Exception | When |
|---|---|
| SabPaisaException | Base exception — network errors, timeouts, etc. |
| ApiException | API returned an error (4xx, 5xx) |
| ChecksumException | Checksum verification failed |
| ValidationException | Invalid input — caught before the API call |
1import in.sabpaisa.pg.errors.*;
2
3try {
4 client.payments.createSession(request);
5
6} catch (ValidationException e) {
7 // Bad input — fix the request and retry
8 System.out.println("Invalid field: " + e.getField());
9 System.out.println("Error: " + e.getMessage());
10
11} catch (ApiException e) {
12 // API returned an error
13 System.out.println("HTTP Status: " + e.getStatusCode());
14 System.out.println("Error Code: " + e.getCode());
15 System.out.println("Message: " + e.getMessage());
16 System.out.println("Retryable: " + e.isRetryable());
17 System.out.println("Trace ID: " + e.getTraceId()); // share with SabPaisa support
18
19} catch (SabPaisaException e) {
20 // Network error, timeout, etc.
21 System.out.println("Error: " + e.getMessage());
22 System.out.println("Code: " + e.getCode());
23}Automatic Retries
The SDK automatically retries on transient failures (HTTP 429 and 5xx) with exponential backoff:
- •Up to 2 retries (delays: 500ms, 1s)
- •Only retries safe requests: GET requests, or any request with an idempotency key
- •POST requests without an idempotency key are never auto-retried — prevents duplicate payments
Request Options
Customize timeout or attach an idempotency key per request.
1// Idempotency key (prevents duplicate operations on retry)
2RequestOptions options = RequestOptions.withIdempotencyKey("unique-key");
3
4// Custom timeout
5RequestOptions options = RequestOptions.withTimeout(Duration.ofSeconds(60));
6
7// Both
8RequestOptions options = RequestOptions.of("unique-key", Duration.ofSeconds(60));
9
10// Use with any method
11client.payments.createSession(request, options);
12client.refunds.create(refundRequest, options);
13client.refunds.getStatus("RFD_123", options);
14client.transactions.enquiry("ORDER_123", null, options);Important Notes
| Topic | Detail |
|---|---|
| Amounts | Always in paise. Rs 500.00 = 50000. The SDK does not convert. |
| Customer Mobile | Use customerMobile() in the SDK. It is automatically mapped to the API's customerPhone field. |
| Transaction Enquiry | merchantTxnId is required. spTxnId is optional for more specific lookup. |
| Idempotency Keys | Always use for createSession() and refunds.create() in production to prevent duplicates. |
| Thread Safety | SabPaisaClient is thread-safe. Create once, reuse across your application. |
| Timeout | Default 30 seconds per request. Override with RequestOptions.withTimeout(). |
| Config Immutability | Config cannot be changed after creation. Create a new SabPaisaClient for different credentials. |
Spring Boot Integration
Register the client as a Spring bean and inject it into any controller or service.
1. Configuration Class
1import in.sabpaisa.pg.*;
2import org.springframework.beans.factory.annotation.Value;
3import org.springframework.context.annotation.Bean;
4import org.springframework.context.annotation.Configuration;
5
6@Configuration
7public class SabPaisaConfiguration {
8
9 @Bean
10 public SabPaisaClient sabPaisaClient(
11 @Value("${sabpaisa.api-key}") String apiKey,
12 @Value("${sabpaisa.merchant-id}") String merchantId,
13 @Value("${sabpaisa.secret-key}") String secretKey,
14 @Value("${sabpaisa.client-code}") String clientCode,
15 @Value("${sabpaisa.env}") String env) {
16
17 SabPaisaConfig config = SabPaisaConfig.builder()
18 .apiKey(apiKey)
19 .merchantId(merchantId)
20 .secretKey(secretKey)
21 .clientCode(clientCode)
22 .env(env)
23 .build();
24
25 return new SabPaisaClient(config);
26 }
27}2. application.properties
1# application.properties
2sabpaisa.api-key=sp_your_api_key
3sabpaisa.merchant-id=YOUR_MERCHANT_ID
4sabpaisa.secret-key=sec_your_secret_key
5sabpaisa.client-code=YOUR_CLIENT_CODE
6sabpaisa.env=production3. Inject and Use
1@RestController
2public class PaymentController {
3
4 private final SabPaisaClient sabpaisa;
5
6 public PaymentController(SabPaisaClient sabpaisa) {
7 this.sabpaisa = sabpaisa;
8 }
9
10 @PostMapping("/create-order")
11 public ResponseEntity<?> createOrder(@RequestBody OrderRequest order) {
12 CreatePaymentResponse payment = sabpaisa.payments.createSession(
13 CreatePaymentRequest.builder()
14 .merchantTxnId(order.getOrderId())
15 .amount(order.getAmountInPaise())
16 .returnUrl("https://yoursite.com/payment/callback")
17 .customerName(order.getCustomerName())
18 .customerEmail(order.getCustomerEmail())
19 .customerMobile(order.getCustomerMobile())
20 .build()
21 );
22 return ResponseEntity.ok(Map.of("checkoutUrl", payment.getCheckoutUrl()));
23 }
24}Need Help?
For integration support, contact the SabPaisa technical team with:
- •Your merchant ID
- •The trace ID from the error response (
ApiException.getTraceId()) - •The SDK version (
1.0.1)
Was this page helpful?
Related Pages
SDKs & Libraries
Choose your platform — Flutter, Java, Python, Node.js
Flutter SDK
Official Flutter SDK — Android, iOS, Web
Quick Start
Get up and running in 30 minutes
API Reference
Complete endpoint documentation
Webhooks
Real-time payment notifications
iFrame Integration
Embed checkout on your site — no redirect