Store credentials

To validate real purchases server-side, EntitleHub needs to talk to the stores. Apple works out of the box; Google Play needs a service account.

Apple (StoreKit 2) — nothing to configure

Apple StoreKit 2 transactions are signed JWS blobs. Send the signed_transaction to /v1/subscribers/{id}/purchases and EntitleHub verifies it against Apple's root CA — checking the certificate chain and signature — with no per-project secret. The authenticated product id and environment from the receipt override anything the client claims, so a purchase can't be forged.

Apple server-to-server notifications (renewals, cancels, refunds)

So a subscription's renewals / cancellations / refunds stay current server-side without the app re-reporting, point Apple's notifications at EntitleHub. In App Store Connect → your app → App Information → App Store Server Notifications, set the Production (and Sandbox) Version 2 URL to:

text
https://entitlehub.com/v1/notifications/apple/{YOUR_PROJECT_ID}

EntitleHub verifies each notification's signature against Apple's root CA and updates the matching grant. Your Project ID is in Settings → General.

Google Play — add a service account

Google purchase tokens are validated by calling the Play Developer API, which needs a service account with access to your Play account.

  1. In Google Cloud Console, create a service account and a JSON key for it (IAM & Admin → Service Accounts → Keys → Add key → JSON).
  2. Enable the Google Play Android Developer API for that Cloud project.
  3. In Play Console → Users & permissions, invite the service account's email and grant it access to view financial data and manage orders / subscriptions for your app.
  4. In EntitleHub → Dashboard → Settings → Store credentials, paste the JSON key and your app's package name (e.g. com.yourco.app).
The JSON key is a secret

It's stored encrypted and never returned to the browser. Treat it like a password; rotate it in Cloud Console if it's ever exposed.

Reporting a validated Google purchase

Once the credential is in place, pass the purchase token — EntitleHub validates it and uses the store's authenticated expiry:

bash
curl https://entitlehub.com/v1/subscribers/USER_ID/purchases \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "store": "play",
    "store_product_id": "app_pro_monthly",
    "purchase_token": "PLAY_PURCHASE_TOKEN",
    "is_subscription": true
  }'

Google Real-Time Developer Notifications (RTDN)

For automatic renewal / expiry / refund tracking, wire up RTDN:

  1. In Google Cloud → Pub/Sub, create a topic (e.g. play-rtdn).
  2. Add a push subscription on that topic with the endpoint:
    text
    https://entitlehub.com/v1/notifications/google/{YOUR_PROJECT_ID}
  3. Grant Google Play's publisher service account permission to publish to the topic (add [email protected] as a Pub/Sub Publisher).
  4. In Play Console → Monetization setup → Real-time developer notifications, set the topic name to your play-rtdn topic.

On each notification EntitleHub re-validates the purchase token against your Play credential (the source of truth for expiry) and updates the grant — then fires your webhooks. Requires the Google Play credential above.

Stripe — add your secret key

For web subscriptions billed through Stripe, add your Stripe secret key in Dashboard → Settings → Store credentials → Stripe (from Stripe → Developers → API keys). EntitleHub verifies the key against Stripe when you save it, and stores it encrypted.

Map your Stripe Price as an EntitleHub product: create a product with store stripe and store_product_id set to the Stripe Price id (e.g. price_1P…), mapped to an entitlement. Then report a subscription by id — EntitleHub confirms it's active/trialing and uses the current period end as the entitlement expiry:

bash
curl https://entitlehub.com/v1/subscribers/USER_ID/purchases \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "store": "stripe", "stripe_subscription_id": "sub_1P…" }'
Stripe lifecycle

Renewals/cancels currently refresh when you re-report the subscription (e.g. after a Stripe webhook in your own backend calls this endpoint again). Native Stripe-webhook ingestion is on the roadmap, alongside Apple ASSN / Google RTDN.

Credentials set — time to integrate: SDK or REST API.