Vega/Kepler LAT: purchase() intermittently returns FAILED (4) with null receipt

:backhand_index_pointing_right: Bug Description

  1. Summary

On Live App Testing, in-app purchases from our Vega (Kepler) build are inconsistent.
PurchasingService.purchase() sometimes completes, and sometimes returns
PurchaseResponseCode.FAILED (4) with receipt: null — same build, same device, same account,
same SKU. Every other IAP call (getUserData, getProductData, getPurchaseUpdates) returns
SUCCESSFUL 100% of the time, including during the failing runs. PurchaseResponse carries no
error detail field, so the client receives no reason code and we cannot diagnose it.

Impact: we cannot reliably test or ship in-app purchasing on Vega devices.

App Name: TF1+
App Link on Amazon Appstore: <fill from Developer Console → Actions → View on Amazon.com>

Bug Severity:
Blocks current development

  1. Steps to Reproduce

  2. Build the app as a Vega/Kepler .vpkg (armv7, Release) and distribute it via Live App
    Testing.

  3. Install on a Fire TV Stick 4K Select and sign in with a LAT tester account.

  4. Call PurchasingService.getUserData() — returns SUCCESSFUL.

  5. Call PurchasingService.getProductData({ skus }) — returns SUCCESSFUL with correct
    titles, prices and product types.

  6. Call PurchasingService.getPurchaseUpdates({ reset: true }) — returns SUCCESSFUL.

  7. Call PurchasingService.purchase({ sku }).

  8. Repeat step 6 across sessions.

Observed: step 6 sometimes succeeds and sometimes returns FAILED (4). Steps 3–5 succeed
every time regardless.

  1. Observed Behavior

purchase() returns, after approximately 10 seconds:

responseCode : 4 (PurchaseResponseCode.FAILED)
receipt : null
userData : { userId “”, marketplace “FR” } (sometimes null on retries)

During a failing streak this is 100% reproducible. We recorded 11 consecutive failures
across 3 SKUs covering both product types, and 3 different customer accounts,
getProductData call succeeded throughout:

SUBSCRIPTION → FAILED (4)
CONSUMABLE → FAILED (4)
CONSUMABLE → FAILED (4)

Device log during a failing purchase() — the Amazon IAP UI launches, comes to the
foreground, then dismisses itself with exit status 0, far faster than a user
a checkout:

appInst(com.amazon.iap.core.ui): LAUNCH in IDLE Completed: true
appInst(com.amazon.iap.core.ui): START in LAUNCHED Completed: true
appInst(com.amazon.iap.core.ui): FOREGROUND in READY Completed: true
appInst(com.amazon.iap.core.ui): Finished foreground transition
appInst(com.amazon.iap.core.ui): BACKGROUND in VISIBLE Completed: true
appInst(com.amazon.iap.core.ui): Execution completed: 0

Related inconsistency: on one attempt purchase() returned ALREADY_PURCHASED (
subscription while getPurchaseUpdates simultaneously returned SUCCESSFUL with 0 receipts —
ownership asserted, but no receipt retrievable.

  1. Expected Behavior

purchase() should either complete and return SUCCESSFUL with a valid receipt, or return a
response code that identifies why it could not complete. Behaviour should be
for the same build, device, account and SKU.

4.a Possible Root Cause & Temporary Workaround

No workaround found. Ruled out on our side:

  • Customer account: 3 different Amazon accounts, all affected.
  • SKU / product type: 3 SKUs across SUBSCRIPTION and CONSUMABLE, all affected.
  • User-data handshake: getUserData() is called before purchase() and returns
    with a valid userId and marketplace.
  • App reinstall and device reboot do not clear it.
  • Manifest declarations are unchanged between working and failing runs:
    [[needs.module]] /com.amazon.kepler.appstore.iap.purchase.core@IAppstore
    [[needs.module]] /com.amazon.kepler.appstore_iap_lib_2@IAppstoreIapLib_12
    [[wants.service]] com.amazon.iap.core.service
    [[wants.module]] /com.amazon.iap.core@IIAPCoreUI

Questions we currently have:

  • Is there rate limiting or throttling on LAT purchase attempts, per app, acc
    device? Our failures occur in streaks, which would be consistent with throttling.
  • Is there a cooldown or propagation delay after “Reset in-app items” / “Rese
    Subscriptions”, or after uploading a new build, during which purchases are refused while
    the catalog continues to serve product data normally?
  • Is there per-device or per-session state in the IAP service that can go stale and cause
    purchase() to fail until refreshed?
  • Can the cause of a FAILED (4) be looked up server-side from the requestId returned in
    PurchaseResponse?
  1. Logs or crash report

App/Device logs attached. No crash occurs — purchase() returns FAILED (4) normally.

  1. Environment

SDK Version: 0.22.5875
React Native Version: RN 0.72
App State: Foreground

  1. Example Code Snippet / Screenshots / Screengrabs

import { PurchasingService } from ‘@amazon-devices/keplerscript-appstore-iap-lib’

// Succeeds every time, including during failing runs
const userData = await PurchasingService.getUserData({
fetchUserProfileAccessConsentStatus: true,
})
const { productData } = await PurchasingService.getProductData({ skus })
const updates = await PurchasingService.getPurchaseUpdates({ reset: true })

// Intermittent: sometimes SUCCESSFUL, sometimes FAILED (4) with receipt: nul
const response = await PurchasingService.purchase({ sku })
// response.responseCode === 4, response.receipt === null

:backhand_index_pointing_right: Playback Issues

N/A

:backhand_index_pointing_right: Additional Context

  • @amazon-devices/keplerscript-appstore-iap-lib 2.12.13
  • @amazon-devices/react-native-kepler 2.0.1758683737
  • Marketplace: FR
  • Distribution: Live App Testing
  • Device: Fire TV Stick 4K Select, OS 1.1, armv7

Hi @hanchaoui,

Thank you for the exceptionally detailed report - the elimination you’ve already done (3 accounts, 3 SKUs across both product types, getUserData/getProductData/getPurchaseUpdates succeeding throughout, reinstall/reboot ruled out) is very helpful.

To investigate the intermittent purchase() failures returning FAILED (4) with a null receipt, let’s confirm a couple of things on your side and gather logs so we can trace what’s happening.

Two things to confirm on your side first

  • Release build for LAT: LAT requires a Release .vpkg - Debug builds do not function in LAT, and because keplerscript-appstore-iap-lib is system-bundled, a non-Release build can cause IAP calls to fail. You’ve indicated you’re building armv7 Release, so this likely isn’t your issue, but please confirm, and confirm the IAP library is correctly system-bundled in your Release vpkg. References: IAP Overview ( IAP Overview - Amazon Vega Docs ) and system-bundle troubleshooting ( Troubleshooting Guide for System Bundles ).
  • If feasible, consider testing on the latest IAP library version, in case the behavior differs from 2.12.13.

On your specific questions

  • Rate limiting / throttling on LAT purchases; cooldown after “Reset in-app items” / “Reset Subscriptions”; per-device/per-session stale state: these aren’t documented behaviors, so we’d need the logs and requestIds below to determine what’s happening in your case rather than speculate.
  • Server-side lookup by requestId: yes - the requestId returned in PurchaseResponse is the identifier used to trace a specific purchase. Please capture the requestId for the failing attempts (these are already in your logs).

What will let us investigate this

To move this forward, please share:

  1. Complete device logs captured from a fresh terminal session (not an IDE/iTerm terminal), covering the entire purchase journey - app launch → purchase() call → the failure response - for a reproduced failure.
  2. The requestId(s) from the failing purchase() responses, with timestamps (UTC).
  3. Confirmation of the Release build, and that the IAP library is system-bundled in the vpkg you’re testing.

Best regards,
Aishwarya