Skip to content

SDK-SPEC-JAVA — Java SDK Specification

Status: Draft Owner: Platform Engineering Artifact: com.simpaisa:simpaisa-sdk Runtime: Java 11+ Last Updated: 2026-04-03


1. Overview

Official Java SDK for the Simpaisa Payment Gateway. Provides typed access to Pay-Ins, Pay-Outs, Remittances, and Cards across PK, BD, NP, and IQ corridors. Handles 270M+ annual transactions at $1B+ volume. Published to Maven Central. Backward compatible with existing Pay-Out and Remittance merchants.

2. Maven Coordinates

<dependency>
    <groupId>com.simpaisa</groupId>
    <artifactId>simpaisa-sdk</artifactId>
    <version>${simpaisa.version}</version>
</dependency>

Gradle: implementation 'com.simpaisa:simpaisa-sdk:${version}'

3. Package Structure

com.simpaisa/
├── SimPaisaClient.java          # Main client entry point (builder pattern)
├── SimPaisaConfig.java          # Configuration (environment, timeout, retries)
├── payin/
│   ├── PayInClient.java         # Pay-in operations (initiate, verify, status, list)
│   ├── PayInRequest.java        # Request model
│   └── PayInResponse.java       # Response model
├── payout/
│   ├── PayOutClient.java        # Pay-out operations (initiate, status, batch, cancel)
│   ├── PayOutRequest.java
│   └── PayOutResponse.java
├── remittance/
│   ├── RemittanceClient.java    # Remittance operations (quote, initiate, status, beneficiaries)
│   ├── RemittanceRequest.java
│   └── RemittanceResponse.java
├── cards/
│   ├── CardsClient.java         # Cards operations (pay, capture, void, refund, tokenise)
│   ├── CardPaymentRequest.java
│   └── CardPaymentResponse.java
├── webhook/
│   ├── WebhookVerifier.java     # HMAC-SHA256 signature verification
│   └── WebhookEvent.java
├── auth/
│   ├── RSAAuthProvider.java     # RSA-SHA256 request signing
│   └── AuthProvider.java        # Interface for custom auth implementations
├── error/
│   ├── SimPaisaException.java   # Base exception
│   ├── AuthenticationException.java
│   ├── ValidationException.java
│   ├── RateLimitException.java
│   └── WebhookVerificationException.java
├── retry/
│   └── RetryPolicy.java         # Exponential backoff via resilience4j
├── idempotency/
│   └── IdempotencyKeyGenerator.java  # UUID v7 generation
└── model/
    └── generated/               # OpenAPI-generated models

4. Authentication — RSAAuthProvider

  • Load merchant private key from PEM file or PrivateKey object
  • Sign request body with RSA-SHA256 using java.security.Signature
  • Bouncy Castle provider for extended algorithm support
  • Attach X-Simpaisa-Signature and X-Simpaisa-Merchant-Id headers
  • Support key rotation via multiple keys
RSAAuthProvider auth = RSAAuthProvider.builder()
    .merchantId("MCH-001")
    .privateKeyPath(Path.of("./keys/merchant.pem"))
    .build();

5. Builder Pattern

All request objects and the client itself SHALL use the builder pattern:

SimPaisaClient client = SimPaisaClient.builder()
    .environment(Environment.SANDBOX)
    .merchantId("MCH-001")
    .privateKeyPath(Path.of("./keys/merchant.pem"))
    .timeout(Duration.ofSeconds(30))
    .maxRetries(3)
    .build();

6. WebhookVerifier

  • Verify X-Simpaisa-Webhook-Signature using HMAC-SHA256 (javax.crypto.Mac)
  • Constructor accepts webhook secret as String or byte[]
  • boolean verify(byte[] payload, String signature)
  • Replay protection: validate timestamp header within tolerance (default 300s)
  • Throw WebhookVerificationException on failure

7. Retry (resilience4j)

  • Exponential backoff with jitter (base 200ms, max 30s)
  • Configurable max retries (default 3)
  • Retry on: 429, 502, 503, 504, IOException
  • Never retry: 400, 401, 403, 404, 409, 422
  • Respect Retry-After header
  • Circuit breaker integration optional via resilience4j

8. Error Handling

SimPaisaException (base, unchecked)
├── AuthenticationException     — 401/403 responses
├── ValidationException         — 400/422 with field-level details
├── RateLimitException          — 429 with retryAfter duration
├── TimeoutException            — request/connection timeout
├── IdempotencyException        — conflicting idempotency key
├── NetworkException            — connection/DNS failures
└── WebhookVerificationException — signature mismatch

All exceptions include: errorCode, message, statusCode, requestId, isRetryable().

9. Model Generation

  • Models auto-generated from canonical OpenAPI 3.1 spec via openapi-generator-maven-plugin
  • Generated into com.simpaisa.model.generated package
  • Jackson annotations for serialisation/deserialisation
  • Immutable models with builder pattern
  • Regenerated in CI on OpenAPI spec changes

10. Configuration

SimPaisaConfig config = SimPaisaConfig.builder()
    .environment(Environment.SANDBOX)        // SANDBOX or PRODUCTION
    .merchantId("MCH-001")
    .privateKeyPath(Path.of("./keys/merchant.pem"))
    .timeout(Duration.ofSeconds(30))         // default 30s
    .maxRetries(3)                           // default 3
    .httpClient(customHttpClient)            // optional, java.net.http.HttpClient
    .build();

11. Backward Compatibility

  • Existing Pay-Out and Remittance merchants MUST be able to migrate without breaking changes
  • Deprecated methods from legacy SDK SHALL be preserved with @Deprecated annotation for 2 major versions
  • Migration guide documenting old → new method mappings

12. Example Usage

SimPaisaClient client = SimPaisaClient.builder()
    .environment(Environment.SANDBOX)
    .merchantId("MCH-001")
    .privateKeyPath(Path.of("./keys/merchant.pem"))
    .build();

// Pay-In
PayInResponse payIn = client.payIn().initiate(PayInRequest.builder()
    .amount(new BigDecimal("5000"))
    .currency("PKR")
    .channel("EASYPAISA")
    .customerMsisdn("03001234567")
    .callbackUrl("https://merchant.com/webhook")
    .build());

// Webhook verification
WebhookVerifier verifier = new WebhookVerifier("whsec_...");
boolean valid = verifier.verify(rawBody, signatureHeader);

13. Build and Publish

  • Build: Maven 3.9+ with maven-wrapper
  • Test: JUnit 5 + Mockito
  • Linting: Checkstyle + SpotBugs
  • CI: Bitbucket Pipelines — lint → test → build → publish
  • Publish: Maven Central via Sonatype OSSRH
  • Versioning: Semantic versioning
  • Java compatibility: Compiled with --release 11, tested on 11, 17, 21

14. Dependencies

  • java.net.http.HttpClient (stdlib, no third-party HTTP)
  • Jackson 2.x for JSON
  • resilience4j-retry for retry logic
  • Bouncy Castle (optional, for extended crypto)
  • SLF4J for logging abstraction

15. Testing Requirements

  • Unit tests for every public method (>90% coverage via JaCoCo)
  • Integration tests against sandbox environment
  • Contract tests validating against OpenAPI spec
  • Webhook verification round-trip tests
  • Retry behaviour tests with WireMock
  • Backward compatibility tests for legacy merchant migration paths