Purchases
Validate purchases directly with Apple and Google
Use InfluTo without RevenueCat — add App Store Server API and Google Play credentials, let the SDK report purchases, and InfluTo verifies each one with the store.
Store-direct is for apps that don't use RevenueCat. The InfluTo SDK sends the store's signed proof of each purchase — a StoreKit 2 transaction on iOS, a Play Billing purchase token on Android — and InfluTo verifies it with Apple or Google before recording a commission. Afterwards InfluTo checks attributed subscriptions with the stores every hour to pick up renewals, cancellations and refunds. You don't need a backend of your own.
Using RevenueCat? Use the RevenueCat path instead — never both on the same platform.
Add your store credentials
Open Settings → Validation for the app. InfluTo only reads from the stores; it never changes anything in your accounts.
Apple (App Store Server API)
- In App Store Connect, open Users and Access → Integrations → In-App Purchase and create a key. Download the
.p8file — Apple lets you download it once. - Note the Issuer ID and the Key ID shown on that page.
- In InfluTo, upload the
.p8(drag and drop works; the Key ID is read from the file name when it's Apple's default), enter the Issuer ID and Key ID, and the app's numeric App Store ID (needed for production). - Choose the Environment: Sandbox while you test with TestFlight or sandbox testers, Production before you release. InfluTo verifies against exactly the environment you pick — a TestFlight purchase sent to an app set to Production fails verification.
The app also needs its bundle ID set (it comes from the store listing when you add the app).
Google (Play Developer API)
- In Google Cloud, enable the Google Play Android Developer API and create a service account with a JSON key.
- In the Play Console, open Users and permissions, invite the service account's email, and give it View financial data, orders, and cancellation survey responses for the app.
- Upload the JSON key in InfluTo and press Save & validate.
New Google permissions can take up to 48 hours to reach the API. InfluTo shows the check as "propagating" meanwhile.
Switch the platform to store-direct
When the credential check is green, pick Apple — direct, Google — direct or Both stores — direct as the validation provider. You can't switch before the check passes, and until you do, the SDK's purchase reports are answered with 400 — so it's safe to ship the SDK first.
The choice is per platform: iOS can be store-direct while Android stays on RevenueCat.
Let the SDK report purchases
On store-direct platforms the SDK captures purchases on its own once you add the platform's capture code. At startup it asks InfluTo whether the platform is store-direct, and only then starts listening — so the same build is safe on RevenueCat apps.
| SDK | To capture automatically |
|---|---|
| iOS | Built in — the SDK observes StoreKit 2 transactions (also report right after each purchase, see below) |
| React Native | Install expo-iap or react-native-iap |
| Android | Add to.influ:android-sdk-billing |
| Flutter | Add influto_iap and call InfluToPurchaseObserver().enable() after initialize |
| Web / Capacitor | Pass a purchaseSource — capgoNativePurchasesSource(), cordovaPurchaseSource() or digitalGoodsSource() for Play in a TWA |
Automatic capture also back-fills purchases that happened before it started, and reports each purchase once. Selling one-time products on Android? List their product IDs in oneTimeProductIds (React Native, Android, web) so they're validated as one-time purchases rather than subscriptions.
Reporting purchases yourself
You can call reportPurchase after each successful purchase — instead of automatic capture (set autoCapture: false), or alongside it. Reports are de-duplicated on the store's transaction identity, so a purchase reported twice is still counted once.
// Store-direct only (no RevenueCat). With expo-iap or react-native-iap installed,
// purchases are captured automatically on store-direct apps. To report
// manually instead, pass the store-signed proof:
await InfluTo.reportPurchase({
platform: 'ios', // or 'android'
signedTransaction: jwsString, // iOS: StoreKit 2 JWS
// purchaseToken: token, // Android: Play Billing purchaseToken
});// Store-direct only (no RevenueCat). Report right after a purchase — StoreKit
// doesn't send purchases made in your app to the background listener, and
// reports are de-duplicated, so this is safe alongside auto-capture:
if case .success(let verification) = try await product.purchase() {
let r = try await InfluTo.reportPurchase(verification: verification)
}// Store-direct only (no RevenueCat). With the android-sdk-billing artifact on the
// classpath, purchases are captured AUTOMATICALLY. To report manually:
InfluTo.reportPurchase(
purchaseToken = purchase.purchaseToken,
// productId = "coins_100", // one-time / consumable products only
)// Store-direct only (no RevenueCat). For automatic capture add influto_iap and
// call InfluToPurchaseObserver().enable() after initialize(). Or report manually:
await InfluTo.instance.reportPurchase(
platform: 'ios', // or 'android'
signedTransaction: jws, // iOS: StoreKit 2 JWS
// purchaseToken: token, // Android: Play Billing purchaseToken
);// Store-direct only (no RevenueCat). Attach a purchase source and purchases are
// captured automatically — TWA/PWA on Play: digitalGoodsSource(); Capacitor:
// capgoNativePurchasesSource(); Cordova: cordovaPurchaseSource(). Or report manually:
await InfluTo.reportPurchase({
platform: 'android', // or 'ios'
purchaseToken: token, // Android: Play Billing purchaseToken
// signedTransaction: jws, // iOS: StoreKit 2 JWS
});reportPurchasethrows on failure — handle it.- A
503means the currency rate wasn't available; retry later. Reports are idempotent, so retrying is safe. - A
409on Android means the one-time purchase isn't in the PURCHASED state yet (still pending). - On iOS, set the purchase's
appAccountTokenwithInfluTo.appAccountToken(forUserID:)if you want purchases tied to your user ID.
Purchases are de-duplicated on the store's identity — Apple's original transaction ID and Google's purchase token — so the same purchase is never counted twice, whoever reports it.
What InfluTo handles on the server
- Verifies every reported purchase with Apple or Google before recording it.
- Converts the price to USD at the purchase date's exchange rate; commissions are calculated in USD.
- Checks attributed subscriptions every hour for renewals, cancellations, expirations and refunds.
- Reverses commission on refunded subscriptions and one-time purchases on both stores.
Test it
- Set the Apple environment to Sandbox and use a TestFlight or sandbox tester account, or a Google Play license tester.
- Open a referral link, install, launch, buy.
- Check Real-Time Events — the purchase shows as validated and attributed. Sandbox purchases never move money.
Switch Apple back to Production before you release. Full checklist: Verify the integration.
With an AI agent
Agents can't receive your keys — credentials always go through a dashboard link you open yourself (influto_get_credential_upload_link). After that, influto_validate_store_credentials runs the green check and influto_activate_store_direct switches the platform over. See AI agents.