Skip to main content

Environment:

  • iOS app using the latest RevenueCat SDK

  • Subscriptions set up in a single Subscription Group in App Store Connect

  • Monthly subscription (Level 2) and Annual subscription (Level 1)

  • In Sandbox 

Steps to Reproduce:

  1. User purchases the Monthly subscription.

  2. Before the Monthly period expires, the user purchases the Annual subscription.

  3. RevenueCat webhooks are received in this order:

    • PRODUCT_CHANGE

    • RENEWAL

    • CANCELLATION (with product_id corresponding to the Annual subscription)

Observed Behavior:

  • After upgrading, the CANCELLATION webhook references the Annual subscription, causing our backend logic to treat it as if the new subscription itself was canceled.

  • When the Annual subscription naturally reaches its expiration date, it does not auto-renew, confirming that the annual plan’s renewal has indeed been disabled.

Expected Behavior:

  • CANCELLATION should reference the Monthly product (old plan).
  • Annual subscription should continue auto-renewing at each billing cycle.

Questions:

  1. Is it expected that an upgrade flow emits CANCELLATION for the new subscription’s product_id, or is this a misconfiguration?

Log:
{"event":{"event_timestamp_ms":1745813064860,"product_id":"month","period_type":"NORMAL","purchased_at_ms":1745813005000,"expiration_at_ms":1745813305000,"environment":"SANDBOX","entitlement_id":null,"entitlement_ids":t"artday pro"],"presented_offering_id":"default","transaction_id":"2000000907748472","original_transaction_id":"2000000907668057","is_family_share":false,"country_code":"US","app_user_id":"efceb22e-8b5f-4dca-8024-a86b8cb77633","aliases":i"$RCAnonymousID:7850d75db12a4df2885ecd0152bca305","efceb22e-8b5f-4dca-8024-a86b8cb77633"],"original_app_user_id":"$RCAnonymousID:7850d75db12a4df2885ecd0152bca305","new_product_id":"annual","currency":"USD","price":0,"price_in_purchased_currency":0,"subscriber_attributes":{"$attConsentStatus":{"value":"denied","updated_at_ms":1745802062222}},"store":"APP_STORE","takehome_percentage":0.7,"offer_code":null,"tax_percentage":0,"commission_percentage":0.3,"metadata":null,"renewal_number":null,"type":"PRODUCT_CHANGE","id":"876BDE94-FFF0-44D1-962E-DE81B10C5A85","app_id":"appb66944c101"},"api_version":"1.0"}

{"event":{"event_timestamp_ms":1745813285422,"product_id":"annual","period_type":"NORMAL","purchased_at_ms":1745813305000,"expiration_at_ms":1745816905000,"environment":"SANDBOX","entitlement_id":null,"entitlement_ids":t"artday pro"],"presented_offering_id":"default","transaction_id":"2000000907749765","original_transaction_id":"2000000907668057","is_family_share":false,"country_code":"US","app_user_id":"efceb22e-8b5f-4dca-8024-a86b8cb77633","aliases":i"$RCAnonymousID:7850d75db12a4df2885ecd0152bca305","efceb22e-8b5f-4dca-8024-a86b8cb77633"],"original_app_user_id":"$RCAnonymousID:7850d75db12a4df2885ecd0152bca305","currency":"USD","is_trial_conversion":false,"price":59.99,"price_in_purchased_currency":59.99,"subscriber_attributes":{"$attConsentStatus":{"value":"denied","updated_at_ms":1745802062222}},"store":"APP_STORE","takehome_percentage":0.7,"offer_code":null,"tax_percentage":0,"commission_percentage":0.3,"metadata":null,"renewal_number":16,"type":"RENEWAL","id":"3595A06C-1DF9-463E-9E52-04C9B238796F","app_id":"appb66944c101"},"api_version":"1.0"}

{"event":{"event_timestamp_ms":1745813285425,"product_id":"annual","period_type":"NORMAL","purchased_at_ms":1745813305000,"expiration_at_ms":1745816905000,"environment":"SANDBOX","entitlement_id":null,"entitlement_ids":t"artday pro"],"presented_offering_id":"default","transaction_id":"2000000907749765","original_transaction_id":"2000000907668057","is_family_share":false,"country_code":"US","app_user_id":"efceb22e-8b5f-4dca-8024-a86b8cb77633","aliases":i"$RCAnonymousID:7850d75db12a4df2885ecd0152bca305","efceb22e-8b5f-4dca-8024-a86b8cb77633"],"original_app_user_id":"$RCAnonymousID:7850d75db12a4df2885ecd0152bca305","cancel_reason":"UNSUBSCRIBE","currency":"USD","price":0,"price_in_purchased_currency":0,"subscriber_attributes":{"$attConsentStatus":{"value":"denied","updated_at_ms":1745802062222}},"store":"APP_STORE","takehome_percentage":0.7,"offer_code":null,"tax_percentage":0,"commission_percentage":0.3,"metadata":null,"renewal_number":16,"type":"CANCELLATION","id":"5A4974AA-6C78-4F8F-9F37-DCD331352B8A","app_id":"appb66944c101"},"api_version":"1.0"}

Resolved: The issue was caused by an incorrect subscription level configuration.