How do I connect the App Store to RevenueDot?

Three steps: create an App Store app in RevenueDot with your bundle ID, give it an In-App Purchase key so it can ask Apple about purchases, and paste its notification URL into App Store Connect as the Version 2 server notification URL. The dashboard's app page walks you through the same steps and checks each one.

1. Create the app#

In the dashboard: Apps → New app → App Store, with your bundle ID. Or with the API:

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/projects/$PROJECT_ID/apps" \
  -H "Authorization: Bearer $SECRET_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Scanner (iOS)","type":"app_store","app_store":{"bundle_id":"com.example.scanner"}}'

The answer holds the app's id. Its public SDK key (appl_...) is on the app's page, or at GET /v2/projects/{project_id}/apps/{app_id}/public_api_keys. Use type mac_app_store (key mac_...) for a separate Mac App Store app.

2. Add the In-App Purchase key#

RevenueDot uses this key to call Apple's App Store Server API: to confirm each StoreKit 2 purchase, read a customer's full history and renewal state (auto-renew, billing retry, grace period), and extend subscriptions.

  1. Open App Store Connect → Users and Access → Integrations → In-App Purchase.
  2. Click +, name the key (for example RevenueDot) and click Generate.
  3. Download the .p8 file. Apple lets you download it only once.
  4. Note the Key ID (10 characters) and the Issuer ID shown above the keys list.
  5. In the dashboard, open the app → In-app purchase key, drop the .p8 file, fill in the IDs and click Check credentials.

Or with the API. RevenueDot stores these under RevenueCat's field names and never returns them:

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/projects/$PROJECT_ID/apps/$APP_ID" \
  -H "Authorization: Bearer $SECRET_KEY" -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile key AuthKey_ABC123DEFG.p8 '{app_store: {subscription_private_key: $key, subscription_key_id: "ABC123DEFG", subscription_key_issuer: "57246542-96fe-1a63-e053-0824d011072a"}}')"

# Ask Apple whether the key works (one harmless API call).
curl -s -X POST "$REVENUEDOT_URL/v2/projects/$PROJECT_ID/apps/$APP_ID/actions/verify_credentials" -H "Authorization: Bearer $SECRET_KEY"
JSON
{"object":"credentials_check","app_id":"appugfw01uy","store":"app_store","status":"valid","valid":true,"message":"Apple accepted the in-app purchase key.","checked_at":1790801342700,"key_id":"ABC123DEFG"}

Without the key, RevenueDot still verifies StoreKit 2 signed transactions against Apple's root certificate, but it knows only what the device sent: no renewal state and no history. StoreKit 1 receipts need the key. Without it RevenueDot answers 500 with code 7234, so the SDK keeps the purchase and retries after you add the key. (For development only, the allow_unsigned_receipts setting accepts StoreKit 1 receipts without checking them. Anyone could forge such a receipt, so never turn it on in production.)

3. Send App Store Server Notifications to RevenueDot#

Notifications tell RevenueDot about renewals, cancellations, billing problems and refunds when they happen, not only when the app next opens.

  1. Copy the app's notification URL from the dashboard, or from the API. It looks like https://revenuedot.example.com/v1/notifications/apple/{app_id}:
    Shell
    curl -s "$REVENUEDOT_URL/v2/projects/$PROJECT_ID/apps/$APP_ID/store_settings" -H "Authorization: Bearer $SECRET_KEY" | jq -r .notification_url
    Behind a reverse proxy, RevenueDot builds the URL from X-Forwarded-Host and X-Forwarded-Proto. Check that it shows your public HTTPS address.
  2. In App Store Connect, open your app → App Information → App Store Server Notifications.
  3. Paste the URL as both the Production Server URL and the Sandbox Server URL, and choose Version 2.
  4. Make a sandbox purchase. The app's notification status turns Ready when the first notification about a known purchase is processed.

How RevenueDot answers Apple:

  • 200 for every verified notification, including ones about purchases it has not seen. Those are stored, and applied only when Track new purchases from server-to-server notifications is on (track_new_purchases).
  • 400 when the signature is invalid, or the notification is for another bundle ID (or another Apple app ID, when you set app_apple_id). App Store Connect shows these as failed.
  • 500 when RevenueDot itself fails. Apple retries.

Check the status any time: GET /v2/projects/{project_id}/setup_health lists each app's notification_status (ready, failing, received or waiting) and the last error. See store notifications not arriving.

Optional settings#

Set these in the app's app_store object with POST /v2/projects/{project_id}/apps/{app_id}, or in the dashboard under More settings:

Field What it does
notification_forward_url Copies each notification, byte for byte, to another URL, such as RevenueCat's during a dual run. null turns it off
track_new_purchases true: apply notifications about purchases RevenueDot has never seen. Useful during a migration
app_apple_id Your app's Apple ID (a number). Production notifications for another app ID are refused
xcode_certificate The StoreKit test certificate exported from Xcode (PEM). Lets RevenueDot accept purchases made with a StoreKit configuration file in the simulator. See sandbox testing
allow_unsigned_receipts Development only: accept StoreKit 1 receipts without the In-App Purchase key
app_store_connect_api_key, _id, _issuer, app_store_connect_vendor_number A separate App Store Connect API key. Stored for a later product import; not used yet
shared_secret The legacy app-specific shared secret. Stored but not used: RevenueDot does not call Apple's deprecated verifyReceipt endpoint

What you can do from the server afterwards#

  • Extend a subscription by 1 to 90 days: POST /v2/projects/{project_id}/subscriptions/{subscription_id}/actions/extend with extend_by_days and extend_reason_code.
  • Extend every active subscriber of a product, for example after an outage: POST /v2/projects/{project_id}/apps/{app_id}/actions/mass_extend.
  • Refunds are Apple's decision; customers ask Apple. RevenueDot records Apple's REFUND notification as a CANCELLATION with a negative price.
Edit this page on GitHub ↗ View as Markdown Last updated