Documentation
Two ways to integrate
PayCraft exposes the same billing engine two ways. Use the drop-in paywall for a polished UI in a few lines, or go headless and render your own.
Setup (both modes)
// build.gradle.kts
implementation("io.github.mobilebytelabs:cmp-paycraft:LATEST")
// App startup — Application.kt / MainActivity.kt / AppDelegate
PayCraft.initialize(apiKey = "pk_live_YOUR_KEY_HERE")Mode 1 — Drop-in paywall (themed)
Three lines. The paywall inherits your app's theme — place it inside yourMaterialTheme and it renders with your colors, shapes, and typography (any brand overrides you set in the dashboard layer on top). Products, prices, trials, and copy all come from the dashboard.
@Composable
fun Screen() {
var showPaywall by remember { mutableStateOf(false) }
MaterialTheme(colorScheme = YourAppColorScheme) { // ← paywall uses YOUR theme
// …your UI…
if (showPaywall) {
PayCraftPaywall(onDismiss = { showPaywall = false })
}
}
}That's the whole integration — plan selection, checkout routing (Google Play / App Store / Stripe / Razorpay), trials, coupons, and restore are handled for you.
Mode 2 — Headless (your own UI)
Want full control of the UI? Observe the billing state and drive checkout yourself. No PayCraft composables required.
@Composable
fun Upgrade() {
val billing = PayCraft.billingManager ?: return
val state by billing.billingState.collectAsState()
val plans by PayCraft.suiteConfigFlow.collectAsState()
when (state) {
is BillingState.Premium -> PremiumContent()
is BillingState.Loading -> YourShimmer()
else -> Column {
plans?.products?.forEach { plan ->
YourPlanRow(plan) {
PayCraft.checkout(plan.toBillingPlan()) // routes to the right provider
}
}
}
}
}Useful headless signals:
PayCraft.billingManager?.billingState— Free / Premium / Loading / DeviceConflictPayCraft.billingManager?.isPremium·?.isInTrial·?.trialEndsAtPayCraft.checkout(plan, email?)— starts checkout on the correct provider for the platformPayCraft.applyCoupon(planId, code)— validate + apply a promo codePayCraft.billingManager?.refreshStatus(force = true)— force a re-check
Which should I use?
- Drop-in — fastest, store-compliant, always up to date with the dashboard. Recommended.
- Headless — when your paywall is bespoke or embedded in a larger flow.
Both stay in sync with the dashboard in realtime — change a price, trial, or discount and the app reflects it without a rebuild.