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

# Java

> Tích hợp Dodo Payments vào các ứng dụng Java của bạn với một SDK mạnh mẽ, an toàn kiểu.

SDK Java cung cấp quyền truy cập thuận tiện và dễ sử dụng vào Dodo Payments REST API cho các ứng dụng viết bằng Java. Nó sử dụng các tính năng đặc thù của Java như Optional, Stream và CompletableFuture cho phát triển Java hiện đại.

## Cài đặt

### Maven

Thêm phần phụ thuộc vào `pom.xml`:

```xml pom.xml theme={null}
<dependency>
  <groupId>com.dodopayments.api</groupId>
  <artifactId>dodo-payments-java</artifactId>
  <version>1.97.1</version>
</dependency>
```

### Gradle

Thêm phần phụ thuộc vào `build.gradle`:

```kotlin build.gradle.kts theme={null}
implementation("com.dodopayments.api:dodo-payments-java:1.97.1")
```

<Tip>
  Luôn sử dụng phiên bản SDK mới nhất để truy cập các tính năng mới nhất của Dodo Payments. Kiểm tra [Maven Central](https://central.sonatype.com/artifact/com.dodopayments.api/dodo-payments-java) để biết phiên bản mới nhất.
</Tip>

<Info>
  SDK hỗ trợ Java 8 và tất cả các phiên bản sau đó, bao gồm Java 11, 17 và 21.
</Info>

## Bắt đầu nhanh

Khởi tạo client và tạo một phiên giao dịch thanh toán:

```java theme={null}
import com.dodopayments.api.client.DodoPaymentsClient;
import com.dodopayments.api.client.okhttp.DodoPaymentsOkHttpClient;
import com.dodopayments.api.models.checkoutsessions.CheckoutSessionCreateParams;
import com.dodopayments.api.models.checkoutsessions.CheckoutSessionRequest;
import com.dodopayments.api.models.checkoutsessions.ProductItemReq;

// Configure using environment variables (DODO_PAYMENTS_API_KEY, DODO_PAYMENTS_BASE_URL)
// Or system properties (dodopayments.apiKey, dodopayments.baseUrl)
DodoPaymentsClient client = DodoPaymentsOkHttpClient.fromEnv();

CheckoutSessionRequest params = CheckoutSessionRequest.builder()
    .addProductCart(ProductItemReq.builder()
        .productId("product_id")
        .quantity(1)
        .build())
    .build();
    
CheckoutSessionResponse checkoutSessionResponse = client.checkoutSessions().create(params);
System.out.println(checkoutSessionResponse.sessionId());
```

<Warning>
  Luôn lưu trữ khóa API một cách an toàn bằng biến môi trường, thuộc tính hệ thống hoặc hệ thống quản lý cấu hình an toàn. Không bao giờ mã hóa cứng chúng vào mã nguồn của bạn.
</Warning>

## Tính năng chính

<CardGroup cols={2}>
  <Card title="Type Safety" icon="shield-check">
    API kiểu tường minh với đảm bảo an toàn thời gian biên dịch
  </Card>

  <Card title="Thread-Safe" icon="bolt">
    An toàn khi sử dụng đồng thời trong các ứng dụng đa luồng
  </Card>

  <Card title="Builder Pattern" icon="layer-group">
    Mẫu builder trực quan để xây dựng các yêu cầu
  </Card>

  <Card title="Async Support" icon="arrows-rotate">
    Hỗ trợ CompletableFuture cho các thao tác bất đồng bộ
  </Card>
</CardGroup>

## Cấu hình

### Biến môi trường

Cấu hình bằng cách sử dụng biến môi trường hoặc thuộc tính hệ thống:

```bash .env theme={null}
DODO_PAYMENTS_API_KEY=your_api_key_here
DODO_PAYMENTS_BASE_URL=https://live.dodopayments.com
```

```java theme={null}
// Automatically reads from environment variables
DodoPaymentsClient client = DodoPaymentsOkHttpClient.fromEnv();
```

### Cấu hình thủ công

Cấu hình thủ công với tất cả các tùy chọn:

```java theme={null}
import java.time.Duration;

DodoPaymentsClient client = DodoPaymentsOkHttpClient.builder()
    .bearerToken("your_api_key_here")
    .baseUrl("https://live.dodopayments.com")
    .maxRetries(4)
    .timeout(Duration.ofSeconds(30))
    .responseValidation(true)
    .build();
```

### Chế độ thử nghiệm

Cấu hình cho môi trường thử nghiệm/sandbox:

```java theme={null}
DodoPaymentsClient testClient = DodoPaymentsOkHttpClient.builder()
    .fromEnv()
    .testMode()
    .build();
```

## Các thao tác thông thường

### Tạo một phiên giao dịch thanh toán

Tạo một phiên giao dịch thanh toán:

```java theme={null}
CheckoutSessionRequest params = CheckoutSessionRequest.builder()
    .addProductCart(ProductItemReq.builder()
        .productId("prod_123")
        .quantity(1)
        .build())
    .returnUrl("https://yourdomain.com/return")
    .build();

CheckoutSessionResponse session = client.checkoutSessions().create(params);
System.out.println("Checkout URL: " + session.checkoutUrl());
```

### Quản lý khách hàng

Tạo và truy xuất thông tin khách hàng:

```java theme={null}
import com.dodopayments.api.models.customers.Customer;
import com.dodopayments.api.models.customers.CustomerCreateParams;

// Create a customer
CustomerCreateParams createParams = CustomerCreateParams.builder()
    .email("customer@example.com")
    .name("John Doe")
    .putMetadata("user_id", "12345")
    .build();

Customer customer = client.customers().create(createParams);

// Retrieve customer
Customer retrieved = client.customers().retrieve("cus_123");
System.out.println("Customer: " + retrieved.name() + " (" + retrieved.email() + ")");
```

### Xử lý đăng ký

Tạo và quản lý các đăng ký định kỳ:

```java theme={null}
import com.dodopayments.api.models.payments.AttachExistingCustomer;
import com.dodopayments.api.models.payments.BillingAddress;
import com.dodopayments.api.models.payments.CountryCode;
import com.dodopayments.api.models.subscriptions.SubscriptionChargeParams;
import com.dodopayments.api.models.subscriptions.SubscriptionChargeResponse;
import com.dodopayments.api.models.subscriptions.SubscriptionCreateParams;
import com.dodopayments.api.models.subscriptions.SubscriptionCreateResponse;

// Create a subscription
SubscriptionCreateParams subscriptionParams = SubscriptionCreateParams.builder()
    .billing(BillingAddress.builder()
        .city("San Francisco")
        .country(CountryCode.US)
        .state("CA")
        .street("1 Market St")
        .zipcode("94105")
        .build())
    .customer(AttachExistingCustomer.builder()
        .customerId("cus_123")
        .build())
    .productId("pdt_456")
    .quantity(1)
    .paymentLink(true)
    .returnUrl("https://yourdomain.com/return")
    .build();

SubscriptionCreateResponse subscription = client.subscriptions().create(subscriptionParams);
System.out.println("Subscription ID: " + subscription.subscriptionId());

// Charge an on-demand subscription
// product_price is in the lowest currency denomination (e.g., 2500 = $25.00 USD)
SubscriptionChargeParams chargeParams = SubscriptionChargeParams.builder()
    .subscriptionId(subscription.subscriptionId())
    .productPrice(2500)
    .build();

SubscriptionChargeResponse chargeResponse = client.subscriptions().charge(chargeParams);
System.out.println("Payment ID: " + chargeResponse.paymentId());
```

<Info>
  `productPrice` được biểu thị bằng mệnh giá tiền tệ thấp nhất (ví dụ: xu cho USD, paise cho INR). Để thanh toán \$25.00, hãy chuyển `2500`.
</Info>

<Tip>
  Thanh toán qua `subscriptions().charge(...)` dành cho [đăng ký theo yêu cầu](/developer-resources/ondemand-subscriptions). Đăng ký định kỳ tiêu chuẩn được tính phí tự động dựa trên lịch trình giá của sản phẩm.
</Tip>

## Thanh toán dựa trên mức sử dụng

### Cấu hình đồng hồ đo

Tạo và quản lý đồng hồ đo để theo dõi mức sử dụng:

```java theme={null}
import com.dodopayments.api.models.meters.*;

// Create API calls meter
MeterCreateParams apiMeterParams = MeterCreateParams.builder()
    .name("API Requests")
    .eventName("api_request")
    .aggregation("count")
    .putMetadata("category", "api_usage")
    .build();

Meter apiMeter = client.meters().create(apiMeterParams);
System.out.println("Meter created: " + apiMeter.meterId());

// List all meters
client.meters().list()
    .autoPager()
    .forEach(m -> System.out.println("Meter: " + m.name() + " - " + m.aggregation()));
```

### Ghi nhận sự kiện sử dụng

Theo dõi sự kiện tùy chỉnh:

```java theme={null}
import com.dodopayments.api.models.usageevents.*;
import java.time.OffsetDateTime;

// Ingest single event
UsageEventIngestParams singleEventParams = UsageEventIngestParams.builder()
    .addEvent(UsageEventIngestParams.Event.builder()
        .eventId("api_call_" + System.currentTimeMillis())
        .customerId("cus_abc123")
        .eventName("api_request")
        .timestamp(OffsetDateTime.now())
        .putMetadata("endpoint", "/api/v1/users")
        .putMetadata("method", "GET")
        .putMetadata("tokens_used", "150")
        .build())
    .build();

UsageEventIngestResponse response = client.usageEvents().ingest(singleEventParams);
System.out.println("Processed: " + response.ingestedCount());
```

### Ghi nhận sự kiện hàng loạt

Ghi nhận nhiều sự kiện một cách hiệu quả (tối đa 1000 mỗi yêu cầu):

```java theme={null}
UsageEventIngestParams.Builder batchBuilder = UsageEventIngestParams.builder();

for (int i = 0; i < 100; i++) {
    batchBuilder.addEvent(UsageEventIngestParams.Event.builder()
        .eventId("batch_event_" + i + "_" + System.currentTimeMillis())
        .customerId("cus_abc123")
        .eventName("video_transcode")
        .timestamp(OffsetDateTime.now().minusMinutes(i))
        .putMetadata("video_id", "video_" + i)
        .putMetadata("duration_seconds", String.valueOf(120 + i))
        .build());
}

UsageEventIngestResponse batchResponse = client.usageEvents().ingest(batchBuilder.build());
System.out.println("Batch processed: " + batchResponse.ingestedCount() + " events");
```

## Xử lý lỗi

Xử lý lỗi toàn diện cho các tình huống khác nhau:

```java theme={null}
import com.dodopayments.api.errors.*;

try {
    Payment payment = client.payments().retrieve("pay_invalid");
} catch (NotFoundException e) {
    System.err.println("Payment not found: " + e.getMessage());
} catch (UnauthorizedException e) {
    System.err.println("Authentication failed: " + e.getMessage());
} catch (PermissionDeniedException e) {
    System.err.println("Permission denied: " + e.getMessage());
} catch (BadRequestException e) {
    System.err.println("Invalid request: " + e.getMessage());
} catch (UnprocessableEntityException e) {
    System.err.println("Validation error: " + e.getMessage());
} catch (RateLimitException e) {
    System.err.println("Rate limit exceeded: " + e.getMessage());
    // SDK automatically retries with backoff
} catch (InternalServerException e) {
    System.err.println("Server error: " + e.getMessage());
} catch (DodoPaymentsServiceException e) {
    System.err.println("API error: " + e.statusCode() + " - " + e.getMessage());
}
```

<Tip>
  SDK tự động thực hiện lại các yêu cầu khi gặp lỗi kết nối, 408, 409, 429 và lỗi 5xx với backoff theo cấp số nhân.
</Tip>

## Hoạt động không đồng bộ

Sử dụng CompletableFuture cho các hoạt động không đồng bộ:

```java theme={null}
import java.util.concurrent.CompletableFuture;

CompletableFuture<CheckoutSessionResponse> future = client.async()
    .checkoutSessions()
    .create(params);

// Handle response asynchronously
future.thenAccept(response -> {
    System.out.println("Session created: " + response.sessionId());
}).exceptionally(ex -> {
    System.err.println("Error: " + ex.getMessage());
    return null;
});
```

## Tích hợp Spring Boot

### Lớp cấu hình

```java theme={null}
import com.dodopayments.api.client.DodoPaymentsClient;
import com.dodopayments.api.client.okhttp.DodoPaymentsOkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DodoPaymentsConfig {
    
    @Value("${dodo.api.key}")
    private String apiKey;
    
    @Value("${dodo.environment:test}")
    private String environment;
    
    @Bean
    public DodoPaymentsClient dodoPayments() {
        return DodoPaymentsOkHttpClient.builder()
            .bearerToken(apiKey)
            .baseUrl(environment.equals("live") 
                ? "https://live.dodopayments.com" 
                : "https://test.dodopayments.com")
            .build();
    }
}
```

### Tầng dịch vụ

```java theme={null}
import com.dodopayments.api.client.DodoPaymentsClient;
import com.dodopayments.api.models.checkoutsessions.*;
import org.springframework.stereotype.Service;

@Service
public class PaymentService {
    
    private final DodoPaymentsClient client;
    
    public PaymentService(DodoPaymentsClient client) {
        this.client = client;
    }
    
    public CheckoutSessionResponse createCheckout(List<ProductItemReq> items) {
        CheckoutSessionRequest params = CheckoutSessionRequest.builder()
            .productCart(items)
            .returnUrl("https://yourdomain.com/return")
            .build();
            
        return client.checkoutSessions().create(params);
    }
}
```

## Tài nguyên

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodopayments-java">
    Xem mã nguồn và đóng góp
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Tài liệu API hoàn chỉnh
  </Card>

  <Card title="Discord Community" icon="discord" href="https://discord.gg/bYqAp4ayYh">
    Nhận trợ giúp và kết nối với các nhà phát triển
  </Card>

  <Card title="Report Issues" icon="bug" href="https://github.com/dodopayments/dodopayments-java/issues">
    Báo cáo lỗi hoặc yêu cầu tính năng
  </Card>
</CardGroup>

## Hỗ trợ

Cần trợ giúp với Java SDK?

* **Discord**: Tham gia [máy chủ cộng đồng](https://discord.gg/bYqAp4ayYh) của chúng tôi để được hỗ trợ theo thời gian thực
* **Email**: Liên hệ với chúng tôi qua [support@dodopayments.com](mailto:support@dodopayments.com)
* **GitHub**: Mở một vấn đề trên [kho lưu trữ](https://github.com/dodopayments/dodopayments-java)

## Đóng góp

Chúng tôi hoan nghênh các đóng góp! Kiểm tra [hướng dẫn đóng góp](https://github.com/dodopayments/dodopayments-java/blob/main/CONTRIBUTING.md) để bắt đầu.
