Subscribe a user by calling your backend to initialize a transaction with a Paystack plan code. Open the authorization_url in your WebView Activity. After checkout, Paystack creates the subscription. Your backend receives the subscription.create webhook. Check subscription status from Android by calling your backend status API, not Paystack directly.
If you distribute your app on the Google Play Store and sell digital subscriptions through it, Google requires you to use Google Play Billing for in-app purchases. Paystack subscriptions work best for:
For consumer apps on the Play Store with digital subscriptions, consult the Google Play policies before using Paystack for subscription billing. This guide is most applicable to non-Play Store distribution or B2B apps.
// viewmodel/SubscriptionViewModel.kt
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
data class SubscriptionStatus(
val active: Boolean = false,
val planName: String? = null,
val nextBillingDate: String? = null,
val subscriptionCode: String? = null,
val loading: Boolean = true,
val error: String? = null
)
class SubscriptionViewModel : ViewModel() {
private val _status = MutableStateFlow(SubscriptionStatus())
val status: StateFlow<SubscriptionStatus> = _status
fun checkStatus(userEmail: String) {
viewModelScope.launch {
_status.value = SubscriptionStatus(loading = true)
try {
val result = RetrofitClient.subscriptionApi.getStatus(userEmail)
_status.value = SubscriptionStatus(
active = result.active,
planName = result.planName,
nextBillingDate = result.nextBillingDate,
subscriptionCode = result.subscriptionCode,
loading = false
)
} catch (e: Exception) {
_status.value = SubscriptionStatus(loading = false, error = e.message)
}
}
}
fun cancelSubscription(subscriptionCode: String, emailToken: String) {
viewModelScope.launch {
try {
RetrofitClient.subscriptionApi.cancel(subscriptionCode, emailToken)
_status.value = _status.value.copy(active = false)
} catch (e: Exception) {
_status.value = _status.value.copy(error = "Cancel failed: ${e.message}")
}
}
}
}
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
// SubscriptionActivity.kt
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
class SubscriptionActivity : AppCompatActivity() {
private val viewModel: SubscriptionViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_subscription)
val userEmail = intent.getStringExtra("email") ?: return finish()
val statusText = findViewById<TextView>(R.id.statusText)
val planText = findViewById<TextView>(R.id.planText)
val nextBillingText = findViewById<TextView>(R.id.nextBillingText)
val cancelButton = findViewById<Button>(R.id.cancelButton)
val subscribeButton = findViewById<Button>(R.id.subscribeButton)
lifecycleScope.launch {
viewModel.status.collect { state ->
if (state.loading) {
statusText.text = "Loading..."
return@collect
}
if (state.active) {
statusText.text = "Active"
planText.text = state.planName ?: "Unknown plan"
nextBillingText.text = "Next billing: ${state.nextBillingDate}"
cancelButton.visibility = View.VISIBLE
subscribeButton.visibility = View.GONE
cancelButton.setOnClickListener {
viewModel.cancelSubscription(
state.subscriptionCode ?: "",
getEmailToken()
)
}
} else {
statusText.text = "No active subscription"
cancelButton.visibility = View.GONE
subscribeButton.visibility = View.VISIBLE
subscribeButton.setOnClickListener {
startPaymentActivity(userEmail)
}
}
}
}
viewModel.checkStatus(userEmail)
}
}
This guide is part of the Paystack integration guides by language and framework series.
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course