> ## Documentation Index
> Fetch the complete documentation index at: https://docs.snappay.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Java SDK

> Complete guide for integrating SnapPay with Java applications using modern asynchronous patterns and reactive programming

## Overview

The SnapPay Java SDK provides a comprehensive, enterprise-grade interface for integrating payment processing, subscription management, and real-time event streaming into your Java applications. Built with modern Java patterns including CompletableFuture for asynchronous operations, reactive streams for event handling, and comprehensive type safety, it offers seamless integration with SnapPay's complete platform.

**Requirements:** Java 11+ / Maven or Gradle

### Key Features

* **Modern async design** with CompletableFuture and reactive patterns for optimal performance
* **Enterprise-grade reliability** with connection pooling and automatic retry mechanisms
* **Real-time event streaming** via Server-Sent Events (SSE) with reactive programming support
* **Full type safety** with immutable POJOs and builder patterns
* **Thread-safe client** for concurrent usage across your application
* **Comprehensive error handling** with typed exceptions and detailed error contexts
* **Framework integrations** for Spring Boot, Quarkus, and Micronaut
* **Environment-based configuration** with flexible setup options

## Installation

### Maven

```xml theme={null}
<dependency>
    <groupId>dev.snappay</groupId>
    <artifactId>snappay-sdk</artifactId>
    <version>0.0.1-beta</version>
</dependency>
```

### Gradle

```groovy theme={null}
dependencies {
    implementation 'dev.snappay:snappay-sdk:0.0.1-beta'
}
```

### Gradle (Kotlin DSL)

```kotlin theme={null}
dependencies {
    implementation("dev.snappay:snappay-sdk:0.0.1-beta")
}
```

## Configuration & Initialization

The SDK client is configured via a primary constructor that accepts a configuration object. All operations return CompletableFuture for asynchronous execution and proper resource management.

### API Key Authentication

Authentication is handled via an API key that must start with `pk_test_` (for testing) or `pk_live_` (for production). Configure your API key in one of these ways:

### SnapPay Client

```java theme={null}
Config config = new Config.Builder()
    .apiKey("pk_test_xxxxxxxxxx") // Required
    .build();

SnapPayClient client = new SnapPayClient(config);
```

### Customer Management

#### getCustomer

Retrieves or creates a customer record.

```java theme={null}
var customer = client.getCustomers().get(
    "user_124",
    "john4@example.com",
    "John Dane 4"
);
```

```Java theme={null}
public abstract fun get(
    id: String,
    email: String? = COMPILED_CODE,
    name: String? = COMPILED_CODE
): Customer
```

**Parameters:**

* `id` (String): Customer identifier
* `email` (String, optional): Customer email address
* `name` (String, optional): Customer full name

**Returns:**

```java theme={null}
public interface Customer {
    String getId();
    String getEmail();
    String getName();
    String getStatus();
}
```

### Checkout Sessions

#### createCheckoutSession

Creates a payment checkout session URL for customer purchases.

```java theme={null}
 var checkout = client.getCheckout().createSession(
                customer.getId(),
                "sand-pd-local-connect-3",
                null,
                "https://example.com/success",
                "https://example.com/cancel",
                "stripe"
        );
```

```java theme={null}
public abstract fun createSession(
    customerId: String,
    productId: String,
    priceId: String? = COMPILED_CODE,
    successUrl: String,
    cancelUrl: String? = COMPILED_CODE,
    provider: String = COMPILED_CODE
): CheckoutSession
```

**Parameters:**

* `customerId` (String): SnapPay customer ID
* `productId` (String): Product ID from your SnapPay dashboard
* `priceId` (String): Price ID from your SnapPay dashboard
* `successUrl` (String): URL to redirect after successful payment
* `cancelUrl` (String, optional): URL to redirect on cancellation
* `provider` (Provider): Payment provider (defaults to STRIPE)

**Returns:**

```java theme={null}
public interface CheckoutSession {
    String getUrl();
    String getSessionId();
    String getExpiresAt();
}
```

### Access Control

#### checkAccess

Checks if a customer has access to a specific feature based on their subscription and usage limits.

```java theme={null}
var access = client.getAccess().check(
    "user_124",
    "sand-ft-messages"
);
```

```java theme={null}
public abstract fun check(
    customerId: String,
    featureId: String
): AccessResult
```

**Parameters:**

* `customerId` (String): SnapPay customer ID
* `featureId` (String): Feature identifier

**Returns:**

```java theme={null}
public interface AccessResult {
    boolean getHasAccess();
    String getFeatureId();
    Integer getUsage();
    Integer getAllowance();
    Long getNextResetAt();
}
```

### Usage Tracking

#### trackUsage

Reports usage for a metered feature. This action is idempotent to prevent duplicate tracking.

```java theme={null}
var tracked = client.getUsage().track(
    customer.getId(),
    "sand-ft-messages",
    1
);
```

```java theme={null}
public abstract fun track(
    customerId: String,
    featureId: String,
    usage: Int,
    idempotencyKey: String?
): TrackUsage
```

**Parameters:**

* `customerId` (String): SnapPay customer ID
* `featureId` (String): Feature identifier for usage tracking
* `usage` (Double): Usage amount to track
* `idempotencyKey` (String, optional): Prevents duplicate tracking

**Returns:**

```java theme={null}
public interface TrackUsage {
    String getCustomerId();
    String getFeatureId();
    int getAdded();
    int getUsed();
    String getTimestamp();
    String getIdempotencyKey();
}
```

#### getUsage

Retrieves current usage details for a customer's feature.

```java theme={null}
var usages = client.getUsage().get(customer.getId(), "sand-ft-messages");
```

```java theme={null}
public abstract fun get(
    customerId: String,
    featureId: String
): List<GetUsage>
```

**Parameters:**

* `customerId` (String): SnapPay customer ID
* `featureId` (String): Feature identifier

**Returns:**

```java theme={null}
public interface GetUsage {
    int getTotalUsage();
    String getProductId();
    String getFeatureId();
    Integer getRemaining();
    Integer getLimit();
    Long getNextResetAt();
}
```

## Real-time Event Handling

**Say goodbye to webhook hell!** SnapPay eliminates the complexity of managing payment webhooks by processing all provider webhooks (Stripe, PayPal, etc.) internally and delivering clean, structured events directly to your application via Server-Sent Events (SSE) using reactive patterns.

### 🚫 What You DON'T Need:

* **No webhook endpoints** to create and maintain
* **No webhook signature verification**
* **No webhook retry logic** or failure handling
* **No webhook security concerns**
* **No debugging webhook delivery issues**

### ✅ What You GET:

* **Real-time events** delivered instantly via reactive streams
* **Guaranteed delivery** with automatic reconnection
* **Clean, structured data** - no raw webhook payloads
* **Reactive programming** perfect for Java's async ecosystem
* **Type-safe event objects** with comprehensive error handling

### Event Structure

```java theme={null}
public interface SseEvent {
    String getId();
    SseEventType getType();
    Map<?, ?> getData();
    String getCreatedAt();
}
```

### Supported Events

See the list of supported events: [Server-sent Event Types](/events/index)

### Reactive Event Streaming

Simply subscribe to events as they arrive - SnapPay handles all the webhook complexity behind the scenes:

```java theme={null}
Flow.Publisher<SseEvent> publisher = client.getSse().subscribe();

publisher.subscribe(new Flow.Subscriber<>() {
    private Flow.Subscription subscription;

    @Override
    public void onSubscribe(Flow.Subscription subscription) {
        this.subscription = subscription;
        subscription.request(1);
    }

    @Override
    public void onNext(SseEvent event) {
        System.out.println("Java => Event: " + event.getType() + " | " + event);

        subscription.request(1);
    }

    @Override
    public void onError(Throwable throwable) {
        System.err.println("Java => Error: " + throwable.getMessage());
    }

    @Override
    public void onComplete() {
        System.out.println("Java => Stream completed");
    }
});

```

**Key Benefits Demonstrated:**

* ✅ **Zero webhook infrastructure** - no endpoints, no servers, no security concerns
* ✅ **Instant event processing** - no webhook delivery delays or failures
* ✅ **Reactive programming** - perfect for Java's async ecosystem
* ✅ **Type-safe event handling** - compile-time safety with comprehensive error handling
