CONCEPTS

Customers and identity.

Who a purchase belongs to, how it follows a customer across devices and sign-ins, and what RevFox stores about them.

01

Customer IDs

A customer is known by the ID your app gives the SDK. Use your own stable user ID once someone signs in. Before that, the SDK runs anonymously under a random UUID it generates and keeps for the install.

  • Pass customerId in the SDK configuration when the user is already signed in at launch.
  • Call setCustomer(id:) (Flutter: logIn) when someone signs in, and clearCustomer() (Flutter: logOut) when they sign out.
  • The SDK sends $anonymous as true or false, so RevFox knows which IDs are generated.
Pick unguessable IDs

The SDK API key is public, so customer IDs should not be guessable. Use your database's UUIDs, not email addresses or sequential numbers.

02

Signing in: aliases and transfers

When a customer signs in, or restores purchases that another customer owns, RevFox decides how the two IDs relate. It depends on whether the ID making the request is anonymous.

Requesting IDWhat happensHistory and webhooks
AnonymousAlias. The two IDs become one customer. The one seen first keeps its ID as the original; the other becomes its alias. Purchases, history and later requests for either ID resolve to the same customer.An ALIAS event in history. Not sent to webhooks.
Signed inTransfer. Every purchase the current owner holds moves to the requesting customer.A TRANSFER event for both customers. The recipient's is sent to webhooks.

This covers buying before signing up: someone buys anonymously, then creates an account, and from then on either ID acts as the signed-in customer.

A transfer moves all the owner's purchases, not just the restored one. The restored receipt only proves which owner to move from. Responses keep the customer_id the app sent and add original_customer_id when it is an alias.

03

Placeholder customers

A store notification can arrive for a purchase RevFox has never seen, for example one made before the app used RevFox. What happens depends on the app's Track new purchases from store notifications switch.

  • Off, the default: the notification is kept but not acted on, unless the store names a customer RevFox already has. The purchase is recorded when your app or an import reports it, which also fills in its renewals and refunds from the store.
  • On: the purchase is recorded straight away. When the store names no known customer, it goes under a placeholder customer.

The App Store history sync always records what it finds. A placeholder's ID is:

  • For the App Store, a UUID derived from the subscription's original_transaction_id, so every notification of that subscription finds the same placeholder.
  • For Play, Google's obfuscated account ID, or play:<token hash>.

Placeholders are anonymous and their events reach webhooks with the placeholder as app_user_id. When your app or an import later reports the purchase, the placeholder is merged into the real customer and deleted. Webhooks then get a TRANSFER from the placeholder to the customer.

Apple names the customer directly when the purchase carried an appAccountToken RevFox knows. The SDK sets one by default for anonymous customers.

04

Family Sharing

An App Store transaction marked FAMILY_SHARED entitles a family member without making them the owner. RevFox records the family member as a holder of the purchase. The purchaser stays the owner.

  • The family member gets the benefits, with ownership: "FAMILY_SHARED" on the purchase.
  • Shared rows carry no revenue, so the purchase is counted once.
  • A family-shared receipt cannot be used to transfer the purchase.
05

How benefits are worked out

A customer has a benefit while they own, hold through Family Sharing, or were granted something active that unlocks it. RevFox works this out on every read, from:

  • store transactions the customer owns, in the requested environment, that have not expired, been refunded or been revoked;
  • active promotional grants, which count in every environment.

Production and sandbox purchases are kept apart. A sandbox purchase never unlocks anything in a production build, and the reverse. See environments.

06

Attributes

Attributes are string values on a customer, shown on their profile and sent with every webhook as subscriber_attributes. Each keeps the time it last changed.

  • Collected by the SDK: platform, app version and build, SDK version, locale, time zone, storefront, install source, and push token once set.
  • Only after the app opts in with collectDeviceIdentifiers(): device model, manufacturer, OS version, IP address, IDFV, and the advertising ID where the user allows it.
  • Set by the app: email, display name, phone number, attribution fields and other tools' IDs, through the SDK's setters.
  • Custom: any key not starting with $, with setAttributes or the server API.

Keys starting with $ are reserved. The full list is in the SDK HTTP protocol. Personal values such as email belong to the signed-in customer and are dropped from the device when they sign out; install values such as the push token are kept.

For an IP address, the SDK only sends $ip as "true". RevFox records the address the request came from, reading the client address from proxy headers such as CF-Connecting-IP and X-Forwarded-For.

07

Promotional grants

A grant gives a customer a benefit without a store purchase: for support, a giveaway or a partner deal. Grant from the customer's page in the panel or with the server API, for a duration (daily up to yearly, or lifetime) or until a set time.

  • Grants count in every environment and add no revenue.
  • They follow the customer when an anonymous ID is aliased into it.
  • Granting and revoking are recorded in history and sent to webhooks as NON_RENEWING_PURCHASE and EXPIRATION with store: "PROMOTIONAL".
  • A timed grant that runs out sends no event. Access ends at its expiration_at_ms.
08

Deleting a customer

Deleting removes the customer, their aliases, the purchases they own, their history, pending webhook deliveries and grants. Purchases they made but later transferred stay with the new owner.

Deleting does not cancel store subscriptions. If a subscription is still active, its next store notification can create a placeholder customer again.

Next concept

Purchases and revenue.

Read on