설치
Gradle (Kotlin DSL)
종속성을build.gradle.kts에 추가하세요:
build.gradle.kts
implementation("com.dodopayments.api:dodo-payments-kotlin:1.86.3")
Maven
종속성을pom.xml에 추가하세요:
pom.xml
<dependency>
<groupId>com.dodopayments.api</groupId>
<artifactId>dodo-payments-kotlin</artifactId>
<version>1.86.3</version>
</dependency>
항상 최신 SDK 버전을 사용하여 최신 Dodo Payments 기능에 액세스하세요. 최신 버전은 Maven Central에서 확인하세요.
SDK는 Java 8 이상이 필요하며 JVM과 Android 플랫폼 모두와 호환됩니다.
빠른 시작
클라이언트를 초기화하고 체크아웃 세션을 생성하세요: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)
val client: DodoPaymentsClient = DodoPaymentsOkHttpClient.fromEnv()
val params: CheckoutSessionRequest = CheckoutSessionRequest.builder()
.addProductCart(ProductItemReq.builder()
.productId("product_id")
.quantity(1)
.build())
.build()
val checkoutSessionResponse: CheckoutSessionResponse = client.checkoutSessions().create(params)
println(checkoutSessionResponse.sessionId())
API 키는 환경 변수나 암호화된 구성으로 안전하게 보관하세요. 절대로 버전 관리 시스템에 커밋하지 마세요.
핵심 기능
Coroutines
비동기 작업을 위한 Kotlin 코루틴 완전 지원
Null Safety
견고한 오류 처리를 위해 Kotlin의 null 안전성을 활용하세요
Extension Functions
향상된 기능을 위한 관용적인 Kotlin 확장
Data Classes
복사 및 구조 분해 지원을 갖춘 타입 안전 데이터 클래스
구성
환경 변수에서
환경 변수 또는 시스템 속성에서 초기화하세요:val client: DodoPaymentsClient = DodoPaymentsOkHttpClient.fromEnv()
수동 구성
모든 옵션으로 수동으로 구성하세요:import java.time.Duration
val client = DodoPaymentsOkHttpClient.builder()
.bearerToken("your_api_key_here")
.baseUrl("https://live.dodopayments.com")
.maxRetries(3)
.timeout(Duration.ofSeconds(30))
.build()
테스트 모드
Test Mode 환경 구성:val testClient = DodoPaymentsOkHttpClient.builder()
.fromEnv()
.testMode()
.build()
타임아웃 및 재시도
전역 또는 요청별로 구성하세요:import com.dodopayments.api.core.RequestOptions
// Global configuration
val client = DodoPaymentsOkHttpClient.builder()
.fromEnv()
.timeout(Duration.ofSeconds(45))
.maxRetries(3)
.build()
// Per-request timeout override
val product = client.products().retrieve(
"pdt_123",
RequestOptions.builder()
.timeout(Duration.ofSeconds(10))
.build()
)
일반 작업
체크아웃 세션 생성
체크아웃 세션을 생성하세요:val params = CheckoutSessionRequest.builder()
.addProductCart(ProductItemReq.builder()
.productId("pdt_123")
.quantity(1)
.build())
.returnUrl("https://yourdomain.com/return")
.build()
val session = client.checkoutSessions().create(params)
println("Checkout URL: ${session.checkoutUrl()}")
제품 생성
상세 구성을 가진 제품을 생성하세요:import com.dodopayments.api.models.products.Price
import com.dodopayments.api.models.products.Product
import com.dodopayments.api.models.products.ProductCreateParams
import com.dodopayments.api.models.misc.Currency
import com.dodopayments.api.models.misc.TaxCategory
import com.dodopayments.api.models.misc.TimeInterval
val createParams = ProductCreateParams.builder()
.name("Premium Subscription")
.description("Monthly subscription with all features")
.price(
Price.RecurringPrice.builder()
.currency(Currency.USD)
.price(2999) // $29.99 in cents
.discount(0L)
.purchasingPowerParity(false)
.paymentFrequencyCount(1)
.paymentFrequencyInterval(TimeInterval.MONTH)
.subscriptionPeriodCount(1)
.subscriptionPeriodInterval(TimeInterval.MONTH)
.build()
)
.taxCategory(TaxCategory.DIGITAL_PRODUCTS)
.build()
val product: Product = client.products().create(createParams)
println("Created product ID: ${product.productId()}")
라이센스 키 활성화
고객을 위한 라이센스 키를 활성화하세요:import com.dodopayments.api.models.licenses.LicenseActivateParams
import com.dodopayments.api.models.licenses.LicenseActivateResponse
val activateParams = LicenseActivateParams.builder()
.licenseKey("XXXX-XXXX-XXXX-XXXX")
.name("user-laptop-01")
.build()
try {
val activationResult: LicenseActivateResponse = client.licenses()
.activate(activateParams)
println("License activated successfully")
println("Instance ID: ${activationResult.id()}")
println("License key ID: ${activationResult.licenseKeyId()}")
} catch (e: UnprocessableEntityException) {
println("License activation failed: ${e.message}")
}
사용 기반 청구
사용 이벤트 기록
POST /subscriptions (SDK의 subscriptions.create 메서드)는 deprecated입니다. 기존 통합에서는 계속 작동하지만, 새로운 통합에서는 Checkout Session을 통해 subscriptions를 생성해야 합니다.import com.dodopayments.api.models.payments.AttachExistingCustomer
import com.dodopayments.api.models.payments.BillingAddress
import com.dodopayments.api.models.misc.CountryCode
import com.dodopayments.api.models.subscriptions.SubscriptionChargeParams
import com.dodopayments.api.models.subscriptions.SubscriptionCreateParams
// Create a subscription
val 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)
.build()
val subscription = client.subscriptions().create(subscriptionParams)
println("Subscription ID: ${subscription.subscriptionId()}")
// Charge an on-demand subscription
// productPrice is in the lowest currency denomination (e.g., 2500 = $25.00 USD)
val chargeParams = SubscriptionChargeParams.builder()
.subscriptionId(subscription.subscriptionId())
.productPrice(2500)
.build()
val chargeResponse = client.subscriptions().charge(chargeParams)
println("Payment ID: ${chargeResponse.paymentId()}")
billing에는 최소 2자리의 ISO country 코드가 필요합니다. 기존 customer를 연결하려면 AttachExistingCustomer를 사용하고, 새 customer를 생성하려면 NewCustomer를 사용하세요. productPrice는 가장 낮은 통화 단위로 표시됩니다.사용량 기반 결제
사용량 이벤트 기록
meters의 사용량을 추적합니다:import com.dodopayments.api.models.usageevents.EventInput
import com.dodopayments.api.models.usageevents.UsageEventIngestParams
val usageParams = UsageEventIngestParams.builder()
.addEvent(EventInput.builder()
.customerId("cust_456")
.eventId("event_123")
.eventName("api_call")
.build())
.build()
client.usageEvents().ingest(usageParams)
println("Usage event recorded")
비동기 작업
비동기 클라이언트
코루틴 기반 작업에는 비동기 클라이언트를 사용하세요:import com.dodopayments.api.client.DodoPaymentsClientAsync
import com.dodopayments.api.client.okhttp.DodoPaymentsOkHttpClientAsync
import kotlinx.coroutines.runBlocking
val asyncClient: DodoPaymentsClientAsync = DodoPaymentsOkHttpClientAsync.fromEnv()
runBlocking {
val customer = asyncClient.customers().retrieve("cust_123")
println("Customer email: ${customer.email()}")
}
오류 처리
Kotlin의 예외 처리를 사용하여 오류를 처리합니다:import com.dodopayments.api.errors.*
try {
val payment = client.payments().create(params)
println("Success: ${payment.paymentId()}")
} catch (e: AuthenticationException) {
println("Authentication failed: ${e.message}")
} catch (e: InvalidRequestException) {
println("Invalid request: ${e.message}")
e.parameter?.let { println("Parameter: $it") }
} catch (e: RateLimitException) {
println("Rate limit exceeded, retry after: ${e.retryAfter}")
} catch (e: DodoPaymentsServiceException) {
println("API error: ${e.statusCode()} - ${e.message}")
}
함수형 오류 처리
함수형 오류 처리에는Result를 사용하세요:
fun safeCreatePayment(client: DodoPaymentsClient): Result<Payment> = runCatching {
client.payments().create(params)
}
// Usage
safeCreatePayment(client)
.onSuccess { payment -> println("Created: ${payment.paymentId()}") }
.onFailure { error -> println("Error: ${error.message}") }
Result 타입을 사용하여 보다 함수형에 가까운 오류 처리를 구현하려면 Kotlin의
runCatching를 사용하세요.Android 통합
Android 애플리케이션에서 사용합니다:import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dodopayments.api.client.DodoPaymentsClient
import kotlinx.coroutines.launch
class PaymentViewModel(application: Application) : ViewModel() {
private val client = DodoPaymentsOkHttpClient.builder()
.bearerToken(BuildConfig.DODO_API_KEY)
.build()
fun createCheckout(productId: String) {
viewModelScope.launch {
try {
val session = client.async().checkoutSessions().create(params)
// Open checkout URL in browser or WebView
openUrl(session.checkoutUrl())
} catch (e: Exception) {
handleError(e)
}
}
}
}
응답 검증
응답 검증을 활성화합니다:import com.dodopayments.api.core.RequestOptions
// Per-request validation
val product = client.products().retrieve(
"pdt_123",
RequestOptions.builder()
.responseValidation(true)
.build()
)
// Or validate explicitly
val validatedProduct = product.validate()
고급 기능
프록시 구성
프록시 설정을 구성합니다:import java.net.InetSocketAddress
import java.net.Proxy
val client = DodoPaymentsOkHttpClient.builder()
.fromEnv()
.proxy(
Proxy(
Proxy.Type.HTTP,
InetSocketAddress("proxy.example.com", 8080)
)
)
.build()
임시 구성
클라이언트 구성을 임시로 수정합니다:val customClient = client.withOptions {
it.baseUrl("https://example.com")
it.maxRetries(5)
}
Ktor 통합
Ktor 서버 애플리케이션과 통합합니다:import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Application.configureRouting() {
val client = DodoPaymentsOkHttpClient.builder()
.bearerToken(environment.config.property("dodo.apiKey").getString())
.build()
routing {
post("/create-checkout") {
try {
val request = call.receive<CheckoutRequest>()
val session = client.checkoutSessions().create(params)
call.respond(mapOf("checkout_url" to session.checkoutUrl()))
} catch (e: DodoPaymentsServiceException) {
call.respond(HttpStatusCode.BadRequest, mapOf("error" to e.message))
}
}
}
}
리소스
GitHub Repository
소스 코드를 확인하고 기여하기
API Reference
전체 API 문서
Discord Community
도움을 받고 개발자들과 소통하기
Report Issues
버그를 신고하거나 기능을 요청하기
지원
Kotlin SDK에 도움이 필요하신가요?- Discord: 실시간 지원을 받으려면 커뮤니티 서버에 참여하세요
- Email: support@dodopayments.com으로 문의하세요
- GitHub: repository에 이슈를 등록하세요