Apple payment receipts without the "in_app" field.

In rare cases, i saw that apple payment receipts without the "in_app" field.

There is a few questions about this.


1. In Apple's In-App Purchase FAQ, when an empty "in_app" field, guiding that you should use the SKReceiptRefreshRequest class to update the receipt.

then In my app(not server), how to i check "in_app" array is empty or not?


2. if i use the SKReceiptRefreshRequest class to update the receipt and the "in_app" array is empty,

i need to be considered a hack?


3. why is the payment receipt verification successful in App when "in_app" array is empty?


4. Apple's In-App Purchase FAQ say that an empty in_app array indicates that StoreKit has not recorded any transactions for that user yet. It may be that the application receipt has not yet been updated.

could i know how to "in_app" array be empty step?


help plz.


https://developer.apple.com/library/content/technotes/tn2413/_index.html#//apple_ref/doc/uid/DTS40016228-CH1-RECEIPT-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_

Accepted Reply

There's not much that app can do in the case that the in_app array is empty.


One verified reason for this issue occurring - the in-app purchase app is run on a jailbroken device - where the addPayment call is intercepted and the updatedTransaction delegate method is called back immediately with a state of SKPaymentTransactionStatePurchased. Since the applicationReceipt cannot be updated as it is cryptographically signed by Apple, the applicationReceipt is left as is - often in the same state it was installed with by the iTunes Store server - with an empty in_app array. The applicationReceipt can be validated which presents one case for the finding many of you report.


The presence of an empty in_app array indicates that the iTunes Store has not recorded an in-app purchase for the iTunes user account and application. When the app process validates the applicationReceipt and the in_app array is empty the application must not call finishTransaction, Doing so indicates that the application has validated the successful transaction indication. When the in_app array is empty, there is no indication that a purchase has taken place. In such case, the user is advised to contact Apple Care. the Apple Care representative can verify that a charge was made to the iTunes user account. They will also be able to tell that the application did not call finishTransaction.


I see this issue reported by developers to DTS. In some cases, there is the response that the typical customer would not be running the iAP app on a jailbroken device. My only suggestion is - submit a bug report to be investigated by the iTunes Store Server Engineers. The contents of the applicationReceipt are under the control of the iTunes Store Server. When a buy request is made and the transaction is successful, the applicationReceipt and the successful transaction notice are passed to the application in the same payload. The applicationReceipt is updated then the updatedTransaction delegate method is called with the state - SKPaymentTransactionStatePurchased. If the applicationReceipt's in_app array is empty, and assuming that the device is not jailbroken, then either the in_app array was empty when the receipt was returned to the app, or iOS did not update the receipt on the successful transaction. Either case or any other possibility is a bug report.


To submit a bug report, I suggest that you include the following information.

1. the application ID

2. the base64 encoded applicationReceipt such that anyone could use the curl command to send the receipt contents to the iTunes Store verifyReceipt server manually and see the validated contents.


I use -

user$ curl -d '{ "password":"yyyy" "receipt-data": "xxxx"}' https://buy.itunes.apple.com/verifyReceipt


where yyyy - is the shared secret - only needed if there is an auto-renewing subscription in-app purchase item in the receipt.


otherwise, one can use the command


user$ curl -d '{ "receipt-data": "xxxx"}' https://buy.itunes.apple.com/verifyReceipt


3. include the transactionID value in the bug report


4. Ideally it would help if you could include the iTunes User account name in the bug report associated with the purchase resulting in the applicationReceipt with the empty in_app array.


I would also file separate bug reports for each applicationReceipt which exhibits this behavior.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Replies

>1.you should use the SKReceiptRefreshRequest class to update the receipt.

This is not necessary if you are responding to a call to updatedTransactions. The receipt is refreshed before StoreKit calls updatedTransactions.


>then In my app(not server), how to i check "in_app" array is empty or not?

You decode the rceeipt using OpenSSL as described here:

https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateLocally.html#//apple_ref/doc/uid/TP40010573-CH1-SW2


>the "in_app" array is empty,....a hack?

yes.


>why is the payment receipt verification successful in App when "in_app" array is empty?

Because the receipt is a valid receipt indicating that no IAPs were purchased.


>....an empty in_app array indicates that StoreKit has not recorded any transactions for that user yet. It may be that the application receipt has not yet been updated. could i know how to "in_app" array be empty step? (What?????)

again - the receipt is updated before StoreKit calls updatedTransactions. But the app needs to call restoreCompletedTransactions or refereshReceipt to get an uodated receipt for that device. For example - if you purchase an autorenewable subscription from device A and then load the app into device B and referesh receipt on device B and then wait 6 months, device B will not get any notice of any new subscriptions purchased by that user. Device B must either restoreCompletedTransactions or referesh receuipt to get an updated receipt.


This also happening to us. Our code responding to updatedTransactions call. But in some cases, receipt with empty in_app array sending to our server. Users said they've charged the money.

We also have retry function that If there is an empty in_app array in the receipt, our code refreshes the receipt. But its no help. Still getting an empty in_app array. I think it is a bug from Apple.

We were not getting empty in_app array until this February. But now, receipts with empty in_app array sending to our server every day. In our case, It is not hacking. Our users sending their itunes purchase history to us and they've really charged money. but not getting coins because of empy in_app array o.0..........

>I think it is a bug from Apple.


I agree.


Be sure to file one, link below right, and add your report # here for reference if you can, thanks.

We are also encountering this problem with our production app in the Mac App Store but only under mac OS 10.12. Has anyone found a solution to this yet?

Hello PBK.

I have a question. Is there any possibility to have in_app array update delayed when updatedTransaction call? If it is possible, Can we update the receipt using SKReceiptRefreshRequest to get a receipt with in_app array?

Thanks

>Is there any possibility to have in_app array update delayed when updatedTransaction call?


I have never seen a delay.


>Can we update the receipt using SKReceiptRefreshRequest to get a receipt with in_app array?


Yes. But I have never seen a case where such an update is necessary if updatedTransactions was called. Calling refresh receipt will require that the user log in to iTunes so don't do it without a request from the user.

We are experiencing the same problem.

Some macOS Sierra users are sending receipts with empty in_app field. Refreshing the receipt doesnt help.

There's not much that app can do in the case that the in_app array is empty.


One verified reason for this issue occurring - the in-app purchase app is run on a jailbroken device - where the addPayment call is intercepted and the updatedTransaction delegate method is called back immediately with a state of SKPaymentTransactionStatePurchased. Since the applicationReceipt cannot be updated as it is cryptographically signed by Apple, the applicationReceipt is left as is - often in the same state it was installed with by the iTunes Store server - with an empty in_app array. The applicationReceipt can be validated which presents one case for the finding many of you report.


The presence of an empty in_app array indicates that the iTunes Store has not recorded an in-app purchase for the iTunes user account and application. When the app process validates the applicationReceipt and the in_app array is empty the application must not call finishTransaction, Doing so indicates that the application has validated the successful transaction indication. When the in_app array is empty, there is no indication that a purchase has taken place. In such case, the user is advised to contact Apple Care. the Apple Care representative can verify that a charge was made to the iTunes user account. They will also be able to tell that the application did not call finishTransaction.


I see this issue reported by developers to DTS. In some cases, there is the response that the typical customer would not be running the iAP app on a jailbroken device. My only suggestion is - submit a bug report to be investigated by the iTunes Store Server Engineers. The contents of the applicationReceipt are under the control of the iTunes Store Server. When a buy request is made and the transaction is successful, the applicationReceipt and the successful transaction notice are passed to the application in the same payload. The applicationReceipt is updated then the updatedTransaction delegate method is called with the state - SKPaymentTransactionStatePurchased. If the applicationReceipt's in_app array is empty, and assuming that the device is not jailbroken, then either the in_app array was empty when the receipt was returned to the app, or iOS did not update the receipt on the successful transaction. Either case or any other possibility is a bug report.


To submit a bug report, I suggest that you include the following information.

1. the application ID

2. the base64 encoded applicationReceipt such that anyone could use the curl command to send the receipt contents to the iTunes Store verifyReceipt server manually and see the validated contents.


I use -

user$ curl -d '{ "password":"yyyy" "receipt-data": "xxxx"}' https://buy.itunes.apple.com/verifyReceipt


where yyyy - is the shared secret - only needed if there is an auto-renewing subscription in-app purchase item in the receipt.


otherwise, one can use the command


user$ curl -d '{ "receipt-data": "xxxx"}' https://buy.itunes.apple.com/verifyReceipt


3. include the transactionID value in the bug report


4. Ideally it would help if you could include the iTunes User account name in the bug report associated with the purchase resulting in the applicationReceipt with the empty in_app array.


I would also file separate bug reports for each applicationReceipt which exhibits this behavior.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

I've filed the bug here: https://bugreport.apple.com/web/?problemID=32948893

Hope it will help, cause it is already 10.12.5 (16F73) but the problem is still here. From October 2016.