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

VueJS? #1237

Open jonesart opened 2 years ago

jonesart commented 2 years ago

Has anyone got this to work Ionic/VueJs/Capacitor?

I don't think I'm accessing the plugin.
When I build it on my phone, I get [log] - window.store is undefined in the Xcode log.

michaelbutler1998 commented 2 years ago

Instead of using store, I have been referencing it like this..

import { InAppPurchase2 } from '@ionic-native/in-app-purchase-2'

Then within methods:

InAppPurchase2.register([{

jonesart commented 2 years ago

@michaelbutler1998

Are using InAppPurchase2 in place of window.store here? const store = window.store;

document.addEventListener('deviceready', () => { const store = window.store; const products = [{ id: 'cc.fovea.purchase.subscription1', type: store.PAID_SUBSCRIPTION }, { id: 'cc.fovea.purchase.subscription2', type: store.PAID_SUBSCRIPTION }]; setState({ products }); store.verbosity = store.DEBUG; store.register(products); store.when().updated(render); store.when().approved(p => p.finish()); store.ready(() => setState({ ready: true })); store.refresh(); window.order = (productId) => { store.order(productId); };

The code is from here https://github.com/j3k0/cordova-iap-workshop/blob/master/02-order/js/index.js

michaelbutler1998 commented 2 years ago

@michaelbutler1998

Are using InAppPurchase2 in place of window.store here? const store = window.store;

document.addEventListener('deviceready', () => { const store = window.store; const products = [{ id: 'cc.fovea.purchase.subscription1', type: store.PAID_SUBSCRIPTION }, { id: 'cc.fovea.purchase.subscription2', type: store.PAID_SUBSCRIPTION }]; setState({ products }); store.verbosity = store.DEBUG; store.register(products); store.when().updated(render); store.when().approved(p => p.finish()); store.ready(() => setState({ ready: true })); store.refresh(); window.order = (productId) => { store.order(productId); };

The code is from here https://github.com/j3k0/cordova-iap-workshop/blob/master/02-order/js/index.js

Yes, I am @jonesart

Please see below two examples of how I have used this to replace the store.register and store.when().updated function...

InAppPurchase2.register([{ id: 'loremIpsum', type: InAppPurchase2.PAID_SUBSCRIPTION, } ]);

InAppPurchase2.when('subscription').updated(function() {

Try importing as I have above and swap store out for InAppPurchase2 and see if it solves your issue

jonesart commented 2 years ago

@michaelbutler1998

I'm getting this error in the xcode log

⚡️ [warn] - Native: tried calling InAppPurchase2.PAID_SUBSCRIPTION, but the InAppPurchase2 plugin is not installed. ⚡️ [warn] - Install the InAppPurchase2 plugin: 'ionic cordova plugin add cordova-plugin-purchase'

Those plugins should be installed

Found 2 Capacitor plugins for android: @capacitor-community/fcm (1.1.0) capacitor-fcm (2.0.0) Found 3 Cordova plugins for android cordova-plugin-device (2.0.3) cordova-plugin-network-information (3.0.0) cordova-plugin-purchase (10.6.1) Found 2 Capacitor plugins for ios: @capacitor-community/fcm (1.1.0) capacitor-fcm (2.0.0) Found 3 Cordova plugins for ios cordova-plugin-device (2.0.3) cordova-plugin-network-information (3.0.0) cordova-plugin-purchase (10.6.1)

ionic-native/in-app-purchase-2 is in the node-modules directory
jonesart commented 2 years ago

This is my script. I'm new to Vue, if you have any advice, that would be awesome.

<script>
export default {
  props: ["basurl"],
  components: {
  },
  data() {
    return {
    };
  },
  mounted() {
    const state = {
      page: null,
      ready: false,
      products: [],
    };
    const setState = (attributes) => {
      Object.assign(state, attributes);
      render();
    };

    const render = () => {
      const html = pages[state.page]();
      const body = document.getElementsByTagName("body")[0];
      body.innerHTML = html;
    };

    const layout = (title, content) => {
      return `
    <div class="container" style="padding-top: 30px">
      <div class="row"><h1>${title}</h1></div>
      <div class="row">${content}</div>
    </div>`;
    };

    const button = (label, btID) => `
  <span id="${btID}" class="button" >${label}</span>
`;

    const pages = {
      home: () => {
        return layout(
          "Home 2",
          `
      <br/><br/>
      ${button("Account", "goToAccount")}
      <br/><br/><br/><br/>
      ${button("Store", "goToStore" )}
    `
        );
      },
      account: () => {
        return layout("Account", button("Back to Home", "goToBackHome"));
      },
      store: () => {
        const content = () => {
          if (!state.ready) {
            return "<p>Please wait...<p>";
          }

          const html = state.products
            .map(({ id }) => {
              const product = InAppPurchase2.get(id);
              if (!product) {
                return '<div class="row">...</div>';
              }
              return `
          <div class="row">
            <h3>${product.title}</h3>
            <p>${product.description}</p>
            <p>${button(product.price, "")}</p>
          </div>
        `;
            })
            .join("");
          return `<div class="container">${html}</div>`;
        };
        return layout(
          "Store",
          content() + button("Back to Home",  "goToBackHome")
        );
      },
    };

    const openPage = (page) => setState({ page });

    openPage("home");

      const products = [
        {
          id: "com.sba.month01",
          type: InAppPurchase2.PAID_SUBSCRIPTION,
        },
        {
          id: "com.sba.week01",
          type: InAppPurchase2.PAID_SUBSCRIPTION,
        },
      ];
      setState({ products });
      InAppPurchase2.verbosity = InAppPurchase2.DEBUG;
      InAppPurchase2.register(products),
      InAppPurchase2.when('subscription').updated(render);
      InAppPurchase2.ready(() => setState({ ready: true }));
      InAppPurchase2.refresh();

  },
};
</script>
michaelbutler1998 commented 2 years ago

@michaelbutler1998

I'm getting this error in the xcode log

⚡️ [warn] - Native: tried calling InAppPurchase2.PAID_SUBSCRIPTION, but the InAppPurchase2 plugin is not installed. ⚡️ [warn] - Install the InAppPurchase2 plugin: 'ionic cordova plugin add cordova-plugin-purchase'

Those plugins should be installed

Found 2 Capacitor plugins for android: @capacitor-community/fcm (1.1.0) capacitor-fcm (2.0.0) Found 3 Cordova plugins for android cordova-plugin-device (2.0.3) cordova-plugin-network-information (3.0.0) cordova-plugin-purchase (10.6.1) Found 2 Capacitor plugins for ios: @capacitor-community/fcm (1.1.0) capacitor-fcm (2.0.0) Found 3 Cordova plugins for ios cordova-plugin-device (2.0.3) cordova-plugin-network-information (3.0.0) cordova-plugin-purchase (10.6.1)

ionic-native/in-app-purchase-2 is in the node-modules directory

I believe the issue is likely what is said on the first two lines, the plugin is not yet installed

In your terminal after navigating to the directory containing the project, run

npm install cordova-plugin-purchase npx cap update

https://capacitorjs.com/docs/guides/in-app-purchases

Good luck. If you're absolutely new to Vue, I would start by reading these docs and looking to put the returned data into Vue's data property as currently you're not doing so. I would look to do this for a few reasons, but first and foremost it will make the code cleaner / easier to follow.

https://v3.vuejs.org/guide/data-methods.html

jonesart commented 2 years ago

Starting with a fresh project helped. The log is showing data from the app store.

the store.ready(() => setState({ ready: true })); is not running or updating the state var

jonesart commented 2 years ago

@michaelbutler1998

Could I email you with some questions?

michaelbutler1998 commented 2 years ago

Yes, send me or post your email and I’ll follow up when I can

On Fri, 15 Oct 2021 at 15:10, jonesart @.***> wrote:

@michaelbutler1998 https://github.com/michaelbutler1998

Could I email you with some questions?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3k0/cordova-plugin-purchase/issues/1237#issuecomment-944333392, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADY2JHD2BOCLY3EGQ6C7GQLUHAY45ANCNFSM5DSLN3BQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

Kamsou commented 2 years ago

@jonesart Did you manage to get out and use the plugin with Vue? I'm going to start with it too, it would be really cool to have your feedback and/or an example ! 🙏🙏🙏🙏🙏

michaelbutler1998 commented 2 years ago

I assisted @jonesart with this set up to get their purchases working for iOS & Android on a consultancy rate basis.

Michael

On Mon, 29 Nov 2021 at 16:57, Camille Coutens @.***> wrote:

@jonesart https://github.com/jonesart Did you manage to get out and use the plugin with Vue? I'm going to start with it too, it would be really cool to have your feedback and/or an example ! 🙏🙏🙏🙏🙏

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3k0/cordova-plugin-purchase/issues/1237#issuecomment-981824689, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADY2JHBH6GIFBNERXOZG5BDUOOWJDANCNFSM5DSLN3BQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

Kamsou commented 2 years ago

@michaelbutler1998 So cool! I will try the implementation in the next few days. If I need help, can I contact you somewhere?

michaelbutler1998 commented 2 years ago

I’ve got push notifications to my emails on this post so will be able to see if you comment. If you send me your email / leave it here I can also reach out to you with my personal email so you can contact me with ease

On Mon, 29 Nov 2021 at 17:27, Camille Coutens @.***> wrote:

@michaelbutler1998 https://github.com/michaelbutler1998 So cool! I will try the implementation in the next few days. If I need help, can I contact you somewhere?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/j3k0/cordova-plugin-purchase/issues/1237#issuecomment-981852495, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADY2JHFQAUWE5GSNI7ZRSFDUOOZYVANCNFSM5DSLN3BQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

mashrurbd commented 11 months ago

can anyone help me with this?###

michaelbutler1998 commented 11 months ago

@mashrurbd same offer as above, my emails in my profile

mashrurbd commented 10 months ago

@mashrurbd same offer as above, my emails in my profile

I have mailed you with the details.Waiting for your help.

arodriguezt commented 9 months ago

I'm also facing the same problems on my vue project can anyone help me out?

michaelbutler1998 commented 9 months ago

Hi Arodriguezt / others replying to this thread

I’m can try to assist an hourly consulting basis. If you’d like to discuss further email me at the email added found in my profile

I would love to offer to help without charging but due to my other obligations this unfortunately is not possible

BR, Michael

On Thu, 10 Aug 2023 at 18:21, arodriguezt @.***> wrote:

I'm also facing the same problems on my vue project can anyone help me out?

— Reply to this email directly, view it on GitHub https://github.com/j3k0/cordova-plugin-purchase/issues/1237#issuecomment-1673612189, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADY2JHDS7C2XMHJ4CZG3P6TXUUJ7ZANCNFSM5DSLN3BQ . You are receiving this because you were mentioned.Message ID: @.***>

Kamsou commented 9 months ago

I've solved the payment problem for Ionic/VueJs/Capacitor app. I can also help you @arodriguezt, if you give me more information about your implementation.

arodriguezt commented 9 months ago

First of all thank you all for offering help, I have tried to implement a simple code using the cordova-plugin-purchase with capacitor after installing

npm install cordova-plugin-purchase @ionic-native/in-app-purchase-2

On my Vue.js i have a mounted code that should initialize a product

import { InAppPurchase2 } from '@ionic-native/in-app-purchase-2';

initializeIAP() {
      InAppPurchase2.register({
        id: "suscription",
        type: InAppPurchase2.CONSUMABLE,
      });
      InAppPurchase2.when("suscription")
        .approved((p) => p.verify())
        .verified((p) => p.finish());
      InAppPurchase2.refresh();
    },
    purchaseProduct(idProduct) {
      InAppPurchase2.order(idProduct);
    },

But when i'm trying it on Android Studio its saying that the plugin InAppPurchase2 its not installed i ran npm install cordova-plugin-purchase npx cap update but still the same error, the bundle is not in play store, i just wanted to try out if the plugin worked in vue

Error: TypeError: Fc.when(...).approved is not a function at Proxy.initializeIAP (index-1e07d8a4.js:2762:27308) at Proxy.mounted (index-1e07d8a4.js:2762:26886) at index-1e07d8a4.js:1:20327 at Wo (index-1e07d8a4.js:1:12867) at lr (index-1e07d8a4.js:1:12946) at Vh.e.weh.e.weh (index-1e07d8a4.js:1:20207) at VM (index-1e07d8a4.js:1:14240) at fe (index-1e07d8a4.js:1:41229) at mount (index-1e07d8a4.js:1:27653) at MA.e.mount (index-1e07d8a4.js:1:55741)

Warnings: Native: tried calling InAppPurchase2.order, but the InAppPurchase2 plugin is not installed. index-1e07d8a4.js:2762 Install the InAppPurchase2 plugin: 'ionic cordova plugin add cordova-plugin-purchase'

In my node_modules the plugin appears inside @ionic-native / in-app-purchase i'm missing something? image

Kamsou commented 9 months ago

@arodriguezt Yes, things have changed on the Google Billing side. I advise you to use only cordova-plugin-purchase without @ionic-native/in-app-purchase-2

And instantiate it this way in your page .vue :

import "cordova-plugin-purchase"

const productId = YOUR_PRODUCT_ID
const InAppPurchase = CdvPurchase.store
const { ProductType, Platform, LogLevel } = CdvPurchase

InAppPurchase.register([
        {
            id: productId,
            type: ProductType.CONSUMABLE,
            platform: Platform.APPLE_APPSTORE,
        },
        {
            id: productId,
            type: ProductType.CONSUMABLE,
            platform: Platform.GOOGLE_PLAY,
        },
    ])

(the rest of the actions are in the doc cordova plugin purchase)

michaelbutler1998 commented 9 months ago

@arodriguezt what version of the @ionic-native/in-app-purchase-2 are you using & do you have any other conflicting purchase libraries installed in your package.json

I haven't updated this library in a while, but with similar code to yours have it working with

"@ionic-native/in-app-purchase-2": "^5.36.0",

arodriguezt commented 9 months ago

@michaelbutler1998 I'm using version 5.36.0 I don't understand why with the configuration I have it doesn't work.

@Kamsou I have implemented the configuration that you have told me and from android studio no longer appears the warning indicating that it does not detect the plugin, now it appears an error

Uncaught (in promise) Error: not implemented
    at returnResult (VM3:774:32)
    at win.androidBridge.onmessage (VM3:749:21)

but I understand that it is related to upload the APK to the play store to use Google Play Store's billing system to process in-app purchases.

I will try to upload the apk, get it accepted and test it again to see if it works, thanks to both of you for your help.

Kamsou commented 9 months ago

@arodriguezt No, you need to be able to test with one of the Android studio simulators.

You need to choose one that has the play store symbol only :

Capture d’écran 2023-08-11 à 18 45 09

arodriguezt commented 9 months ago

@Kamsou I tried on a simulator with Google Play Store, but there's no pop up or modal from the plugin

 import "cordova-plugin-purchase";
 const InAppPurchase = CdvPurchase.store;
 const { ProductType, Platform, LogLevel } = CdvPurchase;

mounted() {
    this.initializeIAP();
  },

initializeIAP() {
       InAppPurchase.initialize();
       InAppPurchase.register([
         {
           id: "53",
           type: ProductType.CONSUMABLE,
           platform: Platform.GOOGLE_PLAY,
         },
       ]);
       InAppPurchase.when("53")
         .approved((p) => p.verify())
         .verified((p) => p.finish());

       InAppPurchase.update();
    },
    purchaseProduct(idProduct) {
         InAppPurchase.order(idProduct)
      }

On clicking a product it's passing his ID, this code should open the plugin on android studio? i'm missing something? in the documentation of the plugin it says that the apk needs to be released in google play in order to test it for relationing the product created from play store console to the plugin isn't that right?

Kamsou commented 9 months ago

needs to be released in google play in order to test it for relationing the product created from play store console to the plugin isn't that right?

Not necessarily ! You can use simulator of Android Studio, Login with you credentials and test directly.

@arodriguezt What is 53 ? you need to create the product first in Play Console.

.initialize() should be after register : InAppPurchase.initialize([Platform.GOOGLE_PLAY])

thommydz commented 3 months ago

I got really far setting this up in NuxtJS. However, I am stuck at finishing a transaction. Here's my set up:

import "cordova-plugin-purchase";
export default {
mounted() {      
      if (process.client) {
        document.addEventListener('deviceready', this.initializeIAP, false);
      }
}
methods: {
initializeIAP() {
    const {store, ProductType, Platform} = CdvPurchase;
    store.register([
    {
      type: ProductType.NON_CONSUMABLE,
      id: 'my_id_1',
      platform: Platform.APPLE_APPSTORE,
    },
    {
      type: ProductType.PAID_SUBSCRIPTION,
      id: 'my_id_2',
      platform: Platform.APPLE_APPSTORE,
    }
    ]);

    store.when()
    .productUpdated(product => this.refreshUI(product))
    .approved(transaction => transaction.verify())
    .verified(receipt => receipt.finish());
}
}
}

In my logs on iOS I see this:

[CdvPurchase.AppleAppStore.objc] Initialized.
To Native Cordova ->  InAppPurchase setup InAppPurchase897418845 ["options": []]
To Native Cordova ->  InAppPurchase canMakePayments InAppPurchase897418846 ["options": []]
To Native Cordova ->  InAppPurchase load InAppPurchase897418847 ["options": [<__NSArrayM 0x600000c659e0>(
my_id_1,
my_id_2
)
]]
To Native Cordova ->  InAppPurchase processPendingTransactions InAppPurchase897418848 ["options": []]
To Native Cordova ->  InAppPurchase appStoreReceipt InAppPurchase897418849 ["options": []]

So everything up until here seems fine. Then I try to do a purchase like this: store.get("my_id_1")?.getOffer()?.order();

That makes the iOS payment pounder show up. I can then hit "pay" and I hear the iOS payment complete sound. Also in my logs I see:

To Native Cordova ->  InAppPurchase purchase InAppPurchase897418850 ["options": [my_id_1, 1, <null>, {
}]]

The weird thing is that after that, the payment popunder just re-shows again. So it seems like the transaction never gets finished. My logs don't show anything. It seems to me that in this part:

store.when()
    .productUpdated(product => this.refreshUI(product))
    .approved(transaction => transaction.verify())
    .verified(receipt => receipt.finish());

approved does not work. I tried setting logs and alerts but they never get called.

Does anyone know why approced is not being called? It feels like I am so close in getting this to work but it just does not finish my purchase...

Kamsou commented 3 months ago

Hello @thommydz , for me i should manage payment only in approved function. (keep your productUpdated brefore)

.approved((transaction) => {

  transaction.verify()

  if (transaction.state !== 'approved') return

  transaction.finish()
}