j3k0 / cordova-plugin-purchase

In-App Purchase for Cordova on iOS, Android and Windows
https://purchase.cordova.fovea.cc
1.29k stars 529 forks source link

TypeError: undefined is not an object (evaluating 'receipt.transactions[0].transactionId') #1526

Open selcukbeyhan opened 2 months ago

selcukbeyhan commented 2 months ago

I was receiving following error in the logs.

⚡️  [error] - ERROR Error: Uncaught (in promise): TypeError: undefined is not an object (evaluating 'receipt.transactions[0].transactionId')
@user-script:23:624:64
@user-script:23:9:75
ZoneAwarePromise@capacitor://localhost/polyfills.js:2724:31
@user-script:23:5:36
forEach@[native code]
run@user-script:23:608:33
timer@capacitor://localhost/polyfills.js:4688:38
onInvokeTask@capacitor://localhost/vendor.js:151023:35
@capacitor://localhost/polyfills.js:1331:49
@capacitor://localhost/polyfills.js:1676:35

Then I checked why this could be happening and found some places where this "receipt.transactions[0].transactionId" statement is in place.

            /**
             * Prepare for receipt validation
             */
            receiptValidationBody(receipt) {
                var _a;
                return __awaiter(this, void 0, void 0, function* () {
                    const transaction = receipt.transactions[0];
                    if (!transaction)
                        return;
                    const productId = (_a = transaction.products[0]) === null || _a === void 0 ? void 0 : _a.id;
                    if (!productId)
                        return;
                    const product = this._products.getProduct(productId);
                    if (!product)
                        return;
                    const purchase = transaction.nativePurchase;
                    return {
                        id: productId,
                        type: product.type,
                        offers: product.offers,
                        products: this._products.products,
                        transaction: {
                            type: CdvPurchase.Platform.GOOGLE_PLAY,
                            id: receipt.transactions[0].transactionId,
                            purchaseToken: purchase.purchaseToken,
                            signature: purchase.signature,
                            receipt: purchase.receipt,
                        }
                    };
                });
            }

and also this section:

                        // for backward compatibility, we consider that the receipt is verified.
                        callback({
                            receipt,
                            payload: {
                                ok: true,
                                data: {
                                    id: receipt.transactions[0].transactionId,
                                    latest_receipt: true,
                                    transaction: { type: 'test' } // dummy data
                                }
                            }
                        });

In both sections, there is no check whether the receipt.transactions array contains an element or not.