react-native-iap icon indicating copy to clipboard operation
react-native-iap copied to clipboard

Getting 21002 from Apple when verifying transactionReceipt

Open AaronCCWong opened this issue 1 year ago • 15 comments

Please use the Discussion board if you want to get some help. Please use issues to report bugs.

Description

Getting { 'status': 21002 } responses when calling /verifyReceipt with transactionReceipt.

Expected Behavior

/verifyReceipt should work.

Environment:

  • react-native-iap: 12.10.5
  • react-native: 0.71.7
  • Platforms (iOS, Android, emulator, simulator, device): iOS

To Reproduce Steps to reproduce the behavior:

The sequence flow I use is as follows:

  1. requestSubscription on button click
  2. purchaseUpdatedListener gets triggered with a purchase object
  3. I call validateReceipt which is a method that sends the following to my web server:
{
        receipt: purchase.transactionReceipt,
        platform: Platform.OS,
        subscriptionId: purchase.productId,
        token: purchase.purchaseToken
}
  1. My web server makes a call to /verifyReceipt with the following request body:
{
    "receipt-data": transactionReceipt,
      "password": SECRET
      "exclude-old-transactions": true,
}
  1. Apple responds with { "status": 21002 }.

This worked until recently when I upgraded expo, react native and react-native-iap.

AaronCCWong avatar May 14 '23 02:05 AaronCCWong

same problem here @andresesfm

midhunevolvier avatar May 19 '23 04:05 midhunevolvier

Check the receipt is properly encoder in base 64

andresesfm avatar May 19 '23 14:05 andresesfm

This is a value that is returned through this library. That is, we get it from the purchase parameter of purchaseUpdateListener. If that returns a string that isn't properly base64 encoded, is there anything we can do on our end to make sure that it is?

AaronCCWong avatar May 20 '23 19:05 AaronCCWong

@andresesfm Experiencing this same issue. The value in currentPurchase.transactionReceipt is malformed. We are receiving this value from the library itself, so it should be in proper Base64 format.

I am currently using requestSubscription and then using currentPurchase to send a validation request to my apple sandbox /verifyRequest using transactionReceipt. My subscription plans are loaded from Storekit config.

nightmre789 avatar May 22 '23 13:05 nightmre789

Look at ios/RNIapIos.swift:322. It is bein encoded there using base64EncodedString. Maybe play around with removing/changing the options argument

andresesfm avatar May 23 '23 17:05 andresesfm

Having the same issue. Value returned by this library and passed on to Apple as-is in the backend.

numsu avatar May 27 '23 10:05 numsu

Does anyone have the solution? I am stuck.

midhunevolvier avatar May 29 '23 07:05 midhunevolvier

I decided to change my implementation because of this. Now I am sending the appAccountToken which contains an uuid of the purchase to Apple and verifying that the purchase is successful by verifying that in the S2S payload. Not handling receipts at all.

numsu avatar May 29 '23 07:05 numsu

This is also happening to me, has anyone gotten a solution? @numsu do you have any details on how you were able to get that information?

ToyboxZach avatar Aug 16 '23 23:08 ToyboxZach

This is also happening to me, has anyone gotten a solution? @numsu do you have any details on how you were able to get that information?

  1. Generate an unique identifier on the client or your backend server once the user presses the "Buy" button and store it to your DB
  2. Set the generated identifier to the appAuthToken field with this library
  3. If the user completed the purchase, you will receive a S2S notification from Apple, if you have set it up. The payload will include your appAuthToken. Set the status of the purchase based on this notification

numsu avatar Aug 17 '23 04:08 numsu

I was also facing the issue earlier but it was solved by making some changes to the way I was passing the parameter to the validateReceiptIos. before I was passing it as "RNIap.validateReceiptIos(receiptBody, true)". but now I have made the changes and called it like this "RNIap.validateReceiptIos({receiptBody: receiptBody, isTest: true})" and It started working properly .

MTPL0005-AbhishekDube avatar Aug 24 '23 10:08 MTPL0005-AbhishekDube

This is also happening to me, has anyone gotten a solution? @numsu do you have any details on how you were able to get that information?

1. Generate an unique identifier on the client or your backend server once the user presses the "Buy" button and store it to your DB

2. Set the generated identifier to the appAuthToken field with this library

3. If the user completed the purchase, you will receive a S2S notification from Apple, if you have set it up. The payload will include your appAuthToken. Set the status of the purchase based on this notification

Sorry to bother @numsu but I cannot seem to get Apple Store Server Notifications. The server url never gets called, the setup is alright as i used the test endpoint and the notification arrived properly Do you have any idea what I'm doing wrong?

Fairbrook avatar Aug 30 '23 03:08 Fairbrook

confirm the same issue "react-native-iap": "^12.12.2",

tony95271 avatar Feb 20 '24 15:02 tony95271

confirm the same issue "react-native-iap": "^12.13.0",

hotaryuzaki avatar Mar 26 '24 04:03 hotaryuzaki

i think one of the reasons this issue is rising is because the docs are not giving the right suggestions. i solved with this useEffect

  useEffect(() => {
    const subscription = purchaseUpdatedListener((purchase) => {
      // console.log('>>> APP JS useEffect purchaseUpdatedListener', purchase.transactionReceipt);

      const verify = async purchase => {
        const verifyPurchase = await validateReceiptIos({
          receiptBody: { 'receipt-data': purchase.transactionReceipt },
          isTest: true
        });
      }

      verify(purchase);
    });

    return () => {
      subscription.remove();
    };
  }, []);

and another issue is that the name of the functions in the docs is wrong, it took me hours to realize this. validateReceiptIos => in the docs is validateReceiptIOS

and another issue requestPurchaseWithQuantityIOS is undefined which i reported here

hotaryuzaki avatar Mar 26 '24 05:03 hotaryuzaki