Post

Replies

Boosts

Views

Activity

Reply to When does Apple send the "INTERACTIVE_RENEWAL" Subscription Notification?
Rich, is it possible that INTERACTIVE_RENEWAL is sent when the change in the subscription is to be applied instantly, and that DID_CHANGE_RENEWAL_PREF is sent when the change is to be made at the end of the current subscription? Perhaps these article in RevenueCat.com can be relevant (you'll have to reconstruct the URLs from fragments, that I can't post it in the right way): https:// www. revenuecat.com/blog/ios-subscription-groups-explained https:// www. revenuecat.com/blog/apple-subscription-notifications-are-almost-useless
Topic: App & System Services SubTopic: StoreKit Tags:
Apr ’21
Reply to How to link Apple in-app subscription to company account
If you want that one user only have one account in ACME, you can detect that the original_transaction_id is being used by another account, and inform the user that he has another account. If you decide to allow a user have different accounts in ACME, then that shouldn't be a problem because the user is the same with two accounts. If the user is the same, it shouldn't matter what account he used to log in. To share subscription between members of a family, Apple has now Family Sharing: https://developer.apple.com/documentation/appstoreservernotifications/notification_type#3733656
Apr ’21
Reply to How to identify users that resubscribe to an expired subscription
If the user reactivates a subscription, you'll receive a notification with the same original_transaction_id, that you should have store in your database related to the user that make the initial purchase using the app. It the last subscrition happened long time ago, and the user reactivates his subscription from outside the app, I think it is posible that you receive a INITIAL_BUY notification, with a different initial_transaction_id, that you don't have in the database, so you don't know the user that made the purchase. You should tell the user to launch the app, where it should obtain the receipt, the original transaction_id and the user ID, and send it to he server. That way you can add the user ID to the database record that matches the original_transaction_id. You can see videos from wwdc2020, wwdc2019 y wwdc2018 related to server to server notifications: https://developer.apple.com/videos/play/wwdc2020/10661/?time=654 See Resources to find more information
Topic: App & System Services SubTopic: StoreKit Tags:
Apr ’21
Reply to Subscriptions - Missing App Store Server Notifications
In the transcript of the video https://developer.apple.com/videos/play/wwdc2020/10661/ you can find that after a successfull auto-renew you will receive DIR_RENEW You mention a RENEWED notification, but it doesn't exist (it never existed). The one that existed, and it is deprecated is RENEWAL. But RENEWAL was a very bad name, because it true meaning was "There were failures when Apple tried to collect, but in the end it was able to do so". Now the have a better name: DID_RECOVER. In https://developer.apple.com/documentation/appstoreservernotifications/notification_type#discussion you can see it: RENEWAL (DEPRECATED IN SANDBOX) Indicates a successful automatic renewal of an expired subscription that failed to renew in the past. Check expires_date to determine the next renewal date and time. This notification is deprecated in the sandbox environment, and scheduled for deprecation in production in March 2021. Update your existing code to rely on DID_RECOVER notification type instead.
Topic: App & System Services SubTopic: StoreKit Tags:
Apr ’21
Reply to How to recognize whether CANCEL notification means "cancel" or "upgrade"
If you check the documentation today (20210426) you'll see that now there is no CANCEL notification after an upgrade: CANCEL Indicates that Apple Support canceled the auto-renewable subscription and the customer received a refund as of the timestamp in cancellation_date_ms. Subscription is active; customer upgraded to another SKU: DID_CHANGE_RENEWAL_STATUS, INTERACTIVE_RENEWAL
Apr ’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
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.
Topic: App & System Services SubTopic: StoreKit Tags:
May ’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 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 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).
Topic: App & System Services SubTopic: StoreKit Tags:
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
Topic: App & System Services SubTopic: StoreKit Tags:
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.
Topic: App & System Services SubTopic: StoreKit Tags:
Jun ’21