Questions Regarding Subscription Receipt Behavior in LAT (RVS cancelReason and Multi-Device Handling)

Hello, and thank you for your time and support.

When testing in-app purchases using LAT, we observed the following behavior.

Prerequisites

  • LAT environment
  • Subscription-type item purchase
  • Subscription renewal acceleration enabled
  • The subscription item is configured with a 30-day validity period

Purchase ticket → Activate subscription

On the device where the purchase was made:

  • One of the receipts has isCancelled = null

  • When validating the receipt with isCancelled = null via RVS:

    • cancelReason in the response is 1
    • The billing date is 4/20, and the cancellation date appears as 6/16
  • Repurchase is not possible

When logging in on another device:

  • None of the receipts have isCancelled = null
  • Repurchase is not possible

Cancel subscription

  • The state remains exactly the same as described above under “Purchase ticket → Activate subscription”
  • The subscription item disappears from the Amazon subscription management page
  • Repurchase becomes possible

Question

I would appreciate your guidance on the following points:

  1. When validating a receipt for an active subscription via RVS, the response shows cancelReason = 1, with a billing date of 4/20 and a cancellation date of 6/16.

    • Is this expected behavior?
    • We have also observed the same behavior even when renewal acceleration is turned OFF.
  2. When logging into the app on a different device using the same Amazon account while the subscription is active, we are unable to retrieve a valid receipt (i.e., a receipt where isCancelled = null).

    • Are there any required steps or conditions to correctly retrieve this receipt?
  3. Even after canceling the subscription, valid receipts continue to be returned.

    • The subscription is removed from the Amazon website, indicating it is canceled.
    • If we refresh the Live App Testing environment with a new test, the receipts are then correctly returned as invalid.
    • Do you have any insight into why this behavior occurs?

Thank you very much for your time and assistance.

Hello @dkksmph_dev01

Thank you for the detailed report. Here are answers to each of your questions basis the information you shared.

Question 1: Active subscription showing cancelReason = 1 with a future cancelDate via RVS - is this expected?
A: Yes, this is expected behavior in the LAT environment with accelerated subscriptions. Here’s why:

  • cancelReason = 1 means “the customer canceled the order” - but in the context of LAT accelerated subscriptions, subscriptions are automatically canceled after four renewals to prevent infinite renewals. The system pre-sets a cancelDate at the point when the subscription will expire after its final renewal cycle.
  • Your 30-day subscription with acceleration enabled maps to a ~10-minute accelerated cycle. The billing date of 4/20 and cancellation date of 6/16 reflect the system projecting the end-of-life for the subscription after the allowed renewal cycles.
  • Per the RVS documentation: “A cancelDate of null indicates that the subscription for this receipt is still active. If the receipt is for an expired subscription, the cancelDate would reflect the date the subscription expired.” In LAT with acceleration, the system populates this date in advance.
  • The fact that you see the same behavior with acceleration turned OFF suggests the LAT environment may still be applying test transaction lifecycle rules. LAT subscriptions are beta/test transactions (betaProduct: true) and may behave differently from production subscriptions in terms of how cancelDate and cancelReason are populated.

Recommendation: Verify the cancelDate via RVS - if the cancelDate is in the future relative to the current time, treat the subscription as still active. The key check should be: cancelDate == null || cancelDate > currentTime

Question 2: Unable to retrieve a valid receipt (isCancelled = null) on a different device with the same Amazon account
A: Please confirm you are calling getPurchaseUpdates(true) on the second device.
This is the recommended approach for restoring subscriptions across devices.

  • getPurchaseUpdates(false) returns only receipts that have changed since the
    last invocation on that device.
  • getPurchaseUpdates(true) returns the full purchase history (active and
    canceled) regardless of prior invocations.

Additionally, we recommend validating receipts server-side via RVS using the receiptId and userId. RVS is device-independent and returns the authoritative subscription state. If getPurchaseUpdates(true) still does not return the active receipt on the second device, this may be a LAT-specific limitation with receipt syncing that does not occur in production.

Question 3: After canceling the subscription, valid receipts continue to be returned - subscription only clears after refreshing the LAT environment
A: This is a known LAT environment behavior:

  • When a subscription is canceled, the receipt’s cancelDate gets populated and isCancelled should reflect the cancellation. However, in LAT, receipt state may be cached on the device and getPurchaseUpdates() may continue returning stale data until the cache is refreshed.
  • The fact that the subscription disappears from the Amazon subscription management page confirms the cancellation was processed server-side. The client-side receipts are lagging behind.
  • Refreshing the LAT environment (starting a new test) clears the cached receipt state, which is why receipts then correctly reflect as invalid.

Workarounds:

  1. Always validate subscription status server-side via RVS rather than relying solely on client-side getPurchaseUpdates() receipts.
  2. When testing cancellation flows in LAT, call getPurchaseUpdates(true) (reset = true) after cancellation to force a full receipt refresh.
  3. For production, this caching issue is significantly less pronounced - RVS is the source of truth and should be your primary validation mechanism.

To properly investigate and resolve this case, here’s what we would like to request you to share:

  1. Account & App Details:
  • Amazon Developer account email / Developer ID
  • App package name (e.g., com.example.myapp)
  • ASIN of the app
  • Subscription SKU(s) being tested
  1. LAT Environment Details:
  • LAT test ID / test name
  • Is accelerated subscription renewal enabled or disabled? (you mentioned both - please clarify current state)
  • Device serial number(s) for both the original device and the second device
  1. Receipt & RVS Details:
  • The receiptId that has isCancelled = null on-device but shows cancelReason = 1 via RVS
  • Full RVS response JSON for that receipt (redact the shared secret)
  • The userId returned by getUserData()
  • Are you using RVS sandbox or production endpoint for validation?
  1. Implementation Details:
  • How are you calling getPurchaseUpdates()? With reset = true or false?
  • Appstore SDK version being used
  • Are you using client-side receipt checking only, or also server-side RVS validation?
  • Relevant code snippet showing how they check isCancelled and call getPurchaseUpdates()
  1. Reproduction Details:
  • Exact steps to reproduce (timestamp of purchase, cancellation, and cross-device login)

  • Device models and Fire OS versions for both devices

  • Screenshots of:

    • The receipt data returned by getPurchaseUpdates() on both devices
    • The RVS response showing cancelReason = 1
    • The Amazon subscription management page showing the subscription removed
  • ADB logs (adb logcat) from both devices during the purchase and cross-device retrieval attempts

  1. Timeline:
  • When was the subscription purchased? (exact date/time)
  • When was it canceled?
  • When was the second device tested?
  • How long after cancellation did you check receipts again?

This information will allow us to trace the exact transaction in the backend and determine whether the behavior is a LAT environment limitation or a defect.

If you want to keep your responses confidential, you raise a Contact Us case with us through the Developer Console with the requested data.

Warm Regards,
Ivy

Thank you for your response.

As the information contains sensitive details, I have sent a message via “Contact Us” under case ID 20057357861.

I appreciate your support and look forward to your assistance.

Hello,

Thank you for your response.

I have also replied via the “Contact Us” channel under case ID 20057357861 with additional information.

I appreciate your continued support.

Best regards,

Hello @dkksmph_dev01

I had responded on your Contact Us Case already, requesting some details.
I’m working on it.

Warm regards,
Ivy