- Home
- Skills
- Mobile Development
- Expo Monetization Pack
Works with the AI Agents you already use
Expo Monetization Pack
Eight agent skills for in-app purchases, subscriptions and paywalls in Expo SDK 57 apps: expo-iap, RevenueCat, store setup, server validation, review rules.
$29
Expo Monetization Pack
Example session with this skill installed
Add a 7-day free trial to our annual plan on both stores and make sure the paywall passes review. We use expo-iap. Here's products.json and the paywall.
- Read your context and instructions
- Compiled the expo monetization
Summary
Found a Play SKU bug that would have shipped, added the trial with durations both stores accept, rewrote the purchase call to use the base plan's offer token, and fixed the paywall disclosures for review.
1. The bug the linter caught
$ node skills/store-products/scripts/lint-products.mjs --manifest products.json --src src
ERROR src/paywall.tsx: "annual" is a Play base plan ID, not a product ID; pass the product ID and pick the base plan through its offer token
1 error(s)
2. Trial added to products.json
App Store free trial options: 3 days, 1 or 2 weeks, 1, 2, 3, 6 months, 1 year. Play: 3 days to 3 years.
{
"type": "subscription",
"apple": { "productId": "com.acme.app.pro.annual", "group": "pro", "level": 1, "period": "P1Y", "introOffer": { "mode": "free", "period": "P1W" } },
"google": { "productId": "pro", "basePlanId": "annual", "period": "P1Y", "offers": [{ "offerId": "trial-7d", "eligibility": "new-customer", "phases": [{ "type": "free", "duration": "P7D" }] }] }
}
3. Purchase call with the offer token
const offers = product.subscriptionOffers.filter((o) => o.basePlanIdAndroid === 'annual' && o.offerTokenAndroid);
const offer = offers.find((o) => o.paymentMode === 'free-trial') ?? offers[0];
if (!offer?.offerTokenAndroid) throw new Error('no offer for base plan annual');
await requestPurchase({
type: 'subs',
request: {
google: {
skus: [product.id],
subscriptionOffers: [{ sku: product.id, offerToken: offer.offerTokenAndroid }],
obfuscatedAccountId: appAccountToken,
},
},
});
On iOS the "Start free trial" label is gated on isEligibleForIntroOfferIOS(product.subscriptionGroupIdIOS), because Apple allows one introductory offer per subscription group per customer.
4. Paywall fixed for review
| Rule | Change |
|---|---|
| Billed amount must be the most prominent price | Annual price large, monthly equivalent small |
| Auto-renew terms next to the button | "7 days free, then $59.99 per year. Renews automatically until cancelled." |
| Restore and legal links | Restore Purchases, Terms of Use, Privacy Policy |
| Localized prices | All prices read from displayPrice |
Next steps
- Add the App Store review notes (where the paywall is, which products are in the submission, purchase works without an account).
- Ship the changed purchase flow in a store build, not an EAS Update.
Connects securely to your tools. The creator never sees your data.
About this skill
Agents write a paywall screen in a minute. Then the app gets rejected or loses money: getProducts and request: { ios } from an expo-iap version that no longer exists, purchase code run in Expo Go, a Play base plan ID passed as the SKU, finishTransaction called before the server granted anything (or never, so Play refunds every purchase after three days), no Restore button, an annual plan advertised by its monthly equivalent, a trial promised to users who already used theirs, access granted from a client flag, and confident but wrong claims about whether Apple allows a "buy on our website" link.
This pack gives the agent the current rules for each of those, checked against package type definitions, Apple and Google documentation, the App Store Review Guidelines (quoted verbatim) and the court record behind US link-outs.
What's inside
- expo-monetization: picks the stack (RevenueCat, expo-iap, web checkout), routes, pre-flight checklist, version boundaries.
- expo-iap-purchases: expo-iap 6 / react-native-iap 17 on StoreKit 2 and Play Billing 9.1, offer tokens, acknowledgement, pending purchases, restore, upgrades.
- revenuecat-expo: react-native-purchases 10.13, entitlements, identity, RevenueCatUI, what Expo Go really does, webhooks into your database.
- store-products: App Store Connect and Play Console setup, subscription groups, base plans, intro offers and the exact allowed trial durations, price localization.
- iap-server-entitlements: JWS verification, App Store Server API, Notifications V2, Play Developer API, RTDN, a Postgres entitlement schema.
- paywall-review: required disclosures, guideline 3.1.x verbatim, review notes, a rejection-to-fix playbook.
- external-purchase-links: US link-outs after Epic v. Apple with dated sources, Stripe Checkout link-out, EU/Japan/Korea programs, Google Play US fees.
- iap-testing: StoreKit files with prebuild, sandbox renewal rates, TestFlight, license testers, a release gate matrix.
Scripts included
Two zero-dependency Node scripts: a product config linter (manifest, .storekit file and source code) and a store notification verifier (Apple signed JWS with chain checks, Play RTDN with Pub/Sub OIDC token checks).
Built to sit next to the Expo Production Pack: it links to that pack's builds, updates and submission guides instead of repeating them.
Versions
Expo SDK 57 (React Native 0.86) with SDK 58 beta notes, expo-iap 6.0.1, react-native-iap 17.0.1, react-native-purchases 10.13.0, Play Billing Library 9.1.0.
How to use
Skills on Agensi run inside your AI agent. Copy the prompt, paste it into your agent, and it connects to Agensi and installs this skill for you. If a payment is needed, your agent shows it to you first.
Reviews
No reviews yet
Be one of the first to try it. Every listed skill passes our trust checks below.
Security scanned
Passed our 8-point scan before listing
Fresh listing
Recently published to Agensi
Money-back guarantee
Doesn't do what its page promises? You get your money back.
Trust & safety
Security scanned
Verified clean 6 days ago
- Passed all security checks, Safe to install
Requires