You'll need a CashSDK workspace. Create one for free, no card needed until your first real purchase.
Quickstart
Zero to a validated purchase in about 15 minutes: get your API keys, install an SDK, model a product, and confirm the receipt server-side.
This guide takes you from zero to a validated purchase. It should take about 15 minutes.
1. Get your API keys#
Every workspace has two kinds of keys:
| Key | Prefix | Used by |
|---|---|---|
| Publishable | csk_pk_… / csk_pk_… | Client SDKs (safe to ship) |
| Secret | csk_sk_… | Your backend, the CLI, and the MCP server |
Find them under Settings → API keys in the dashboard, or read more in Authentication.
2. Install the SDK#
// In Xcode: File → Add Packages…
// https://github.com/cashsdk/cashsdk-ios
import CashSDK
// settings.gradle.kts → repositories { google(); mavenCentral() }
// build.gradle.kts
dependencies {
implementation("com.cashsdk:cashsdk-android:1.2.0")
}
npm install cashsdk-react-native
flutter pub add cashsdk
npm install cashsdk-web
3. Configure on launch#
Initialize CashSDK once, as early as possible, with your publishable key.
import CashSDK
CashSDK.configure(publishableKey: "csk_pk_…")
import com.cashsdk.CashSDK
// In Application.onCreate()
CashSDK.configure(context = this, publishableKey = "csk_pk_…")
Then identify the signed-in customer, on every launch:
CashSDK.shared.identify(userId: "8841", userToken: tokenFromYourBackend)
CashSDK.shared.identify(userId = "8841", userToken = tokenFromYourBackend)
4. Create a product#
Model a subscription in the dashboard under Catalog, then confirm it from the terminal with the CLI:
cashsdk catalog # products + entitlements
cashsdk catalog sync # pull the latest from the store
Prefer to let an agent do it? Point Cursor, Claude Code, or Codex at the CashSDK MCP server and ask it to set up your catalog.
5. Show a paywall and purchase#
Present your paywall and complete a purchase with a product identifier. CashSDK handles the native store interaction and verifies the transaction server-side.
switch try await CashSDK.shared.purchase("pro_monthly") {
case .success(let entitlements):
if entitlements.isActive("pro") { unlockPro() }
case .pending: showPendingNotice() // Ask-to-Buy / SCA
case .userCancelled: break
}
// Play Billing launches its flow from an Activity.
val entitlements = CashSDK.shared.purchase(activity, "pro_monthly")
if (entitlements.isActive("pro")) {
unlockPro()
}
Then gate features on the entitlement, a synchronous, offline-valid read:
if CashSDK.shared.entitlements.isActive("pro") { unlockPro() }
if (CashSDK.shared.entitlements.isActive("pro")) unlockPro()
If purchase throws, the transaction is deliberately left unfinished and the
store will redeliver it. Never tell the customer they were not charged.
Show a retry instead.
6. Verify server-side (optional)#
Your backend can check entitlements or validate a receipt directly:
curl https://api.cashsdk.com/v1/receipts/validate \
-H "Authorization: Bearer csk_sk_..." \
-H "Content-Type: application/json" \
-d '{ "platform": "apple", "receipt": "MII...", "app_user_id": "u_812" }'