Skip to content

qotra/slickpay-kotlin

Repository files navigation

slickpay-kotlin

Kotlin SDK for the Slick-Pay API.

Module Artifact Description
slickpay dev.qotra:slickpay Kotlin/JVM HTTP client
slickpay-spring dev.qotra:slickpay-spring Spring Boot 4 autoconfiguration
slickpay-ui dev.qotra:slickpay-ui Compose Multiplatform payment WebView (Android + iOS)

Installation

dependencies {
  implementation("dev.qotra:slickpay:1.0.0")

  // Spring Boot autoconfiguration (optional)
  implementation("dev.qotra:slickpay-spring:1.0.0")

  // Compose Multiplatform WebView (optional)
  implementation("dev.qotra:slickpay-ui:1.0.0")
}

Usage

All API methods are suspend functions. The client implements AutoCloseable.

val client = SlickPayClient("your-api-key")

// Sandbox
val client = SlickPayClient("your-api-key", baseUrl = "https://devapi.slick-pay.com")

Accounts

val result = client.accounts.create(
  CreateAccountRequest(
    rib = "00799999004929530156", title = "Mr",
    firstname = "John", lastname = "Doe",
    address = "123 Main St, Algiers", default = 0,
  )
)
println(result.uuid)

val page    = client.accounts.list(page = 1)
val account = client.accounts.get("uuid").data
client.accounts.update("uuid", UpdateAccountRequest(address = "New Address"))
client.accounts.delete("uuid")

Contacts

val contact = client.contacts.create(
  CreateContactRequest(
    rib = "00799999004929530156", firstname = "Jane",
    lastname = "Smith", address = "456 Elm St",
  )
)

val contacts = client.contacts.list()
client.contacts.update(contact.uuid!!, UpdateContactRequest(phone = "+213555000000"))
client.contacts.delete(contact.uuid!!)

Invoices

val commission = client.invoices.calculateCommission(10_000)

val invoice = client.invoices.create(
  CreateInvoiceRequest(
    amount  = 10_000,
    contact = "contact-uuid",
    url     = "https://my-site.com/thank-you",
    items   = listOf(InvoiceItem("Product A", price = 10_000, quantity = 1)),
  )
)
// Redirect the user to invoice.url to complete payment

val details = client.invoices.get(invoice.id.toString())
// details.completed == 1 means paid

Transfers

val commission = client.transfers.calculateCommission(5_000)

val transfer = client.transfers.create(
  CreateTransferRequest(amount = 5_000, contact = "contact-uuid")
)

val status = client.transfers.get(transfer.id.toString())

Aggregations

val commission = client.aggregations.calculateCommission(
  AggregationCommissionRequest(
    type     = AggregationType.PERCENTAGE,
    total    = 10_000,
    contacts = listOf(
      AggregationContact("uuid-1", 60),
      AggregationContact("uuid-2", 40),
    ),
  )
)

val aggregation = client.aggregations.create(
  CreateAggregationRequest(
    type     = AggregationType.AMOUNT,
    total    = 10_000,
    contacts = listOf(
      AggregationContact("uuid-1", 6_000),
      AggregationContact("uuid-2", 4_000),
    ),
  )
)

Error handling

try {
  client.invoices.get("bad-id")
} catch (e: SlickPayException) {
  println("HTTP ${e.statusCode}: ${e.error.message}")
  e.error.errors?.forEach { (field, messages) ->
    println("  $field: ${messages.joinToString()}")
  }
}

Spring Boot

Set your API key in application.properties and a SlickPayClient bean is registered automatically:

slickpay.api-key=your-api-key-here
slickpay.base-url=https://prodapi.slick-pay.com  # optional
@Service
class PaymentService(private val slickPay: SlickPayClient) {
  suspend fun pay(amount: Long, contactUuid: String): String {
    val invoice = slickPay.invoices.create(
      CreateInvoiceRequest(amount = amount, contact = contactUuid)
    )
    return invoice.url ?: error("No payment URL returned")
  }
}

Compose Multiplatform WebView

Renders the SlickPay iFrame payment flow on Android and iOS. First create an invoice with qrcode = true, then pass the returned invoice number to the composable:

@Composable
fun PaymentScreen(invoiceNumber: String, onSuccess: () -> Unit) {
  SlickPayWebView(
    config = SlickPayWebViewConfig(
      invoiceNumber    = invoiceNumber,
      production       = true,
      locale           = SlickPayLocale.FR,  // FR, AR, EN
      onPaymentSuccess = onSuccess,
      onError          = { e -> /* handle */ },
    ),
    modifier = Modifier.fillMaxSize(),
  )
}

Always verify the invoice status server-side before marking an order as paid. The callback is for navigation only.

License

MIT