Skip to content

Latest commit

 

History

History
209 lines (168 loc) · 5.19 KB

File metadata and controls

209 lines (168 loc) · 5.19 KB

PayCraft Customization Guide

Theme Customization

Default Theme (Zero Config)

PayCraft uses Material3 adaptive colors by default — it automatically matches your app's color scheme.

// Default — no customization needed
PayCraftPaywall(onDismiss = { })

Custom Theme

val myTheme = PayCraftTheme(
    colors = PayCraftColorScheme(
        accent = Color(0xFF6200EE),
        activeBadge = Color(0xFF4CAF50),
        premiumGradientStart = Color(0xFF6200EE),
        premiumGradientEnd = Color(0xFF3700B3),
        // ... other tokens or leave as defaults
    ),
    typography = PayCraftTypography(
        titleLarge = MaterialTheme.typography.headlineMedium,
        priceText = TextStyle(
            fontSize = 28.sp,
            fontWeight = FontWeight.Bold,
        ),
    ),
)

PayCraftPaywall(
    onDismiss = { },
    theme = myTheme,
)

Theme Builder

val theme = PayCraftTheme.materialAdaptive(
    accentColor = Color(0xFF6200EE),
    activeBadgeColor = Color(0xFF4CAF50),
)

UI Customization

Option 1: Default UI (Zero Code)

// Full-screen paywall
PayCraftPaywall(onDismiss = { })

// Bottom sheet
PayCraftSheet(visible = show, onDismiss = { show = false })

// Settings banner
PayCraftBanner(
    onClick = { showPaywall = true },
    onRestoreClick = { showRestore = true },
)

// Restore sheet
PayCraftRestore(visible = showRestore, onDismiss = { showRestore = false })

Option 2: Custom Plan Card (Slot API)

Override just the plan card while keeping everything else:

PayCraftPaywall(
    onDismiss = { },
    planCard = { plan, isSelected, isCurrentPlan, onClick ->
        // Your completely custom plan card
        MyPlanCard(
            plan = plan,
            isSelected = isSelected,
            onClick = onClick,
        )
    },
)

Option 3: Custom Benefits

PayCraftPaywall(
    onDismiss = { },
    benefitRow = { benefit ->
        // Your custom benefit row
        Row {
            Text(benefit.text, style = MaterialTheme.typography.bodyLarge)
        }
    },
)

Option 4: Custom Header

PayCraftPaywall(
    onDismiss = { },
    header = {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Image(painter = painterResource(Res.drawable.app_logo), contentDescription = null)
            Text("Unlock ${BuildConfig.APP_NAME} Premium", style = MaterialTheme.typography.headlineMedium)
        }
    },
)

Option 5: Fully Custom UI

Use BillingManager directly and build your own paywall:

@Composable
fun MyCustomPaywall(onDismiss: () -> Unit) {
    val billingManager: BillingManager = koinInject()
    val billingState by billingManager.billingState.collectAsState()
    val plans = PayCraft.requireConfig().plans
    val benefits = PayCraft.requireConfig().benefits
    var selectedPlan by remember { mutableStateOf(plans.first { it.isPopular }) }

    when (billingState) {
        is BillingState.Loading -> LoadingSpinner()

        is BillingState.Premium -> {
            val status = (billingState as BillingState.Premium).status
            PremiumContent(status = status)
        }

        is BillingState.Free -> {
            FreeContent(
                plans = plans,
                benefits = benefits,
                selectedPlan = selectedPlan,
                onPlanSelected = { selectedPlan = it },
                onCheckout = {
                    PayCraft.checkout(selectedPlan, billingManager.userEmail.value)
                },
                onRestore = { email ->
                    billingManager.logIn(email)
                },
            )
        }

        is BillingState.Error -> ErrorContent(
            message = (billingState as BillingState.Error).message,
            onRetry = billingManager::refreshStatus,
        )
    }
}

Plans Customization

Dynamic Plans

Plans are defined in PayCraft.configure() — change them without modifying the library:

plans(
    BillingPlan(id = "weekly",    name = "Weekly",    price = "₹29",    interval = "/week",   rank = 1),
    BillingPlan(id = "monthly",   name = "Monthly",   price = "₹99",    interval = "/month",  rank = 2),
    BillingPlan(id = "yearly",    name = "Yearly",    price = "₹799",   interval = "/year",   rank = 3, isPopular = true),
    BillingPlan(id = "lifetime",  name = "Lifetime",  price = "₹1,999", interval = "once",   rank = 4),
)

Benefits with Custom Icons

benefits(
    BillingBenefit(icon = Icons.Default.Block,       text = "No advertisements"),
    BillingBenefit(icon = Icons.Default.Download,    text = "Unlimited downloads"),
    BillingBenefit(icon = Icons.Default.HighQuality, text = "HD quality"),
    BillingBenefit(icon = Icons.Default.Speed,       text = "Faster downloads"),
    BillingBenefit(icon = Icons.Default.Refresh,     text = "Background sync"),
)

Premium Guard

Gate any content behind premium status:

PayCraftPremiumGuard(
    lockedContent = {
        // Shown when user is not premium
        Button(onClick = { showPaywall = true }) {
            Text("Upgrade to Premium")
        }
    }
) {
    // Shown only to premium users
    PremiumFeatureScreen()
}