Stripe API API in Kotlin

Stripe API API in Kotlin

This guide shows you how to integrate the Stripe API into your Kotlin application. Full-stack payments platform for cards, bank transfers, wallets, subscriptions, marketplaces, and billing.

Prerequisites

  • Kotlin installed on your system
  • An Stripe API API key (sign up at https://stripe.com)
  • Basic familiarity with HTTP APIs

Installation

// build.gradle.kts
dependencies {
    implementation("io.ktor:ktor-client-core:2.3.0")
    implementation("io.ktor:ktor-client-cio:2.3.0")
    implementation("io.ktor:ktor-client-content-negotiation:2.3.0")
    implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.0")
}

Basic Usage

import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import kotlinx.coroutines.*

fun main() = runBlocking {
    val apiKey = System.getenv("API_KEY") ?: "YOUR_API_KEY"
    val baseUrl = "https://api.stripe.com"

    val client = HttpClient(CIO)
    val response: HttpResponse = client.get("$baseUrl/v1/resources") {
        header("Authorization", "Bearer $apiKey")
        header("Content-Type", "application/json")
    }

    println("Status: ${response.status}")
    println(response.bodyAsText())
    client.close()
}

Error Handling

import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import kotlinx.coroutines.*

suspend fun callApiWithRetry(url: String, apiKey: String, maxRetries: Int = 3): HttpResponse {
    val client = HttpClient(CIO)
    var attempt = 0
    while (true) {
        val response = client.get(url) {
            header("Authorization", "Bearer $apiKey")
            header("Content-Type", "application/json")
        }
        if (response.status.value != 429 && response.status.value < 500) {
            client.close()
            return response
        }
        println("Attempt $attempt failed (HTTP ${response.status}). Waiting 60s...")
        delay(60000)
        attempt++
        if (attempt >= maxRetries) {
            client.close()
            throw RuntimeException("Max retries exceeded: ${response.status}")
        }
    }
}

fun main() = runBlocking {
    val apiKey = System.getenv("API_KEY") ?: "YOUR_API_KEY"
    val response = callApiWithRetry("https://api.stripe.com/v1/resources", apiKey)
    println(response.bodyAsText())
}

Advanced Usage

import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import kotlinx.coroutines.*
import kotlinx.serialization.json.*

class StripeClient(
    private val apiKey: String,
    private val baseUrl: String = "https://api.stripe.com"
) {
    private val client = HttpClient(CIO)

    suspend fun request(method: HttpMethod, path: String, body: String? = null): JsonObject {
        val url = "$baseUrl/v1$path"
        val response = client.request(url) {
            this.method = method
            header("Authorization", "Bearer $apiKey")
            header("Content-Type", "application/json")
            if (body != null) setBody(body)
        }
        if (!response.status.isSuccess()) {
            throw RuntimeException("API Error: HTTP ${response.status}")
        }
        return Json.parseToJsonElement(response.bodyAsText()).jsonObject
    }

    suspend fun listResources(limit: Int = 50): JsonObject =
        request(HttpMethod.Get, "/resources?limit=$limit")

    suspend fun createResource(data: String): JsonObject =
        request(HttpMethod.Post, "/resources", data)
}

fun main() = runBlocking {
    val client = StripeClient(System.getenv("API_KEY") ?: "YOUR_API_KEY")
    val resources = client.listResources()
    println("Found ${resources["data"]?.jsonArray?.size ?: 0} resources")
    client.close()
}

Best Practices

  • Store your API key in an environment variable, never in source code
  • Implement retry logic with exponential backoff for 429 and 5xx errors
  • Set reasonable timeouts (10-30 seconds) for all API calls
  • Log request IDs from response headers for debugging
  • Cache responses where appropriate to reduce API calls

Other languages