Android / Kotlin
Installation
Section titled “Installation”Add JitPack to your project-level settings.gradle.kts:
dependencyResolutionManagement { repositories { google() mavenCentral() maven { url = uri("https://jitpack.io") } }}Add the dependencies to your module-level build.gradle.kts:
dependencies { implementation("com.github.Sanwohq.android:sanwo:0.1.1") implementation("com.github.Sanwohq.android:paystack:0.1.1")}Requirements
Section titled “Requirements”- Min SDK 24
- Kotlin
Quick start
Section titled “Quick start”import com.sanwohq.sanwo.Sanwoimport com.sanwohq.paystack.paystackProvider
class CheckoutActivity : AppCompatActivity() {
private val sanwo = Sanwo( provider = paystackProvider, publicKey = "pk_test_xxxxxxxxxxxx" )
private val launcher = sanwo.registerForCheckoutResult(this) { result -> when (result) { is CheckoutResult.Successful -> { Log.d("Sanwo", "Paid! Ref: ${result.reference}") } is CheckoutResult.Cancelled -> { Log.d("Sanwo", "User cancelled") } is CheckoutResult.Failed -> { Log.d("Sanwo", "Failed: ${result.error}") } } }
fun pay() { val options = CheckoutOptions( amount = 500000, // 5,000.00 NGN in kobo currency = "NGN", customer = CheckoutCustomer(email = "customer@example.com") ) sanwo.launchCheckout(this, launcher, options) }}import com.sanwohq.sanwo.Sanwoimport com.sanwohq.paystack.paystackProvider
class CheckoutActivity : AppCompatActivity() {
private val sanwo = Sanwo( provider = paystackProvider, publicKey = "pk_test_xxxxxxxxxxxx" )
fun pay() { val options = CheckoutOptions( amount = 500000, currency = "NGN", customer = CheckoutCustomer(email = "customer@example.com") )
sanwo(this, options) { result -> when (result) { is CheckoutResult.Successful -> { Log.d("Sanwo", "Paid! Ref: ${result.reference}") } is CheckoutResult.Cancelled -> { Log.d("Sanwo", "User cancelled") } is CheckoutResult.Failed -> { Log.d("Sanwo", "Failed: ${result.error}") } } } }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) sanwo.onActivityResult(requestCode, resultCode, data) }}val sanwo = Sanwo( provider = paystackProvider, publicKey = "pk_test_xxxxxxxxxxxx", debug = false, // optional timeout = 120 // optional, seconds)| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
provider |
SanwoProvider |
Yes | — | Provider from a provider package |
publicKey |
String |
Yes | — | Your provider public key |
debug |
Boolean |
No | false |
Enable debug logging |
timeout |
Int |
No | 120 |
Timeout in seconds |
CheckoutOptions
Section titled “CheckoutOptions”val options = CheckoutOptions( amount = 500000, currency = "NGN", customer = CheckoutCustomer(email = "customer@example.com"), reference = "order_abc123", // optional channels = listOf("card", "bank"), // optional metadata = mapOf("plan" to "premium"),// optional extra = mapOf("split_code" to "SPL_xxx") // optional, provider-specific)| Property | Type | Required | Description |
|---|---|---|---|
amount |
Long |
Yes | Amount in minor units (kobo, cents, paisa) |
currency |
String |
Yes | ISO 4217 currency code |
customer |
CheckoutCustomer |
Yes | Customer with at least an email |
reference |
String? |
No | Your unique transaction reference |
channels |
List<String>? |
No | Allowed payment channels |
metadata |
Map<String, Any>? |
No | Arbitrary metadata |
extra |
Map<String, Any>? |
No | Provider-specific options |
CheckoutResult
Section titled “CheckoutResult”A sealed class with three variants:
sealed class CheckoutResult { data class Successful( val reference: String, val providerResponse: Any? ) : CheckoutResult()
object Cancelled : CheckoutResult()
data class Failed( val error: String ) : CheckoutResult()}Checkout patterns
Section titled “Checkout patterns”Modern: Activity Result API (recommended)
Section titled “Modern: Activity Result API (recommended)”Register the result handler in your activity or fragment. The launcher is reusable.
// Register once (must be called before onStart)private val launcher = sanwo.registerForCheckoutResult(this) { result -> // handle result}
// Launch checkout whenever neededfun pay() { sanwo.launchCheckout(this, launcher, options)}Legacy: onActivityResult
Section titled “Legacy: onActivityResult”Use the callback-based API and forward onActivityResult:
sanwo(activity, options) { result -> // handle result}
// Don't forget to forward:override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) sanwo.onActivityResult(requestCode, resultCode, data)}Events
Section titled “Events”Subscribe to lifecycle events. on() returns an unsubscribe function.
val unsubscribe = sanwo.on(SanwoEvent.SUCCESS) { payload -> Log.d("Sanwo", "Payment succeeded: ${payload["reference"]}")}
// Laterunsubscribe()Available events
Section titled “Available events”| Event | Description |
|---|---|
SanwoEvent.STARTED |
Checkout initiated |
SanwoEvent.OPENED |
Checkout UI visible |
SanwoEvent.LOADED |
Provider UI finished loading |
SanwoEvent.SUCCESS |
Payment successful |
SanwoEvent.CANCELLED |
User dismissed checkout |
SanwoEvent.FAILED |
Payment failed |
SanwoEvent.CLOSED |
Checkout UI dismissed |
Full example
Section titled “Full example”import android.os.Bundleimport android.widget.Toastimport androidx.appcompat.app.AppCompatActivityimport com.sanwohq.sanwo.*import com.sanwohq.paystack.paystackProvider
class MainActivity : AppCompatActivity() {
private val sanwo = Sanwo( provider = paystackProvider, publicKey = "pk_test_xxxxxxxxxxxx" )
private val checkoutLauncher = sanwo.registerForCheckoutResult(this) { result -> when (result) { is CheckoutResult.Successful -> { Toast.makeText( this, "Paid! Ref: ${result.reference}", Toast.LENGTH_LONG ).show() } is CheckoutResult.Cancelled -> { Toast.makeText(this, "Cancelled", Toast.LENGTH_SHORT).show() } is CheckoutResult.Failed -> { Toast.makeText( this, "Failed: ${result.error}", Toast.LENGTH_LONG ).show() } } }
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
// Track events sanwo.on(SanwoEvent.LOADED) { _ -> Log.d("Sanwo", "Checkout UI loaded") }
findViewById<Button>(R.id.payButton).setOnClickListener { val options = CheckoutOptions( amount = 500000, currency = "NGN", customer = CheckoutCustomer(email = "customer@example.com"), reference = "order_${System.currentTimeMillis()}" ) sanwo.launchCheckout(this, checkoutLauncher, options) } }}Jetpack Compose
Section titled “Jetpack Compose”You can use the same Sanwo instance from a Compose activity:
class ComposeCheckoutActivity : ComponentActivity() {
private val sanwo = Sanwo( provider = paystackProvider, publicKey = "pk_test_xxxxxxxxxxxx" )
private val launcher = sanwo.registerForCheckoutResult(this) { result -> // handle result }
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Button(onClick = { sanwo.launchCheckout( this@ComposeCheckoutActivity, launcher, CheckoutOptions( amount = 500000, currency = "NGN", customer = CheckoutCustomer(email = "customer@example.com") ) ) }) { Text("Pay ₦5,000") } } }}