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

store.restorePurchases() not work on V13 [restoreFailed: 6777010] #1515

Closed JMLiu26 closed 2 months ago

JMLiu26 commented 3 months ago

Observed behavior

I used version 11 before and everything was fine. After upgrading to version 13, when I call store.restorePurchases(), it returns restoreFailed: 6777010 error and all store.when().xxx() events are not fired, but when I kill the app and restart the app, I see in the store.when().receiptUpdated() that the product is owned.

Include logs with CdvPurchase.store.verbosity = CdvPurchase.LogLevel.DEBUG

[CdvPurchase.AppleAppStore] INFO: restoreFailed: 6777010
[CdvPurchase.AppleAppStore] INFO: receiptsRefreshed
j3k0 commented 3 months ago

How and when are you calling store.restorePurchases()?

Is the plugin initialized properly?

Can you share more logs and code?

JMLiu26 commented 3 months ago

@j3k0 Hello, here is my code:

const { store, ProductType, LogLevel, ErrorCode } = CdvPurchase;
const paymentPlatform = store.defaultPlatform();

store.verbosity = LogLevel.DEBUG;
store.validator = 'https://validator.iaptic.com/v3/validate?appName=XXX&apiKey=XXX';
store.register([{
  id: this.productId,
  type: ProductType.PAID_SUBSCRIPTION,
  platform: paymentPlatform,
}]);
store.error((error) => {
  if (error) {
    if (error.code === ErrorCode.PAYMENT_CANCELLED) {
      console.log('Purchase flow has been cancelled by user');
    } else {
      console.log(`ERROR ${error.code}: ${error.message}`);
    }
  }
});

const handleUpdate = () => {
  if (store.owned(this.productId)) {
    this.gotoLoginPage();
    return;
  }

  if (this.receiptsVerified) {
    if (store.get(this.productId) && this.canPurchase) {
      this.gotoSubscriptionPage();
    } else {
      this.gotoErrorPage();
    }
  }
};

store.when()
  .productUpdated(() => {
    const product = store.get(this.productId);
    this.canPurchase = !!(product && product.canPurchase);
    handleUpdate();
  })
  .receiptUpdated(() => {
    handleUpdate();
  })
  .receiptsVerified(() => {
    this.receiptsVerified = true;
    handleUpdate();
  })
  .approved((transaction) => {
    transaction.verify();
  })
  .verified((receipt) => {
    receipt.finish();
  })
  .unverified((receipt) => {
    console.log(`Receipt cannot be verified: ${receipt && receipt.payload && receipt.payload.message}`);
  });

store.initialize([paymentPlatform]).then((errors) => {
  if (errors && errors.length) {
    console.log('CdvPurchase.store.initialize() errors: ', errors);
  }
});

On the subscription page, I can not restore the subscription by calling the restorePurchases function.

  restorePurchases() {
    const { store } = CdvPurchase;
    store.restorePurchases().then(async (error) => {
      // 
    });
  }

Also on the subscription page, calling the purchase function works fine.

  purchase() {
    const { store } = CdvPurchase;
    const product = store.get(this.productId);
    if (product && product.canPurchase) {
      product.getOffer().order();
    }
  }
mluttmann commented 3 months ago

Have you found a solution to this problem? We also get error 6777010 after calling store.restorePurchases().

j3k0 commented 3 months ago

I cannot reproduce here... Do you get logs in XCode maybe?

JMLiu26 commented 3 months ago

@j3k0 The XCode log is as follows:

Apache Cordova native platform version 6.2.0 is starting.
Multi-tasking -> Device: YES, App: YES
CDVWKWebViewEngine: trying to inject XHR polyfill
The preference key "KeyboardResize" is not defined and will default to "TRUE"
The preference key "AutoInjectCordova" is not defined and will default to "FALSE"
The preference key "AudioCanMix" is not defined and will default to "FALSE"
The preference key "WKSuspendInBackground" is not defined and will default to "TRUE"
The preference key "MediaPlaybackAllowsAirPlay" is not defined and will default to "TRUE"
The preference key "KeyboardAppearanceDark" is not defined and will default to "FALSE"
The preference key "InspectableWebview" is not defined and will default to "TRUE"
The preference key "AllowLinkPreview" is not defined and will default to "FALSE"
The preference key "AllowBackForwardNavigationGestures" is not defined and will default to "FALSE"
CDVWKWebViewEngine will reload WKWebView if required on resume
Using Ionic WKWebView
[CDVTimer][console] 0.0759ms
[CDVTimer][handleopenurl] 0.0410ms
[CDVTimer][intentandnavigationfilter] 2.7339ms
[CDVTimer][gesturehandler] 0.0449ms
[CDVTimer][ionicdeeplinkplugin] 0.0499ms
[CDVTimer][statusbar] 2.0940ms
The preference key "KeyboardResize" is not defined and will default to "TRUE"
CDVIonicKeyboard: resize mode 1
The preference key "HideKeyboardFormAccessoryBar" is not defined and will default to "TRUE"
The preference key "KeyboardAppearanceDark" is not defined and will default to "FALSE"
[CDVTimer][cdvionickeyboard] 0.5790ms
[CDVTimer][file] 2.6101ms
[CDVTimer][diagnostic] 0.6320ms
[CDVTimer][diagnostic_location] 5.3459ms
[CdvPurchase.AppleAppStore.objc] Initialized.
[CDVTimer][inapppurchase] 9.2280ms
[CDVTimer][TotalPluginStartup] 24.5869ms
active
application first launch: remove badge icon number
PushPlugin skip clear badge
[CdvPurchase.AppleAppStore.objc] (before init): WARNING: Your app should be single page to use in-app-purchases. onReset is not supported.
The preference key "AutoHideSplashScreen" is not defined and will default to "TRUE"
Create CdvPurchase...
[CdvPurchase] INFO: initialize(["ios-appstore"]) v13.10.1
[CdvPurchase.Adapters] INFO: Adding platforms: [{"platform":"ios-appstore"}]
[CdvPurchase.Adapters] INFO:
[CdvPurchase.Adapters] INFO: AppStore initializing...
[CdvPurchase.AppleAppStore] INFO: bridge.init
[CdvPurchase.AppleAppStore.objc] setup: OK
THREAD WARNING: ['CordovaHttpPlugin'] took '10.5048' ms. Plugin should use a background thread.
[CdvPurchase.AppleAppStore.Bridge] DEBUG: setup ok
[CdvPurchase.AppleAppStore] INFO: ready
[CdvPurchase.AppleAppStore] INFO: bridge.init done
[CdvPurchase.AppleAppStore.objc] canMakePayments: Device can make payments.
[CdvPurchase.Adapters] INFO: AppStore initialized.
[CdvPurchase.Adapters] INFO: AppStore products: [{"id":"xxxxxxsub1","type":"paid subscription","platform":"ios-appstore"}]
[CdvPurchase.AppleAppStore] INFO: bridge.load
[CdvPurchase.AppleAppStore.Bridge] DEBUG: load ["xxxxxxsub1"]
[CdvPurchase.AppleAppStore.objc] load: Getting products data
[CdvPurchase.AppleAppStore.objc] load: Set has 1 elements
[CdvPurchase.AppleAppStore.objc] load:  - xxxxxxsub1
[CdvPurchase.AppleAppStore.objc] load: Starting product request...
[CdvPurchase.AppleAppStore.objc] load: Product request started
[CdvPurchase.AppleAppStore.Bridge] DEBUG: processing pending transactions
[CdvPurchase.AppleAppStore.objc] processPendingTransactionUpdates
nw_proxy_resolver_create_parsed_array [C1.1 proxy pac] Evaluation error: NSURLErrorDomain: -1,003
nw_proxy_resolver_create_parsed_array [C2.1 proxy pac] Evaluation error: NSURLErrorDomain: -1,003
[CdvPurchase.AppleAppStore.objc] BatchProductsRequestDelegate.productsRequest:didReceiveResponse:
[CdvPurchase.AppleAppStore.objc] BatchProductsRequestDelegate.productsRequest:didReceiveResponse: Has 1 validProducts
[CdvPurchase.AppleAppStore.objc] BatchProductsRequestDelegate.productsRequest:didReceiveResponse:  - xxxxxxsub1: Xxxxxx Subscription
[CdvPurchase.AppleAppStore.objc] BatchProductsRequestDelegate.productsRequest:didReceiveResponse: sendPluginResult: (
        (
                {
            billingPeriod = 1;
            billingPeriodUnit = Year;
            countryCode = HK;
            currency = HKD;
            description = "Gives you unlimited access and updates to app";
            discounts =             (
            );
            group = 20736370;
            id = xxxxxxsub1;
            introPrice = "HK$0.00";
            introPriceMicros = 0;
            introPricePaymentMode = FreeTrial;
            introPricePeriod = 1;
            introPricePeriodUnit = Month;
            price = "HK$103.00";
            priceMicros = 103000000;
            title = "Xxxxxx Subscription";
        }
    ),
        (
    )
)
[CdvPurchase.AppleAppStore.Bridge] DEBUG: load ok: { valid:[{"id":"xxxxxxsub1","description":"Gives you unlimited access and updates to app","introPrice":"HK$0.00","introPricePaymentMode":"FreeTrial","billingPeriodUnit":"Year","countryCode":"HK","introPricePeriodUnit":"Month","discounts":[],"title":"Xxxxxx Subscription","price":"HK$103.00","billingPeriod":1,"group":"20736370","priceMicros":103000000,"currency":"HKD","introPricePeriod":1,"introPriceMicros":0}] invalid:[] }
[CdvPurchase.AppleAppStore] INFO: bridge.loaded: {"validProducts":[{"id":"xxxxxxsub1","description":"Gives you unlimited access and updates to app","introPrice":"HK$0.00","introPricePaymentMode":"FreeTrial","billingPeriodUnit":"Year","countryCode":"HK","introPricePeriodUnit":"Month","discounts":[],"title":"Xxxxxx Subscription","price":"HK$103.00","billingPeriod":1,"group":"20736370","priceMicros":103000000,"currency":"HKD","introPricePeriod":1,"introPriceMicros":0}],"invalidProducts":[]}
[CdvPurchase.AppleAppStore] DEBUG: load eligibility: [{"id":"xxxxxxsub1","description":"Gives you unlimited access and updates to app","introPrice":"HK$0.00","introPricePaymentMode":"FreeTrial","billingPeriodUnit":"Year","countryCode":"HK","introPricePeriodUnit":"Month","discounts":[],"title":"Xxxxxx Subscription","price":"HK$103.00","billingPeriod":1,"group":"20736370","priceMicros":103000000,"currency":"HKD","introPricePeriod":1,"introPriceMicros":0}]
[CdvPurchase.AppleAppStore] DEBUG: No discount eligibility determiner, skipping...
[CdvPurchase.AppleAppStore] INFO: eligibilities ready: {"request":[],"response":[]}
[CdvPurchase.AppleAppStore] DEBUG: xxxxxxsub1 is valid: {"id":"xxxxxxsub1","description":"Gives you unlimited access and updates to app","introPrice":"HK$0.00","introPricePaymentMode":"FreeTrial","billingPeriodUnit":"Year","countryCode":"HK","introPricePeriodUnit":"Month","discounts":[],"title":"Xxxxxx Subscription","price":"HK$103.00","billingPeriod":1,"group":"20736370","priceMicros":103000000,"currency":"HKD","introPricePeriod":1,"introPriceMicros":0}
[CdvPurchase.AppleAppStore] DEBUG: registering new product
[CdvPurchase.AppleAppStore] DEBUG: Products loaded: [{"className":"Product","title":"Xxxxxx Subscription","description":"Gives you unlimited access and updates to app","platform":"ios-appstore","type":"paid subscription","id":"xxxxxxsub1","group":"20736370","offers":[{"className":"Offer","id":"$","pricingPhases":[{"price":"HK$0.00","priceMicros":0,"currency":"HKD","billingPeriod":"P1M","paymentMode":"FreeTrial","recurrenceMode":"FINITE_RECURRING","billingCycles":1},{"price":"HK$103.00","priceMicros":103000000,"currency":"HKD","billingPeriod":"P1Y","paymentMode":"PayAsYouGo","recurrenceMode":"INFINITE_RECURRING"}],"productId":"xxxxxxsub1","productType":"paid subscription","productGroup":"20736370","platform":"ios-appstore","offerType":"Default"}],"raw":{"id":"xxxxxxsub1","description":"Gives you unlimited access and updates to app","introPrice":"HK$0.00","introPricePaymentMode":"FreeTrial","billingPeriodUnit":"Year","countryCode":"HK","introPricePeriodUnit":"Month","discounts":[],"title":"Xxxxxx Subscription","price":"HK$103.00","billingPeriod":1,"group":"20736370","priceMicros":103000000,"currency":"HKD","introPricePeriod":1,"introPriceMicros":0},"countryCode":"HK"}]
[CdvPurchase.AppleAppStore] DEBUG: loading appstore receipt...
[CdvPurchase.AppleAppStore.Bridge] DEBUG: loading appStoreReceipt
[CdvPurchase.AppleAppStore.objc] appStoreReceipt:
[CdvPurchase.AppleAppStore.Bridge] DEBUG: infoPlist: com.xxxxxx.yyyyyy,1.6.0,0,????
[CdvPurchase.AppleAppStore] DEBUG: appstore receipt loaded
[CdvPurchase.AdapterListener] DEBUG: receiptsReady: ios-appstore (1/0)
WARN: [CdvPurchase.AppleAppStore] WARNING: no appStoreReceipt
[CdvPurchase.Adapters] INFO: AppStore products loaded: [{"className":"Product","title":"Xxxxxx Subscription","description":"Gives you unlimited access and updates to app","platform":"ios-appstore","type":"paid subscription","id":"xxxxxxsub1","group":"20736370","offers":[{"className":"Offer","id":"$","pricingPhases":[{"price":"HK$0.00","priceMicros":0,"currency":"HKD","billingPeriod":"P1M","paymentMode":"FreeTrial","recurrenceMode":"FINITE_RECURRING","billingCycles":1},{"price":"HK$103.00","priceMicros":103000000,"currency":"HKD","billingPeriod":"P1Y","paymentMode":"PayAsYouGo","recurrenceMode":"INFINITE_RECURRING"}],"productId":"xxxxxxsub1","productType":"paid subscription","productGroup":"20736370","platform":"ios-appstore","offerType":"Default"}],"raw":{"id":"xxxxxxsub1","description":"Gives you unlimited access and updates to app","introPrice":"HK$0.00","introPricePaymentMode":"FreeTrial","billingPeriodUnit":"Year","countryCode":"HK","introPricePeriodUnit":"Month","discounts":[],"title":"Xxxxxx Subscription","price":"HK$103.00","billingPeriod":1,"group":"20736370","priceMicros":103000000,"currency":"HKD","introPricePeriod":1,"introPriceMicros":0},"countryCode":"HK"}]
[CdvPurchase.Adapters] INFO: AppStore receipts loaded: [{"className":"Receipt","transactions":[],"platform":"ios-appstore"}]
[CdvPurchase.AdapterListener] DEBUG: setSupportedPlatforms: ios-appstore (1 have their receipts ready)
[CdvPurchase.AdapterListener] DEBUG: triggering receiptsReady()
[CdvPurchase] DEBUG: Calling callback: type=productUpdated() name=#b8fd499e842e85fec3b0da2b55fa3f06 reason=adapterListener_productsUpdated
Product.canPurchase: true
[CdvPurchase] DEBUG: Calling callback: type=receiptsReady() name=receiptsMonitor_setup reason=adapterListener_setSupportedPlatforms
[CdvPurchase.ReceiptsMonitor] DEBUG: receiptsReady...
[CdvPurchase.AppleAppStore] DEBUG: receipt updated.
[CdvPurchase.AdapterListener] DEBUG: receiptsUpdated: [{"className":"Receipt","transactions":[],"platform":"ios-appstore"}]
[CdvPurchase] DEBUG: Calling callback: type=receiptUpdated() name=#b3e62f81c994ad545c7c6bc001f126f5 reason=adapterListener_receiptsUpdated
[CdvPurchase.ReceiptsMonitor] DEBUG: keep checking every 10s...
[CdvPurchase.ReceiptsMonitor] DEBUG: check(0/0)
[CdvPurchase.ReceiptsMonitor] INFO: receiptsVerified()
[CdvPurchase] DEBUG: Calling callback: type=receiptsVerified() name=#fe086e054e5bc185d3e89b9b9f71ddda reason=receipts_monitor_controller
[CdvPurchase.AppleAppStore.objc] paymentQueue:restoreCompletedTransactionsFailedWithError:
[CdvPurchase.AppleAppStore] INFO: restoreFailed: 6777010
[CdvPurchase.AppleAppStore.Bridge] DEBUG: refreshing appStoreReceipt
[CdvPurchase.AppleAppStore.objc] appStoreRefreshReceipt: Request to refresh app receipt
[CdvPurchase.AppleAppStore.objc] appStoreRefreshReceipt: Starting receipt refresh request...
[CdvPurchase.AppleAppStore.objc] appStoreRefreshReceipt: Receipt refresh request started
[CdvPurchase.AppleAppStore.objc] RefreshReceiptDelegate.requestDidFinish: Got refreshed receipt
[CdvPurchase.AppleAppStore.objc] RefreshReceiptDelegate.requestDidFinish: Send new receipt data
[CdvPurchase.AppleAppStore.Bridge] DEBUG: infoPlist: com.xxxxxx.yyyyyy,1.6.0,0,????
[CdvPurchase.AppleAppStore] INFO: receiptsRefreshed
Background Task 4 ("SKReceiptRefreshRequest"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
Received XPC error Connection interrupted for message type 3 kCFNetworkAgentXPCMessageTypePACQuery
Received XPC error Connection invalid for message type 3 kCFNetworkAgentXPCMessageTypePACQuery
<SKClientBroker: 0x280456850>: Error getting unfinished transactions: Error Domain=ASDServerErrorDomain Code=5002 "An unknown error has occurred" UserInfo={NSLocalizedFailureReason=An unknown error has occurred, AMSServerErrorCode=5002}
<SKClientBroker: 0x280456850>: Error getting unfinished transactions: Error Domain=ASDServerErrorDomain Code=5002 "An unknown error has occurred" UserInfo={NSLocalizedFailureReason=An unknown error has occurred, AMSServerErrorCode=5002}
j3k0 commented 3 months ago

The errors you're encountering seem to involve the XPC (inter-process communication) and the StoreKit (SK) client broker. Here's a breakdown of the issues and potential solutions:

  1. XPC Errors:

    • Received XPC error Connection interrupted for message type 3 kCFNetworkAgentXPCMessageTypePACQuery
    • Received XPC error Connection invalid for message type 3 kCFNetworkAgentXPCMessageTypePACQuery

    These errors indicate issues with the XPC connection, which is used for inter-process communication. Specifically, the errors are related to PAC (Proxy Auto-Config) queries, which are used to determine the appropriate proxy for a given URL.

    Potential Causes:

    • Network changes or instability can interrupt the XPC connection.
    • App sandboxing or permission issues can lead to invalid connections.

    Solutions:

    • Ensure stable network conditions.
    • Check if any network proxies or VPNs might be interfering with the connection.
    • Review app settings and permissions to ensure they allow necessary network access and inter-process communication.
  2. SKClientBroker Errors:

    • <SKClientBroker: 0x280456850>: Error getting unfinished transactions: Error Domain=ASDServerErrorDomain Code=5002 "An unknown error has occurred" UserInfo={NSLocalizedFailureReason=An unknown error has occurred, AMSServerErrorCode=5002}

    This error is coming from the StoreKit framework, specifically indicating an issue when trying to retrieve unfinished transactions.

    Potential Causes:

    • Server-side issues with the App Store.
    • Issues with the user's Apple ID or payment method.

    Solutions:

    • Check server status for the App Store to see if there are any outages or issues that might be affecting transaction processing.
    • Check the Apple ID and payment method settings.
    • Try with a different Apple ID.

If the problem continues, consider reaching out to Apple Developer Support for more specific guidance.