Quick Start

Get your first paywall live in under 5 minutes.

1. Install

npm install paywallkit

2. Initialize

import { PaywallKit } from 'paywallkit';
PaywallKit.init({ apiKey: 'pk_live_your_key', theme: 'dark' });

3. Present a Paywall

PaywallKit.present({
  template: 'gradient-pro',
  products: [
    { id: 'yearly', name: 'Annual', price: '$49.99/yr', badge: 'Best Value' },
    { id: 'monthly', name: 'Monthly', price: '$9.99/mo' }
  ],
  onPurchase: (product) => console.log('Selected:', product.id),
  onDismiss: () => console.log('Dismissed')
});

Installation

Install via npm, yarn, or CDN.

npm install paywallkit
# or
yarn add paywallkit
# or CDN
<script src="https://cdn.paywallkit.com/v1/paywallkit.min.js"></script>

Configuration

PaywallKit.init({
  apiKey: 'pk_live_your_key',
  theme: 'dark',        // 'light', 'dark', 'auto'
  locale: 'en',
  debug: false,
  analytics: true,
  onError: (err) => console.error(err)
});
OptionTypeDefaultDescription
apiKeystring-Your API key
themestring'auto'Theme mode
localestring'en'Locale
debugbooleanfalseDebug logging
analyticsbooleantrueEvent tracking

Templates

TemplateDescriptionBest For
gradient-proFull-screen gradientPremium apps
minimal-modalClean modalSaaS
feature-gridPlan comparisonMulti-tier
bottom-sheetiOS bottom sheetMobile
fullscreenFull takeoverOnboarding
inline-bannerBannerContent sites
trial-countdownCountdownTrial urgency
social-proofSocial proofTrust
multi-stepMulti-step flowOnboarding
floating-cardFloating cardPersistent

Products

const products = [
  { id: 'yearly', name: 'Annual', price: '$49.99/yr', badge: 'Best Value',
    features: ['Unlimited access', 'Priority support', 'Custom themes'] },
  { id: 'monthly', name: 'Monthly', price: '$9.99/mo',
    features: ['Full access', 'Email support'] }
];

Events & Callbacks

PaywallKit.present({
  template: 'gradient-pro', products,
  onPurchase: (product) => { /* purchase */ },
  onDismiss: () => { /* dismissed */ },
  onRestore: () => { /* restore */ },
  onImpression: () => { /* shown */ }
});

A/B Testing

PaywallKit.experiment({
  name: 'pricing-test-q1',
  variants: [
    { name: 'control', template: 'gradient-pro', weight: 50 },
    { name: 'variant-a', template: 'minimal-modal', weight: 50 }
  ],
  onAssignment: (v) => console.log('Assigned:', v.name)
});

Stripe

PaywallKit.init({
  apiKey: 'pk_live_...',
  billing: { provider: 'stripe', publishableKey: 'pk_live_stripe_key' }
});

RevenueCat

PaywallKit.init({
  apiKey: 'pk_live_...',
  billing: { provider: 'revenuecat', apiKey: 'rc_api_key' }
});

Apple IAP

// Swift
PaywallKit.shared.configure(apiKey: "pk_live_...", billing: .appleIAP)

Google Play Billing

// Kotlin
PaywallKit.configure(apiKey = "pk_live_...", billing = GooglePlayBilling())

React

import { PaywallProvider, usePaywall } from 'paywallkit/react';
function App() {
  return <PaywallProvider apiKey="pk_live_..."><MyApp /></PaywallProvider>;
}
function UpgradeButton() {
  const { present } = usePaywall();
  return <button onClick={() => present({ template: 'gradient-pro' })}>Upgrade</button>;
}

Vue

import { PaywallPlugin } from 'paywallkit/vue';
createApp(App).use(PaywallPlugin, { apiKey: 'pk_live_...' }).mount('#app');

Svelte

<script>
import { paywall } from 'paywallkit/svelte';
paywall.init({ apiKey: 'pk_live_...' });
</script>
<button on:click={() => paywall.present({ template: 'gradient-pro' })}>Upgrade</button>

Vanilla JS

<script src="https://cdn.paywallkit.com/v1/paywallkit.min.js"></script>
<script>
PaywallKit.init({ apiKey: 'pk_live_...' });
document.getElementById('btn').onclick = () => PaywallKit.present({...});
</script>

Swift (iOS)

import PaywallKit
PaywallKit.shared.configure(apiKey: "pk_live_...")
PaywallKit.shared.present(template: .gradientPro, products: [
  .init(id: "yearly", name: "Annual", price: "$49.99/yr")
]) { result in
  switch result {
  case .purchased(let p): print("Purchased: \(p.id)")
  case .dismissed: print("Dismissed")
  }
}

Kotlin (Android)

PaywallKit.configure(apiKey = "pk_live_...")
PaywallKit.present(template = Template.GradientPro, products = listOf(
  Product(id = "yearly", name = "Annual", price = "$49.99/yr")
)) { result -> when (result) {
  is PaywallResult.Purchased -> println("Purchased")
  is PaywallResult.Dismissed -> println("Dismissed")
}}

API Reference

MethodEndpointDescription
GET/api/healthHealth check
GET/api/v1/configGet config
POST/api/v1/eventsTrack events
POST/api/v1/experimentExperiment assignment
POST/api/v1/checkoutCreate checkout
GET/api/v1/analyticsAnalytics

Webhooks

POST /api/v1/webhooks
{ "event": "purchase.completed", "userId": "user_123", "productId": "yearly", "amount": 4999 }

Analytics

const stats = await PaywallKit.analytics({ period: '30d' });
// { impressions: 12500, conversions: 625, revenue: 31225 }

Self-Hosting

git clone https://github.com/mr-girff/paywallkit.git
cd paywallkit && npm install && npm run deploy

Changelog

v1.0.0 (2024-12-01)

  • Initial release with 10 templates
  • Stripe & RevenueCat integration
  • A/B testing engine
  • React, Vue, Svelte, Swift, Kotlin SDKs