[Question] How to verify subscriptions on backend with openIAP #151
Replies: 2 comments 3 replies
-
|
@timolino13 Your understanding is mostly correct! Here's the server-side validation pattern: Frontend Flow:
Backend Flow:
Example from the codebase: where it demonstrates sending the token to a backend endpoint for verification before granting access to premium features.
**Key Points:**
- **Don't validate locally**: Never trust the `Purchase` object's state on the client side alone
- **Always verify server-side**: The JWS token proves the purchase to your backend
- **Token format**: The `purchaseToken` is a cryptographically signed JWT that can't be forged
- **Expiration handling**: Your backend receives `state: "expired"` if the subscription lapsed, allowing you to revoke access
**Security Best Practice:**
```swift
// Frontend: Send token to backend
let purchaseToken = purchase.purchaseToken
let response = try await backend.validateSubscription(token: purchaseToken)
// Backend (pseudocode):
POST /verify-subscription
Body: { "token": purchaseToken }
Response: { "isValid": true, "state": "entitled" }This ensures users can't fake premium access by modifying local app state. The IAPKit verification endpoint is the single source of truth for subscription validity. 🤖 Generated by gitdog.dev · Have more questions? Tag |
Beta Was this translation helpful? Give feedback.
-
|
Small correction to the Gitdog answer above: the token source is right, but I would not recommend passing the purchase token/JWS from the frontend on every premium API request. In OpenIAP,
In import { Platform } from "react-native";
import {
kitApi,
verifyPurchaseWithProvider,
type Purchase,
} from "expo-iap";
const IAPKIT_API_KEY = "openiap-kit_...";
export async function verifyAndBindPurchase(
purchase: Purchase,
userId: string,
) {
const token = purchase.purchaseToken;
if (!token) throw new Error("Missing purchase token");
const result = await verifyPurchaseWithProvider({
provider: "iapkit",
iapkit: {
apiKey: IAPKIT_API_KEY,
...(Platform.OS === "ios"
? { apple: { jws: token } }
: { google: { purchaseToken: token } }),
},
});
if (result.iapkit?.isValid) {
await kitApi({ apiKey: IAPKIT_API_KEY }).bindUser(token, userId);
}
return result.iapkit;
}For backend-gated premium access, I still recommend making your backend the final authority:
POST https://kit.openiap.dev/v1/purchase/verify
Authorization: Bearer openiap-kit_...
Content-Type: application/jsonApple body: { "store": "apple", "jws": "..." }Google body: { "store": "google", "purchaseToken": "..." }
POST /v1/subscriptions/bind-user/{apiKey}
{ "purchaseToken": "...", "userId": "your-user-id" }
GET /v1/subscriptions/status/{apiKey}?userId=...
GET /v1/subscriptions/entitlements/{apiKey}?userId=...Why
Related docs:
|
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Original Content
I'm trying to implement subscriptions in my Expo app using openIAP.
As far as I understand from the docs, on the app side you can do everything using the expo-iap package. This means I don't need to call my own backend to verify anything that has to do with subscriptions, but can do everything using the provided methods that connect to the IAPKit, and use verifyPurchaseWithProvider to verify the subscription. (I hope I got that right)
Now the thing I don't understand is how I verify these things in my backend. For example, I have a premium account and send a request to my backend that requires a premium account. How do I verify that in the backend?
I found the https://kit.openiap.dev/v1/purchase/verify endpoint, which requires a purchaseToken or jws. Where do I get that? Am I supposed to pass that from the frontend on every request that needs subscription validation?
Thank you for any help!
Question
How do I verify subscriptions on my backend when a user makes a request that requires a premium account?
Context
I'm implementing subscriptions in an Expo app using openIAP. I understand that:
expo-iappackage withverifyPurchaseWithProviderto verify subscriptionsHowever, I'm unclear about the backend verification flow.
What I've Found
I discovered the
https://kit.openiap.dev/v1/purchase/verifyendpoint, which requires either apurchaseTokenorjwsparameter.What I Need Help With
purchaseTokenorjwsfrom?Thank you for any guidance!
🤖 Formatted by gitdog.dev
Beta Was this translation helpful? Give feedback.
All reactions