question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

iOS Receipt Validation from Server Side

See original GitHub issue

I am using my backend server to validate the iOS receipt. For that all I’ve done is passed the purchase.transactionReceipt to the application server in a post request. I want to know if purchase.transactionReceipt returns a base64 encoded receipt data or what? I’m getting error: 21002 with the current implementation

requestServerForReceiptVerification = (purchase: InAppPurchase | SubscriptionPurchase) => {
        const receipt = purchase.transactionReceipt;
        if (receipt) {
            // Hit Server API for Receipt Validation
            if (Platform.OS == 'ios') {
                let headers = {
                    'Content-Type': 'application/json'
                }
                Stores.UserStore.hitVerifyiOSReceiptAPI(receipt, headers, this.dropdown, (response: any) => {
                    finishTransaction(purchase).then(() => {
                        console.warn('Trasaction Finished');
                    }).catch((error) => {
                        console.warn(error.message);
                    })
                })
            } 
        }
    }

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

8reactions
bang9commented, Feb 18, 2020

check this one

const IOS_SHARED_PWD = "********";

async function validateIOS() {
    const latestPurchase = await getLatestPurchase();
    if (latestPurchase) {
        return false;
    }

    return RNIap.validateReceiptIos(
        {
            "receipt-data": latestPurchase.transactionReceipt,
            "password": IOS_SHARED_PWD,
            "exclude-old-transactions": false
        },
        false
    )
        .then(uncheckedValidation => {
            //check test receipt
            if (uncheckedValidation?.status === 21007) {
                return RNIap.validateReceiptIos(
                    {
                        "receipt-data": latestPurchase.transactionReceipt,
                        "password": IOS_SHARED_PWD,
                        "exclude-old-transactions": false
                    },
                    true
                );
            } else {
                return uncheckedValidation;
            }
        })
        .then(checkedValidation => {
            return isValidReceipt(checkedValidation);
        });
}

function getLatestPurchase() {
    return RNIap.getAvailablePurchases().then(purchases => {
        return purchases?.sort((a, b) => Number(b.transactionDate) - Number(a.transactionDate))?.[0] || null;
    });
}

function isValidReceipt(checkedValidation) {
    if (!checkedValidation) {
        return false;
    }

    // check is valid validation request
    if (checkedValidation.status === 21006 || checkedValidation.status === 21010) {
        return false;
    }

    const { latest_receipt_info: latestReceiptInfo } = checkedValidation;
    const latestReceipt = latestReceiptInfo
        ?.sort((a, b) => Number(b.purchase_date_ms) - Number(a.purchase_date_ms))
        ?.find(receipt => receipt.product_id === "some.product.id")?.[0];

    // no receipt
    if (!latestReceipt) {
        return false;
    }

    // refunded receipt
    if (latestReceipt.cancellation_date) {
        return false;
    }

    // expired receipt
    if (Number(latestReceipt.expires_date_ms) < Date.now()) {
        return false;
    }

    return checkedValidation.status === 0;
}
0reactions
InfiniteDreamzcommented, May 18, 2020

@leelandclay Thanks for putting up your solutions. This really helped a lot and we finally were able to validate our receipt. Thanks !!

Read more comments on GitHub >

github_iconTop Results From Across the Web

iOS In-App Purchases Server Side Validation - Adapty
Server validation (server-side receipt validation) is a way to verify the purchase's authenticity. Unlike device-based validation, server ...
Read more >
Choosing a receipt validation technique - Apple Developer
You can authenticate purchased content by adding receipt validation code to your app or server. Receipt validation requires an understanding of secure coding ......
Read more >
How to do App store IAP verification on server side with S2S ...
1. Receipt validation · a. Verify receipt with app store URL · b. Get a receipt from the app, parse it and then...
Read more >
How to verify ios In-App Purchase on your server
On this page you can find detailed information about IOS receipt verification. It is very easy. You should just send http request with...
Read more >
App Store Receipt Verification Tutorial: The Basics - Nami ML
It's possible to validate a receipt from the client-side or the server-side. Server-side receipt validation is more complicated, but the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found