Local receipt doesn't get updated after (automatically) renewing a subscription - macos

I have an app that uses in-app purchases (IAP), specifically auto-renewable subscriptions.
Occasionally it seems that, when a subscription automatically get renewed, the local receipt doesn't get updated automatically. As a result, checking locally if an active subscription is available results false. Performing the same validation remotely (using Apple servers) returns true.
How and when is the local stored receipt updated or is this something that can only be triggered manually? If so, does this need to happen using SKReceiptRefreshRequest or SKPaymentQueue's restoreCompletedTransactions? Based on Apple's documentation the former seems to be the way to go:
A request to refresh the receipt, which represents the user's transactions with your app.
Unfortunately, this fails, perhaps because it thinks there's noting to update? However there is: as the local receipt is outdated as it doesn't contain the renewed subscription status.
I want to ensure I'm doing things correctly and this behavior (that again happens occasionally) is not something on Apple's end.
Thanks for any feedback.

Related

Android Google Play Subscription gets canceled after buying it

I have a react native app and using react-native-iap library to communicate with Apple/Google server to buy the subscriptions. The subscription got successful and it returns a transaction as well but when I try to use that receipt to validate in in-app-purchase library, it returns with cancelReason: 1. I don't know what's happening but as per the Google Play cancelReason:1 means, "Subscription was canceled by the system, for example because of a billing problem"
Below is the real purchase I tried with my app. I have added the amount to buy it from the prod app which uploaded on internal testing. This library isn't able to verify it. Even it's showing me as an active subscription on the Play store app in Manage Subscription.
If I try to restore purchase in my app, it would return a purchase but when I went to verify it from the in-app-purchase library, it doesn't validate. Don't know why.
Here is the receipt data I got from the react-native-iap library.
{"purchaseToken":"sdfdsfssfsd.AE-Jw-8fCifXt8xC1LzUDMhl2EyupYjgdGjmkpdHZH-j3-0YWE4UGa_jFlKTwodhLbKXCIWg","productId":"com.xyz.subscription","acknowledged":true,"orderId":"GPA.31-25-01-22058","purchaseTime":1620884406333,"packageName":"com.xyz","purchaseState":0,"autoRenewing":true,"subscription":true}
The response I got from the in-app-purchase library -
{"service":"google","status":0,"packageName":"com.xyz","productId":"com.xyz.subscription","purchaseToken":"sdfdsfssfsd.AE-Jw-8fCifXt8xC1LzUDMhl2EyupYjgdGjmkpdHZH-j3-0YWE4UGa_jFlKTwodhLbKXCIWg","startTimeMillis":"1620884406333","expiryTimeMillis":"1623562757349","autoRenewing":false,"priceCurrencyCode":"INR","priceAmountMicros":"79000000","countryCode":"IN","developerPayload":"","paymentState":1,"cancelReason":1,"orderId":"GPA.31-25-01-22058","acknowledgementState":1,"kind":"androidpublisher#subscriptionPurchase"}
if it got canceled as per the response, I didn't get any refund in my account.
Please help :(

Microsoft Teams bots can only update the last two posts in a conversation. Is that by design?

Summary
I am using the Bot Framework REST API to create and update Microsoft Teams posts.
I have found that I can only update the last two posts of a conversation, but cannot find documentation that describes this restriction.
It is not possible to identify the failed updates from the API response, as the HTTP response code and body is always the same, regardless of whether the update works or not (200 with the id of the "updated" activity). I would expect the response to indicate the failure, and so this appears to be a Teams bug.
Detail
I can create conversations and create replies to conversations using the Bot Framework REST API without issue (using the create conversation and send to conversation endpoints). My problem arises if I try to update these messages.
Given a conversation that looks like this:
parent_message
|_ child_message_1
|_ child_message_2
|_ child_message_3
If I attempt to use the update activty endpoint to update each one of these messages, I observe that:
I can always update parent_message.
I can update child_message_3 and child_message_2, but not child_message_1. In each case the HTTP response is a successful HTTP response (200 response code, with a JSON body that contains the id of the updated message), regardless of whether the update succeeds or not.
If I add another message, child_message_4, then this will be updatable, but child_message_2 will no longer be updatable. I assume this is because now child_message_2 is no longer one of the last two messages.
I see the same behavior if another user adds messages to the conversation, ie. if a user were to make two posts to the conversation I would no longer be able to update any of my own child messages as they are no longer one of the last two messages.
My questions are:
Does anyone know if this restriction is by design? If so, can you point to some documentation on this?
Is it possible to determine when an update fails? As mentioned, the HTTP response always reports success so I'm unable to find a way to do this. Is this a bug in Teams?
Thanks for reporting this. We are able to repro this at our end and we are tracking it here: MicrosoftDocs/msteams-docs#2011
Please follow this issue for updates/progress/questions.
Updates: This is fixed.
This appears to be a bug, but I think the bug is different from what you think it is. Go ahead and "refresh" the conversation and you should see the updates in effect. If you're using the web app then you can refresh the page, but since you're probably using the desktop or mobile app then you could try switching to another conversation and back, or you might have to sign out and sign in again.

Consumable in app purchases validation

We recently launched the app which has only consumable in-app purchases. We noticed lot of fake purchases - purchases with invalid receipts and also 'valid' receipts but the "in_app" array in the validation response from apple is empty array. I need to know how users are forming such a 'valid' receipts ? Is it the receipt of the app download and not of in-app purchase or what ? I am now putting the following check for validation. Extract "in_app" field in json response from Apple and if it is non-empty, then check the product_id matches or not. I need to know if this check is enough or their is a better fool proof check.
All apps have a receipt. Those apps that have purchased an IAP have an in_app field in their receipt. Your users are pushing a fake call into their updatedTransaction method and you are grabbing their receipt (sans IAP cause they made no purchase)and sending it to your server. Other users might swap some receipt from somewhere (e.g. one of 30 thieves makes a purchase and extracts that valid receipt and sends it to their 29 co-thieves). If they stick that receipt into their device and then push a call to updatedTransactions then your server will get their now-valid-but-duplicate receipt. Your server needs to check *** the date of the receipt and discover it is older than recent or, even better, older than the paymentRequest which you would need to co-send to your server. (it is better to decode on the device - much more secure)
*** you used to be able to check transaction_id for a duplicate transaction_id. Unfortunately you can no longer do that since a restoreCompletedTransaction returns the same transaction_id as the original purchase. I have told Apple about that and they ignored me.
Refer to this In-App Purchase FAQ My app validates its receipt with the App Store via paymentQueue:updatedTransactions: after a successful purchase. However, the returned receipt contains an empty in_app array rather than the expected products.
An empty in_app array indicates that the App Store has not recorded
any transactions for the user yet. It may be that the application
receipt has not yet been updated. When this happens, your app can
inform the user that the receipt does not appear current and ask
whether to refresh it.
Information about consumable products is added to the receipt when
they are paid for and remains in the receipt until you finish the
transaction. After you finish the transaction, this information is
removed the next time the receipt is updated. Thus resulting into an
empty in_app array if your app only sells consumable products.

Server side receipt validation for non-consumable products in iOS7 and transactionReceipt deprecation

I'm porting a working application from previous iOS's and am having trouble with the new in app purchase receipts.
The way we work now is to take the transactionReceipt property from the SKPaymentTransaction object and send it to the server for validation.
From what I could gather from other questions, it seems that the receipt is now held in one place, being :
[[NSBundle mainBundle] appStoreReceiptURL];
There are a few things I don't understand here :
Is there now one receipt for all of the purchased products?
If so, does this file grow and grow and grow?
If I want to send single receipts for single products to the server, how can I?
Is the only way to send the full file to the server all the time?
Very confused by this, any help would be greatly appreciated.
From what I've been able to gather via Apple's documentation.
1) There is one receipt for all purchased products. In order to perform server side validation you send the entire receipt to your server, which forwards it to Apple for verification. See this post on the Apple Developer Forums (starting around comment 13) https://devforums.apple.com/thread/193893?tstart=0
2) Non-consumables will remain in the receipt forever, so yes it will grow and grow. Consumables are removed lazily from the receipt once finished via a call to finishTransaction. See https://devforums.apple.com/message/876265#876265
3) The iOS6 way of looping through updatedTransactions and sending individual receipts to your server for validation seems at odds with the new iOS7 design. This post on the Apple Developer forums suggests you "Send the whole list of transactions to your server with the receipt. When the receipt is verified, deliver all of the products, and finish all of the transactions." https://devforums.apple.com/message/897870#897870
4) That really does seem to be the case.
If you believe the iOS7 documentation is lacking you can raise a bug report with Apple

In-App Billing subscription issues

With the release of the new subscription option from In-App Billing API we started a proof of concept of the service and we found a few issues. Has anyone else tried it and would have some answers for us? Here's the issues we have been facing so far:
1 – While testing the unsubscribe functionality, the Google Play interface displays a white page with an “Item not found” message and a retry button. Is it due to the fact the app is not yet published? If yes, how can we test this flow without publishing it first?
2 – Inter device synchronization. When making a subscription on one device, other devices tied to the same account did not receive a OnPurchaseStateChange event. Is it again due to the fact the app is not published? Or are subscriptions tied to a particular device and not to an account?
3 – On our Google merchant page, when we cancel a purchase, the device does not receive a notification telling the subscription has been cancelled. Is this a bug? As a workaround we are manually checking the current time and comparing with the expiration date to force a restore transactions call. At this point, we are able to see the subscription is no longer valid. Do you think this is an acceptable solution?
4 – When a subscription is made, two transactions show up on the Google Merchant page: a FAILED transaction with a value of $0 and a valid one with the value we charged. Is this the expected behavior? What’s the purpose of the $0 FAILED transaction?
If anyone has faced similar issues we would like to know. Maybe these could be bugs on Google's end or maybe we did not understand 100% how it is supposed to work.
Thanks in advance.
1.I had the same issue and after I published (and later unpublished) my app I could see the app page in the market,so you can publish and than unpublish.
2.I didn't check it with subscriptions ,but for managed item i didn't get purchaseStateChange on two different devices as expected.
3.I do get subscription expired after canceling one,but only after a while.
I didn't understood how you can get the expiration date ?
you only can get it with access to play developer api.
the restore transactions will give you same purchaseStateChange as you got when purchase the item.
*in the developer guide it is recommanded to use restore transactions only in first app use.
4.I have same issue,and i heard at least about 10 people with same 0$ charge.

Resources