Kotlin SDK¶
Idiomatic Kotlin client for PulseRoute. Zero dependencies, data classes, named parameters. Requires Java 11+.
Installation¶
Gradle (Kotlin DSL)¶
Gradle (Groovy)¶
Quick Start¶
val pulse = PulseRoute(
apiKey = System.getenv("PULSEROUTE_KEY"),
baseUrl = "https://api.pulseroute.dev"
)
// Pre-transaction: get routing decision
val route = pulse.getRoute(RouteRequest(country = "US", currency = "USD", cardType = "visa"))
// Process payment with route.processorId...
// Post-transaction: report outcome (fire-and-forget)
pulse.reportOutcome(OutcomeRequest(
ruleId = route?.ruleId ?: "",
processorId = route?.processorId ?: "",
success = true,
latencyMs = 145.0
))
// On shutdown
pulse.shutdown()
Stripe + Adyen Integration¶
val pulse = PulseRoute(apiKey = System.getenv("PULSEROUTE_KEY"))
fun processPayment(country: String, currency: String, cardType: String, amount: Long): PaymentResult {
val route = pulse.getRoute(RouteRequest(country, currency, cardType = cardType))
val start = System.currentTimeMillis()
return try {
val result = when (route?.processorId) {
"stripe" -> stripe.charges.create(amount, currency)
"adyen" -> adyen.payments.create(amount, currency)
else -> stripe.charges.create(amount, currency) // default
}
pulse.reportOutcome(OutcomeRequest(
ruleId = route?.ruleId ?: "",
processorId = route?.processorId ?: "",
success = true,
latencyMs = (System.currentTimeMillis() - start).toDouble()
))
result
} catch (e: PaymentException) {
pulse.reportOutcome(OutcomeRequest(
ruleId = route?.ruleId ?: "",
processorId = route?.processorId ?: "",
success = false,
latencyMs = (System.currentTimeMillis() - start).toDouble(),
errorCode = e.code
))
// Try fallback
route?.fallbackProcessorId?.let { fallback ->
processWithFallback(fallback, amount, currency)
} ?: throw e
}
}
Spring Boot¶
@Configuration
class PulseRouteConfig {
@Bean
fun pulseRouteClient(
@Value("\${pulseroute.api-key}") apiKey: String,
@Value("\${pulseroute.base-url:http://localhost:8080}") baseUrl: String,
) = PulseRoute(apiKey = apiKey, baseUrl = baseUrl)
@PreDestroy
fun shutdown(@Autowired client: PulseRoute) = client.shutdown()
}
Ktor¶
fun Application.configurePulseRoute() {
val pulse = PulseRoute(
apiKey = environment.config.property("pulseroute.apiKey").getString()
)
environment.monitor.subscribe(ApplicationStopped) {
pulse.shutdown()
}
routing {
post("/pay") {
val route = pulse.getRoute(RouteRequest("US", "USD"))
// ... process payment ...
}
}
}
Configuration¶
| Option | Default | Description |
|---|---|---|
apiKey |
null |
API key for authentication |
baseUrl |
http://localhost:8080 |
PulseRoute API URL |
timeoutMs |
5000 | HTTP request timeout |
flushIntervalMs |
5000 | Outcome flush interval |
batchSize |
50 | Max outcomes per flush |
Features¶
- Zero dependencies — Java 11+
HttpClientunder the hood - Idiomatic Kotlin — data classes, named parameters, null safety
- Local decision cache — falls back to cached decision if API unreachable
- Fire-and-forget outcomes — buffered and flushed async in batches
- Thread-safe — daemon flush thread, concurrent collections
- AutoCloseable — works with
use {}blocks