Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

restorePurchases returns unexpected transactionIdentifier #991

Open
5 tasks done
TobiDevloft opened this issue Apr 30, 2024 · 4 comments
Open
5 tasks done

restorePurchases returns unexpected transactionIdentifier #991

TobiDevloft opened this issue Apr 30, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@TobiDevloft
Copy link

Describe the bug
When purchasing a package (consumable product), I'm storing the returned productIdentifier, purchaseDate and transactionIdentifier in my DB. I now want to implement restore logic using restorePurchases the following way:

const { nonSubscriptionTransactions } = await Purchases.restorePurchases()

My goal is to compare the restored transactions to the ones in my DB. However, the transactionId differs in the restored transactions from the original transaction.

E.g., when the original transaction for purchasePackage looks like this:

{
   "productId":"product_id",
   "productIdentifier":"product_id",
   "purchaseDate":"2024-04-30T16:16:32Z",
   "purchaseDateMillis":1714493792000,
   "revenueCatId":"2000000585921649",
   "transactionIdentifier":"2000000585921649"
}

The corresponding restored transaction looks like this:

{
   "productId":"product_id",
   "productIdentifier":"product_id",
   "purchaseDate":"2024-04-30T16:16:32Z",
   "purchaseDateMillis":1714493792000,
   "revenueCatId":"eb6f56e377",
   "transactionIdentifier":"eb6f56e377"
}

I could just link these transactions using the timestamp, but that does not seem like a clean approach. Am I misunderstanding something here?

I also noticed that the returned properties do not match the PurchasesStoreTransaction interface like specified, but that seems to be another issue.

Thanks for your help!

  1. Environment
    1. Platform: iOS & Android
    2. SDK version: 7.27.0
    3. OS version: MacOS 14.0
    4. Xcode/Android Studio version: Xcode 15.0.1
    5. React Native version: 0.72.5
    6. SDK installation (CocoaPods + version or manual): I don't understand what that is
    7. How widespread is the issue. Percentage of devices affected: All of them
  2. Debug logs that reproduce the issue
  3. Steps to reproduce, with a description of expected vs. actual behavior: Make a purchase, restore that purchase.
@TobiDevloft TobiDevloft added the bug Something isn't working label Apr 30, 2024
@RCGitBot
Copy link
Contributor

👀 We've just linked this issue to our internal tracker and notified the team. Thank you for reporting, we're checking this out!

@WesleyClarkRC
Copy link

Hi! Thank you for raising this issue. We may need to escalate this further. Could you share the debug logs that reproduce this issue?

@TobiDevloft
Copy link
Author

Hi @WesleyClarkRC, thanks for getting back to me. Here are the Debug logs:

APP START

DEBUG: ℹ️ Configuring SDK using RevenueCat's UserDefaults suite.
DEBUG: 👤 Identifying App User ID
DEBUG: ℹ️ Debug logging enabled
DEBUG: ℹ️ SDK Version - 4.41.0
DEBUG: ℹ️ Bundle ID - app.bundle
DEBUG: ℹ️ System Version - Version 17.4.1 (Build 21E236)
DEBUG: ℹ️ Not using a simulator.
DEBUG: 👤 No initial App User ID
DEBUG: ℹ️ Purchases is configured with response verification disabled
DEBUG: ℹ️ Delegate set
DEBUG: ℹ️ No cached Offerings, fetching from network
DEBUG: ℹ️ Offerings cache is stale, updating from network in foreground
DEBUG: ℹ️ GetOfferingsOperation: Started
DEBUG: ℹ️ Network operation 'GetOfferingsOperation' found with the same cache key 'GetOfferingsOpe…'. Skipping request.
DEBUG: ℹ️ There are no requests currently running, starting request GET /v1/subscribers/$RCAnonymousID%3A348a78f9ea4543fb9dc62110489b1742/offerings
DEBUG: ℹ️ API request started: GET '/v1/subscribers/$RCAnonymousID%3A348a78f9ea4543fb9dc62110489b1742/offerings'
DEBUG: ℹ️ API request completed: GET '/v1/subscribers/$RCAnonymousID%3A348a78f9ea4543fb9dc62110489b1742/offerings' (304)
DEBUG: ℹ️ No existing products cached, starting store products request for: ["escape_single_2999", "escape_group_3999"]
DEBUG: ℹ️ Found an existing request for products: ["escape_single_2999", "escape_group_3999"], appending to completion
DEBUG: ℹ️ GetOfferingsOperation: Finished
DEBUG: ℹ️ Serial request done: GET /v1/subscribers/$RCAnonymousID%3A348a78f9ea4543fb9dc62110489b1742/offerings, 0 requests left in the queue
DEBUG: ℹ️ GetCustomerInfoOperation: Started
DEBUG: ℹ️ There are no requests currently running, starting request GET /v1/subscribers/$RCAnonymousID%3A348a78f9ea4543fb9dc62110489b1742
DEBUG: ℹ️ API request started: GET '/v1/subscribers/$RCAnonymousID%3A348a78f9ea4543fb9dc62110489b1742'
DEBUG: 😻 Store products request received response
DEBUG: 😻 Store products request finished
DEBUG: 😻 Offerings updated from network.
DEBUG: 😻 Offerings updated from network.
DEBUG: ℹ️ This StoreProduct represents an SK1 product, the type of product cannot be determined, the value will be undefined. Use `StoreProduct.productCategory` instead.
DEBUG: ℹ️ This StoreProduct represents an SK1 product, the type of product cannot be determined, the value will be undefined. Use `StoreProduct.productCategory` instead.
DEBUG: ℹ️ This StoreProduct represents an SK1 product, the type of product cannot be determined, the value will be undefined. Use `StoreProduct.productCategory` instead.
DEBUG: ℹ️ This StoreProduct represents an SK1 product, the type of product cannot be determined, the value will be undefined. Use `StoreProduct.productCategory` instead.
[GET] - player/information
DEBUG: ℹ️ API request completed: GET '/v1/subscribers/$RCAnonymousID%3A348a78f9ea4543fb9dc62110489b1742' (304)
DEBUG: 😻 CustomerInfo updated from network.
DEBUG: ℹ️ GetCustomerInfoOperation: Finished
DEBUG: ℹ️ Serial request done: GET /v1/subscribers/$RCAnonymousID%3A348a78f9ea4543fb9dc62110489b1742, 0 requests left in the queue

PURCHASE PROCESS:

DEBUG: ℹ️ Vending Offerings from memory cache
INFO: 💰 Purchasing Product 'escape_single_2999' from package in Offering 'default'
DEBUG: ℹ️ Adding payment for product 'escape_single_2999'. 0 transactions already in the queue.
DEBUG: ℹ️ StoreKit1Wrapper (0x0000000300c8bc00) updatedTransaction: escape_single_2999 0
DEBUG: ℹ️ StoreKit1Wrapper (0x0000000300c8bc00) updatedTransaction: escape_single_2999 2000000587971827 1
DEBUG: ℹ️ Found 0 unsynced attributes for App User ID: $RCAnonymousID:348a78f9ea4543fb9dc62110489b1742
DEBUG: ℹ️ TransactionPoster: handling transaction '2000000587971827' for product 'escape_single_2999' (date: 2024-05-03 08:32:00 +0000) in Offering 'default'
DEBUG: ℹ️ Force refreshing the receipt to get latest transactions from Apple.
DEBUG: ℹ️ SKReceiptRefreshRequest started
<SKReceiptRefreshRequest: 0x3028e4fc0>: Finished refreshing receipt with error: Error Domain=ASDErrorDomain Code=603 "Request throttled" UserInfo={NSLocalizedDescription=Request throttled, NSLocalizedFailureReason=Unified receipt is valid and current}
DEBUG: ℹ️ SKReceiptRefreshRequest finished
DEBUG: ℹ️ Loaded receipt from url file:///private/var/mobile/Containers/Data/Application/E3E870D4-1A9B-4A54-A952-88752464018F/StoreKit/sandboxReceipt
DEBUG: ℹ️ Skipping products request for these products because they were already cached: ["escape_single_2999"]
DEBUG: ℹ️ PostReceiptDataOperation: Started
INFO: ℹ️ Parsing receipt
INFO: ℹ️ Receipt parsed successfully
DEBUG: ℹ️ PostReceiptDataOperation: Posting receipt (source: 'purchase') (note: the contents might not be up-to-date, but it will be refreshed with Apple's servers):
{"original_application_version":"1.0","opaque_value":"uz6Gg6brXC4RvVAksrm\/pg==","creation_date":"2024-05-03T08:32:00Z","environment":"ProductionSandbox","application_version":"46","sha1_hash":"ZUyNK3uM4FE2EubtE+WAgjN4KRU=","bundle_id":"app.bundle","in_app_purchases":[{"quantity":1,"product_type":1,"original_purchase_date":"2024-05-03T08:32:00Z","purchase_date":"2024-05-03T08:32:00Z","product_id":"escape_single_2999","is_in_trial_period":false,"original_transaction_id":"2000000587971827","web_order_line_item_id":0,"transaction_id":"2000000587971827"}]}
DEBUG: ℹ️ There are no requests currently running, starting request POST /v1/receipts
DEBUG: ℹ️ API request started: POST '/v1/receipts'
DEBUG: ℹ️ API request completed: POST '/v1/receipts' (200)
DEBUG: ℹ️ PostReceiptDataOperation: Finished
INFO: 💰 Finishing transaction '2000000587971827' for product 'escape_single_2999'
DEBUG: ℹ️ Serial request done: POST /v1/receipts, 0 requests left in the queue
DEBUG: ℹ️ StoreKit1Wrapper (0x0000000300c8bc00) removedTransaction: escape_single_2999 2000000587971827 1
DEBUG: ℹ️ Sending updated CustomerInfo to delegate.
DEBUG: ℹ️ Detected active subscriptions changed. Clearing trial or intro eligibility cache.
DEBUG: ℹ️ PurchasedProductsFetcher: invalidating cache
INFO: 😻💰 Purchased product - 'escape_single_2999'

RESTORE PROCESS:

DEBUG: ℹ️ Loaded receipt from url file:///private/var/mobile/Containers/Data/Application/E3E870D4-1A9B-4A54-A952-88752464018F/StoreKit/sandboxReceipt
INFO: ℹ️ Parsing receipt
INFO: ℹ️ Receipt parsed successfully
INFO: ℹ️ Parsing receipt
INFO: ℹ️ Receipt parsed successfully
DEBUG: ℹ️ PostReceiptDataOperation: Started
INFO: ℹ️ Parsing receipt
INFO: ℹ️ Receipt parsed successfully
DEBUG: ℹ️ PostReceiptDataOperation: Posting receipt (source: 'restore') (note: the contents might not be up-to-date, but it will be refreshed with Apple's servers):
{"application_version":"46","environment":"ProductionSandbox","sha1_hash":"ZUyNK3uM4FE2EubtE+WAgjN4KRU=","original_application_version":"1.0","in_app_purchases":[{"web_order_line_item_id":0,"transaction_id":"2000000587971827","quantity":1,"is_in_trial_period":false,"product_type":1,"original_transaction_id":"2000000587971827","original_purchase_date":"2024-05-03T08:32:00Z","product_id":"escape_single_2999","purchase_date":"2024-05-03T08:32:00Z"}],"opaque_value":"uz6Gg6brXC4RvVAksrm\/pg==","creation_date":"2024-05-03T08:32:00Z","bundle_id":"app.bundle"}
DEBUG: ℹ️ There are no requests currently running, starting request POST /v1/receipts
DEBUG: ℹ️ API request started: POST '/v1/receipts'
DEBUG: ℹ️ API request completed: POST '/v1/receipts' (200)
DEBUG: ℹ️ PostReceiptDataOperation: Finished
DEBUG: ℹ️ Serial request done: POST /v1/receipts, 0 requests left in the queue

@WesleyClarkRC
Copy link

Hi @TobiDevloft, I apologize for the delay. Thank you for the debug logs. This difference in what is returned is actually a result of whether the transaction ID is returned from the device or through our API. From the device, it will be the one provided by the store, while through our API, it will be the hashed version of that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants