j3k0 / cordova-plugin-purchase

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

[iOS] getting receipt type application in store.validator #1398

Open asaf-interator opened 1 year ago

asaf-interator commented 1 year ago

Observed behavior

Trying to update to v13.3.11 from V11.0.0 On iOS when trying to purchase a subscription I'm getting receipt type application in the store.validator even through I'm not subscribing this product id and it's not the product id I'm using to order. On Android it seems to be working well.

Expected behavior

Getting the right id and type of product in the receipt in the store.validator

System Info

Cordova Packages: cli: 11.1.0 common: 4.1.0 create: 4.1.0 lib: 11.1.0 common: 4.1.0 fetch: 3.1.0 serve: 4.0.1

Project Installed Platforms: android: 11.0.0 ios: 6.2.0

Project Installed Plugins: cordova-plugin-actionsheet: 2.3.3 cordova-plugin-androidx-adapter: 1.1.3 cordova-plugin-appsflyer-sdk: 6.8.2-rc1 cordova-plugin-camera: 6.0.0 cordova-plugin-customurlscheme: 5.0.1 cordova-plugin-datepicker: 0.9.3 cordova-plugin-device: 2.1.0 cordova-plugin-dialogs: 2.0.2 cordova-plugin-file: 7.0.0 cordova-plugin-firebasex: 16.0.0-cli cordova-plugin-inappbrowser: 5.0.0 cordova-plugin-insomnia: 4.3.0 cordova-plugin-intercom: 12.1.0 cordova-plugin-ionic-keyboard: 2.2.0 cordova-plugin-ionic-webview: 5.0.0 cordova-plugin-listpicker: 2.2.2 cordova-plugin-media: 6.1.0 cordova-plugin-network-information: 3.0.0 cordova-plugin-opentok: 3.4.3 cordova-plugin-proguard: 2.2.0 cordova-plugin-purchase: 13.3.11 cordova-plugin-statusbar: 3.0.0 cordova-plugin-whitelist: 1.3.5 cordova-universal-links-plugin-fixed: 1.2.1 cordova.plugins.diagnostic: 7.1.1 onesignal-cordova-plugin: 3.3.1

Environment: OS: macOS Monterey 12.6.3 (21G419) (darwin 21.6.0) x64 Node: v16.15.0 npm: 8.10.0

ios Environment: xcodebuild: Xcode 14.2 Build version 14C18

asaf-interator commented 1 year ago

I'm also getting TypeError: undefined is not an object (evaluating 'callback.name') on

function safeCall(logger, className, callback, value) { setTimeout(() => { try { callback(value); } catch (error) { logger.error(Error in callback: type=${className} name=${callback.name}); const errorAsError = error; if ('message' in errorAsError) logger.error(errorAsError.message); if ('fileName' in error) logger.error('in ' + error.fileName + ':' + error.lineNumber); if ('stack' in errorAsError) logger.error(errorAsError.stack); } }, 0); }

ollm commented 1 year ago

I have the same problem in v13.5.0, any solution to this?

Will it work correctly if I validate the receipt type application?

sjquant commented 1 year ago

I also have the same problem in v13.6.0. Could you check this issue please? @j3k0 It worked in v11.0.

And, the approved product is the product that I wanted to buy, but the request body contains a product with type application

I think it's because this part (https://github.com/j3k0/cordova-plugin-purchase/blob/b402df92ca4649d142deb162082f851578df0144/src/ts/platforms/apple-appstore/appstore-adapter.ts#L654C17-L664C18) has id applicationReceipt.bundleIdentifier and type 'application' instead of product id and product type. Is it intentional? Android has product id and type. @j3k0

bhaskar-se commented 12 months ago

hi @asaf-interator @sjquant did you guys got any resolution? @j3k0 please respond if it's intentional!

ollm commented 12 months ago

I currently have it working with something like this:

Request purchase:

userRequestedAdsPurchase = true;
store.order(store.get('my_subscription_name').getOffer(), {developerPayload: {}});

And in the validation function:


function storeValidator(receipt, callback)
{
    // Only validate type APPLICATION if the user has requested the purchase and not when opening the app
    if(receipt.type != CdvPurchase.ProductType.APPLICATION || (window.cordova.platformId == 'ios' && userRequestedAdsPurchase))
    {
        // Validate purchase code here, example:
        let xError = checkReceiptInServer(receipt);

        if(xError)
        {
            callback({
                ok: false,
                code: CdvPurchase.ErrorCode.CLIENT_INVALID,
                message: 'Error message',
            })
        }
        else
        {
            callback({ok: true, data: receipt.transaction});
        }

        // Reset userRequestedAdsPurchase
        userRequestedAdsPurchase = false;
    }
    else
    {
        // Try run always callback to avoid errors in iOS
        if(window.cordova.platformId == 'ios')
            callback({ok: true, data: receipt.transaction});
    }
}
cmaas commented 11 months ago

See my reply here, this seems to be related: https://github.com/j3k0/cordova-plugin-purchase/issues/1428#issuecomment-1727936885

Before in v11, the handlers (on iOS) only ever triggered for your pre-defined product ids. Now the handlers also trigger for the application itself, because apparently, the application is part of the transaction history. Solution is to filter in your .when().approved() handler (and possibly all others).