Post

Replies

Boosts

Views

Activity

Reply to missing unified_receipt in server notifications
Hello, @crauss77. Have you been able to find any users whose subscriptions are being affected by this problem? Because it could serve as an additional piece of information for Apple to use when investigating the problem. And if you have stored the "latest_receipt" of any of their purchases, you could call the verifyReceipt URL to see if, at least, the purchase information that does not arrive as a notification is correctly registered with Apple.
Jul ’21
Reply to original_purchase_date posterior to purchase_date ?
This is the answer I've got today (20210621) from Feedback Assistant: Apple - Jun 21, 2021 at 2:23 PM Engineering has provided the following information regarding this issue: In sandbox, such issues can happen if the purchase was made on or before 2018 as transactions created in or before 2018 were deleted. So, the original transaction data was not available and we use the date of the restored transaction as a fallback. This shouldn't happen in production. Kind regards, Oscar
Jun ’21
Reply to App Store Server Notifications Pass-Through Custom Variables
@KPsingh, you can read my answers in thread https://developer.apple.com/forums/thread/681607 A summary: In our case, when the user makes a purchase in the app, we send the userID, and the original_transaction_id, the purchased product to a URL in our backend server, and register that information in the database (using the original transaction_id as the database primary key). When we receive notifications, using the auto_renew_product_id and the unified_receipt.pending_renewal_info we get the original_transaction_id afected in the notification. That original_transaction_id will be used to query the database, and get the userID related to that purchase.
Jun ’21
Reply to Passing the User ID between an iOS app and Rails backend for In-App Purchases
Hello, @noddam. In our case, we have to create a external subscription in other system that we have to bind to the one purchased in Apple. And to do that binding we need the userID in that external system, so we have to store the userID (that the app sends us when the user buys the subscription in the app). When you receive notifications from Apple you don't have any information about the user. Allyou can use is the original_transaction_id, because that data is a common field that let you relate all the purchased derived from the "first" purchase notified by INITIAL_BUY. Remember that after a subscription has expired, the user will be able to renew it from outside the app (during the purchase tests in the Sandbox, in iOS 14, it is under Settings->App Store (I have a Spanish version iOS, so I don't know the exact name, but the translation would be something like "Test environment account), so you should have a field in your database that let you bind an original_transaction_id with an user when you receive a notification. Check my answer in thread https://developer.apple.com/forums/thread/680581 so you can see the suggested source code sample to get a summary of the subscription state. In our case, when the user makes a purchase in the app, we send the userID, and the original_transaction_id, the purchased product to a URL in our backend server, and register that information in the database (using the original transaction_id as the database primary key). When we receive notifications, using the auto_renew_product_id and the unified_receipt.pending_renewal_info we get the original_transaction_id afected in the notification. That original_transaction_id will be used to query the database, and get the userID related to that purchase. Kind regards, Oscar
Jun ’21
Reply to Apple Subscription Renewal(Server to Server Notification)
I always see a different latest_receipt value. If you use the latest_receipt_info info, you can use even an old latest_receipt value to call verifyReceipt URL and you'll get all the purchases. But if you use the field in_app (it seems that it is better to use the latest_receipt_info), you won't receive the last purchases if you use a old value of latest_receipt. When you call verifyReceipt, the response included in the in_app field seem to be the decoded value of the information stored in the latest_receipt. So, if you send an old value, you'll get a decoded value of old purchases. But in the latest_receipt_info you'll have all the purchases (well, the last hundred).
Jun ’21
Reply to App Store server notification for testing purposes?
Hello, @houmie. In my previous message I forgot to mention that in the source code (the example is based in NodeJS) you can see how to connect with the verifyReceipt URL if you need to validate the contents of a received notification. The code manages automatically the sandbox or production environment: it calls to the production URL, and if the response says that the receipt is for sandbox, it will call to the sandbox verifyReceipt URL. It is interesting to analyze the actions of the processReceiptJSON function, and the auxiliary ones used by processReceiptJSON. Kind regards, Oscar
Jun ’21
Reply to App Store server notification for testing purposes?
Hello, @houmie In order to manage server-to-server notifications I suggest you visit the following URL: https://developer.apple.com/videos/play/wwdc2020/10671 and to download the code in resource "Determining Service Entitlement on the Server", in URL https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/determining_service_entitlement_on_the_server Analyzing the code you can get an idea of how you can get a summary of the history of the purchases, and get the latest state of the last one hundred of purchased subscription. Kind regards, Oscar
Jun ’21
Reply to App Store Sandbox and/or Server Notifications down ?
Hello. This also happens to me. I detected it yesterday. Initially I thought I might have a problem with the app after making some changes to it, but I did a subscription renewal using the native test subscriptions interface in IOS 14 (in Settings - App Store) and I wasn't getting notifications either. When I went back to look at the logs, I saw that they were about 4 or 5 hours late. I made other purchases though, and nothing has arrived even though it's been over 8 hours. While waiting for the notifications to arrive, I tested by calling the verifyReceipt URL (using a "latest_receipt" that I had saved from a previous notification), and in the response the new purchases did appear, although they appeared in a state EXPIRED_BUT_IN_RETRY_PERIOD. And in that state they have remained. This JSON corresponds to the output of processing the verifyReceipt response with a modified version of the processReceiptJSON() function available in the code example that you can download from the URL https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/determining_service_entitlement_on_the_server This URL corresponds to one of the resource links available in the article Architecting for subscriptions - https://developer.apple.com/videos/play/wwdc2020/10671 Specifically, to Determining Service Entitlement on the Server - https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/determining_service_entitlement_on_the_server. (I recommend that you download the example to see how you can obtain a summary of the information obtained from the verifyReceipt queries, although it could also be applied to a notification) I have modified the code of the example so that besides showing the numerical values, it shows me an explanatory text that shows in a simple way to which state the numerical value corresponds (I have also modified the text strings that come in the example, to make them more intelligible). json { "subscriptions" : [ { "product_id" : "IDPPAR0001", "entitlementCode" : -1, "expiration" : 1621518754000, "entitlementMainStateDescription" : "EXPIRED_BUT_IN_RETRY_PERIOD", "expirationAsISOString" : "2021-05-20T13:52:34.000Z", "entitlementSubstateDescription" : "STANDARD_SUBSCRIPTION", "web_order_line_item_id" : "10000000xxxxxxxx", "transaction_id" : "10000000xxxxxxxx", "totalRenewals" : 12, "groupID" : "20xxxxxx", "originalTransactions" : [ { "originalTX" : "10000000xxxxxxxx", "start" : 1600943224000, "startAsISOString" : "2020-09-24T10:27:04.000Z", "expiration" : 1621518754000, "expirationAsISOString" : "2021-05-20T13:52:34.000Z", "renewals" : 12 } ] }, { "product_id" : "IDPPAR00000001BR", "entitlementCode" : -1, "expiration" : 1621515085000, "entitlementMainStateDescription" : "EXPIRED_BUT_IN_RETRY_PERIOD", "expirationAsISOString" : "2021-05-20T12:51:25.000Z", "entitlementSubstateDescription" : "STANDARD_SUBSCRIPTION", "web_order_line_item_id" : "10000000xxxxxxxx", "transaction_id" : "10000000xxxxxxxx", "totalRenewals" : 17, "groupID" : "20xxxxxx", "originalTransactions" : [ { "originalTX" : "10000000xxxxxxxx", "start" : 1614640470000, "startAsISOString" : "2021-03-01T23:14:30.000Z", "expiration" : 1621515085000, "expirationAsISOString" : "2021-05-20T12:51:25.000Z", "renewals" : 17 } ] }, { "product_id" : "IDPPARES0001", "entitlementCode" : -5, "expiration" : 1620837172000, "entitlementMainStateDescription" : "USER_LET_EXPIRE_VOLUNTARILY", "expirationAsISOString" : "2021-05-12T16:32:52.000Z", "entitlementSubstateDescription" : "STANDARD_SUBSCRIPTION", "web_order_line_item_id" : "10000000xxxxxxxx", "transaction_id" : "10000000xxxxxxxx", "totalRenewals" : 56, "groupID" : "20577648", "originalTransactions" : [ { "originalTX" : "10000000xxxxxxxx", "start" : 1614640470000, "startAsISOString" : "2021-03-01T23:14:30.000Z", "expiration" : 1620837172000, "expirationAsISOString" : "2021-05-12T16:32:52.000Z", "renewals" : 56 } ] }, ], "trialConsumedForGroup" : [] } Until these problems occurred yesterday, the final status of the sandbox subscriptions I had seen was always USER_LET_EXPIRE_VOLUNTARILY. But the ones purchased yesterday, stay in the EXPIRED_BUT_IN_RETRY_PERIOD state.
May ’21
Reply to Testing subscriptions upgrade/downgrade on sandbox
If all you want is the same level of access (same contents) but for a different length of time, you should create subscriptions within the same group, indicating a lower numerical level to the subscription with the longest duration (it appears higher up in the web interface showing the subscriptions of a group). In reality, this change operation does not correspond to an upgrade/downgrade, but to a crossgrade. When you create products in two different groups you are implicitly indicating that you allow the user to have simultaneous subscriptions. You can read: https://developer.apple.com/app-store/subscriptions/ You can join the next lines to recreate a valid URL (the system doesn't let me put external URLs) a see additional information: https:// qonversion.io/blog/ios-subscription-upgrades-downgrades-and-service-levels/ Or this one: https:// discourse.world/h/2019/11/14/Auto-renewable-subscription-levels-in-iOS-app Or this: https://www. revenuecat.com/blog/ios-subscription-groups-explained
May ’21