zyra / cordova-plugin-stripe

A Cordova plugin that lets you use Stripe's Native SDKs for Android and iOS.
MIT License
93 stars 57 forks source link

Stripe with Google pay and Apple pay #54

Open testersoftware opened 5 years ago

testersoftware commented 5 years ago

I checked plugin code and notice that only you provide card payment and also check in stripe it's provide google pay and apple pay my Question is that :- How can I integrate Google pay and Apple pay using this plugin in ionic4? please guide me

ihadeed commented 5 years ago

The master branch currently uses an older version of Stripe SDK. You need to download the plugin from the v2 branch:

cordova plugin add git+https://github.com/zyra/cordova-plugin-stripe.git#v2

As for Ionic usage; Ionic Native currently doesn't have an updated wrapper for this v2 branch. We will take care of that as soon as it's finalised. For now you can do something like this:

import { CordovaStripe } from 'cordova-plugin-stripe';

interface Cordova {
  plugins: {
    stripe: typeof CordovaStripe.Plugin;
  }
}

function Promisify<T = any>(func, ...args: any[]): Promise<T> {
  return new Promise<T>((resolve, reject) => {
    func.apply(func, [...args, resolve, reject]);
  });
}

declare const cordova: Cordova;

@Injectable()
export class StripeProvider {

  constructor(plt: Platform) {
    plt
      .ready()
      .then(() => Promisify(cordova.plugins.stripe.setPublishableKey, 'YOUR KEY HERE'))
      .then(() => console.log('done setting publsihable key'))
      .catch(err => 'Error setting publishable key');
  }

  async updateCreditCard(card: CordovaStripe.CardTokenRequest) {
          const res = await Promisify<CordovaStripe.CardTokenResponse>(cordova.plugins.stripe.createCardToken, card);
          // res should contain card object
  }
}

Please note that the v2 branch is still in beta, we may release breaking changes at any point. It seems to be stable so far and we are using it in production in one of our apps.

giladrom commented 5 years ago

How does the Apple Pay support actually work? I looked in the code but couldn't find a JS function that initializes it?

ihadeed commented 5 years ago

@giladrom see this https://github.com/zyra/cordova-plugin-stripe/blob/v2/www/CordovaStripe.js#L107

The options are here: https://github.com/zyra/cordova-plugin-stripe/blob/v2/www/CordovaStripe.d.ts#L95

const opts = {
  ....
};

const success = (token, cb) => {
  // token is the payment authorization token
  // cb is a callback function that accepts a boolean. Pass `true` to capture payment or `false` to discard it.
};

const error = (err) => {
  ...
};

cordova.plugins.stripe.payWithApplePay(opts, success, error);
loomtronic commented 5 years ago

Is there any update on this? What about Google Pay? Why does there not seem to be anything on Google Pay and Ionic? Thanks!

giladrom commented 5 years ago

@loomtronic I ended up using this: https://github.com/monoku/cordova-plugin-applepay-stripe

And I can only assume there's no Google Pay because no one actually uses it.

ihadeed commented 5 years ago

@loomtronic Google Pay is also functional in the beta branch

loomtronic commented 5 years ago

It's hard for me to believe that Google Pay isn't being used by anyone. If you want to have payments and you're building a hybrid app, it just seems logical you'd want to use both. I could be wrong, it's happened before... once ;)

giladrom commented 5 years ago

You're absolutely right - I'm just speaking from a personal perspective, I've been using Apple Pay since the get go and have made a point of checking how people pay for their groceries whenever I go - I've never actually seen anyone use an Android phone for contactless payment. But that's obviously anecdotal.

RedEars commented 5 years ago

@ihadeed Google Pay doesn't actually work in the current beta branch because the "payWithGooglePay" method does not exist in CordovaStripe.java. As a workaround I changed the cordova.exec call to "createGooglePayToken" which exists in the java file. It was also needed to change data.getString(2) to data.getString(1) in the "createGooglePayToken" switch case of the execute function at CordovaStripe.java

IsaacHub commented 5 years ago

@ihadeed Google Pay doesn't actually work in the current beta branch because the "payWithGooglePay" method does not exist in CordovaStripe.java. As a workaround I changed the cordova.exec call to "createGooglePayToken" which exists in the java file. It was also needed to change data.getString(2) to data.getString(1) in the "createGooglePayToken" switch case of the execute function at CordovaStripe.java

I have done as you said, but I'm getting Invalid action returned from the error callback of the following code:

const opts = {
    amount: '5',
    currencyCode: 'inr'
};
const success = (token: TokenResponse) => {
    console.log("GPay token:" + token);
};
const error = (err) => {
    console.log(err)
};
cordova.plugins.stripe.payWithGooglePay(opts, success, error); 

Getting the same error even without modifying those files. I'm using it with Ionic V3. The following is my build.gradle

dependencies {
    implementation fileTree(dir: 'libs', include: '*.jar')
    implementation(project(path: ":CordovaLib"))
    compile "com.google.android.gms:play-services-auth:11.4.2"
    compile "com.google.android.gms:play-services-identity:11.4.2"
    compile "com.google.android.gms:play-services-wallet:11.4.2"
    compile "com.android.support:support-v4:26.0.1"
    compile "com.android.support:appcompat-v7:26.0.1"
    compile "com.stripe:stripe-android:8.1.0"
}

I have tried several combinations(but always using the same version as seen in build.gradle), but getting the same Invalid action error. I see that Google pay implementation is not verified from the pull request(v2 branch is still broken I guess). The function cordova.plugins.stripe.initGooglePay() is working fine and returns OK as response.

Could someone help me? It will be a great help for others too.

RedEars commented 5 years ago

@IsaacHub Did you change "payWithGooglePay" on this line https://github.com/zyra/cordova-plugin-stripe/blob/6bfc88c8bbed5aee4698aaec87f6fe84eb20f1b9/www/CordovaStripe.ts#L370 to "createGooglePayToken"? I got the same error in the beginning and changed the action name (as stated above) in order to work. But the plugin won't work anyways for google. The google pay window opens but there is no return at all. I moved to a different Cordova plugin (https://github.com/kartikk/cordova-plugin-dynamic-googlepay-stripe and https://github.com/osikes/cordova-plugin-dynamic-applepay-stripe) because this repo seems very inactive (v2 is in work since almost 2 years) and I think it takes a lot more time until it will be fixed, finished and finally published v2

IsaacHub commented 5 years ago

Yes. I have changed that line and error remains though. I will checkout those links you provided..

IsaacHub commented 5 years ago

@RedEars The plugin you referred is triggering the Gpay window and once Gpay opens up, it's asking for card number, expiry and CVC.

My question is why Gpay is asking to add card information while bank account is already linked? Is this the supposed workflow? Is "stripe using Gpay" only work with card? and not by bank account?

RedEars commented 5 years ago

@IsaacHub Stripe only supports credit and debit cards as payment source from google pay as stated here: https://stripe.com/docs/google-pay

iphubpush commented 5 years ago

@IsaacHub Did you change "payWithGooglePay" on this line

https://github.com/zyra/cordova-plugin-stripe/blob/6bfc88c8bbed5aee4698aaec87f6fe84eb20f1b9/www/CordovaStripe.ts#L370

to "createGooglePayToken"? I got the same error in the beginning and changed the action name (as stated above) in order to work. But the plugin won't work anyways for google. The google pay window opens but there is no return at all. I moved to a different Cordova plugin (https://github.com/kartikk/cordova-plugin-dynamic-googlepay-stripe and https://github.com/osikes/cordova-plugin-dynamic-applepay-stripe) because this repo seems very inactive (v2 is in work since almost 2 years) and I think it takes a lot more time until it will be fixed, finished and finally published v2

Hey, we are also using the same plugin to integrate stripe apple pay in our app: https://github.com/osikes/cordova-plugin-dynamic-applepay-stripe

In this plugin after payment we are only getting 'paymentData' and 'transactionIdentifier', but we need stripeToken to charge the user. Are you able to get the token? Please help.

ofyzero commented 5 years ago

I added my code to my app and stripe works %100 , but after calling cordova.plugins.stripe.payWithApplePay(opts, success, error); method app is frozen and i can not get any response. Do you have any idea ? I am using ionic 5.4.2 , cordova 7.2.2.

SRV-Garg commented 5 years ago

Hi, I am also facing the same problem. How can we get the stripe token after the payment successful?

On Tue, Oct 29, 2019 at 12:39 AM ofyzero notifications@github.com wrote:

I added my code to my app and stripe works %100 , but after calling cordova.plugins.stripe.payWithApplePay(opts, success, error); method app is frozen and i can not get any response. Do you have any idea ? I am using ionic 5.4.2 , cordova 7.2.2.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/zyra/cordova-plugin-stripe/issues/54?email_source=notifications&email_token=AGIHFYYZA2RSR3TKMAQX3LDQQ42HBA5CNFSM4GOTFB62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOECOBVQI#issuecomment-547101377, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGIHFY6ERKSRUGWSCQTEYILQQ42HBANCNFSM4GOTFB6Q .

ofyzero commented 5 years ago

This is the example of payWithApplePay and i added an example of NodeJS server for charge request . Here it is : https://gist.github.com/ofyzero/43f4e7400982e9c427dbedd696de587e

vijaystudio45 commented 5 years ago

@ofyzero Thank you i will check that.

TravBradfield commented 4 years ago

@ihadeed Hello! :)

Has this progressed any further? Is there an Ionic wrapper for the Google Pay implementation yet? Thanks very much.

sanctus671 commented 4 years ago

Has anyone got Apple Pay actually working? Whenever I call the function cordova.plugins.stripe.payWithApplePay(opts, success, error); nothing happens. I don't even get any error. Any ideas?

@TravBradfield I modified the code to get Google Pay working. You can see this here: https://github.com/sanctus671/cordova-plugin-stripe/tree/v2. Just put declare const cordova: any; in the imports area in your .ts file. And then you can call:

cordova.plugins.stripe.initGooglePay(() => {
        cordova.plugins.stripe.payWithGooglePay({
            amount:10,
            currencyCode: 'USD'
        }, (data) => {
//data.id is the token
        }, (e) => {
            console.log(e);
        });
}, () => {
 })
TravBradfield commented 4 years ago

Hello @sanctus671!

Yes I have got Apple Pay working...

the global variables will be:

supportedNetworks: any = ['visa', 'amex', 'masterCard', 'discover']; merchantCapabilities: any = ['3ds', 'debit', 'credit']; merchantIdentifier: string = 'merchant.ultra-booking.app'; currencyCode: string = 'GBP'; countryCode: string = 'GB'; billingAddressRequirement: any = ['Trav test', 'testtrav@mailinator.com', '07377444422']; shippingAddressRequirement: any = ['Trav test', 'testtrav@mailinator.com', '07377444422']; shippingType: string = "service"

The method to call for Apple Pay:

`async payWithApplePay() { console.log('*** payWithApplePay()'); var stripe = Stripe('pk_test_Stripe_Key');

let items: any = [
  {
    label: 'Online Product',
    amount: 10
  }
];
let shippingMethods: any = [
  {
    identifier: 'Available',
    label: 'Apple Pay',
    detail: "lovely product"
    amount: 10.00
  }
];

try {
  let order: any = {
    items: items,
    shippingMethods: shippingMethods,
    merchantIdentifier: this.merchantIdentifier,
    currencyCode: this.currencyCode,
    countryCode: this.countryCode,
    billingAddressRequirement: this.billingAddressRequirement,
    shippingAddressRequirement: this.shippingAddressRequirement,
    shippingType: this.shippingType,
    merchantCapabilities: this.merchantCapabilities,
    supportedNetworks: this.supportedNetworks
  }
  console.log('*** paymentRequest Order: ', order);
  this.applePay.makePaymentRequest(order).then(message => {
    console.log("*** makePaymentRequest: ", message);
    let token = message.paymentData;
    console.log('Base64encoded: ', JSON.stringify(token));
    console.log('Base64decoded: ', JSON.parse(atob(message.paymentData)));

    let request = {
      tokenIntent: {
        email: "test@email.com"
        name: "Trav Test",
        token: atob(message.paymentData),
        type: "Apple-Pay",
        currency: "gbp",
      }
    }

    console.log('REQUEST REQUEST REQUEST REQUEST: ', request);

    console.log("/* This next bit is where you send the payment intent to your backend */");

    this.paymentService.stripeWebHookRoute(request).subscribe(paymentRes => {
      console.log('Payment Res: ', paymentRes);
      console.log('Your booking is complete!');

      this.applePay.completeLastTransaction('success').then(complete => {
        console.log('*** ApplePay Success: ', complete);
        }).catch(err => {
          console.log('Error saving transaction: ', err);
      });
    }, err => {
      console.log('Error on payment Res: ', err);
    });
  }).catch(error => {
    console.log("*** makePaymentRequest ERROR: ", error);
    this.applePay.completeLastTransaction('failure');
    this.presentAlert(error);
  });

} catch {
  // handle payment request error
  // Can also handle stop complete transaction but these should normally not occur
}

}`

TravBradfield commented 4 years ago

@sanctus671 Please let me know if that is helpful to you? Thanks!

sanctus671 commented 4 years ago

@sanctus671 Please let me know if that is helpful to you? Thanks!

Thanks but this looks like it is not this plugin but rather the generic Apply Pay cordova plugin without Stripe. How are you able to process the request in Stripe on the backend without a Stripe token?

TravBradfield commented 4 years ago

@sanctus671 Oh yes, you're right.

Apple Pay effectively generates a card, so you use your Stripe backend functions to create the stripe token. Apple Pay returns a 'card token' which you send to your backend when creating the string payment intent

sanctus671 commented 4 years ago

@TravBradfield The token generated with that plugin is not Stripe compatible though. How are you able to generate a Stripe token from that? What Stripe API end point are you using on the backend?

TravBradfield commented 4 years ago

@sanctus671 Have a look at

let request = { tokenIntent: { email: "test@email.com" name: "Trav Test", token: atob(message.paymentData), type: "Apple-Pay", currency: "gbp", } }

This request goes to your backend. the paymentData field is Stripe compatible. I'm using this in production at the moment taking payments happily. Perhaps if you share your code we can have a look and help debug?

josebyte commented 4 years ago

@sanctus671 Is your repo working for Apple pay? Can you give us an example?

sanctus671 commented 4 years ago

@josebyte yes it is. Here is an example:

                    let appleItems = [];

                    for (let item of items){
                        appleItems.push({label:item.name, amount:(item.price * item.quantity).toFixed(2)});
                    }

                    const opts = {
                        merchantId: "YOUR APPLE MERCHANT ID",
                        country:"US",
                        currency:"USD",
                        items: appleItems
                    };

                    const success = (token, cb) => {
                        this.completeOrder(token.id);   
                        cb("true");                     
                    }

                    const error = (e) => {
                        alert(e);
                    }

                    cordova.plugins.stripe.payWithApplePay(opts, success, error);

items are an array of items. In my case this is someones shopping cart. Ensure each item is set to 2 decimal places or else it will fail (that's the .toFixed(2) part) this.completeOrder is a function you need to create that takes the stripe token and then sends it to the server to complete the charge

One other thing to note is that Apple Pay only works on iPhone 6 or greater. This plugin doesn't provide errors so I pulled my hair for a while until I realized that fact. Probably obvious to everyday Apple users but I'm an Android user so didn't realize!

josebyte commented 4 years ago

Thanks!! But I didn't make it work, I have the following crash error with this code after the setpublishablekey:

      const item = {
            merchantId: 'merchant.com.mycompanyid',
            country: 'ES',
            currency: 'EUR',
            items: [{
                label: "My label",
                amount: 100.00,
            }]
        };

        const success = (token, cb) => {
            this.completeOrder(token.id);   
            cb("true");                     
        }

        const error = (e) => {
            alert(e);
        }

        cordova.plugins.stripe.payWithApplePay(item, success, error);

Callback ID is CordovaStripe1176650167 APP INACTIVE [App.AppDelegate paymentAuthorizationViewController:didAuthorizePayment:completion:]: unrecognized selector sent to instance 0x6000016ffd00 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[App.AppDelegate paymentAuthorizationViewController:didAuthorizePayment:completion:]: unrecognized selector sent to instance 0x6000016ffd00' First throw call stack: ( 0 CoreFoundation 0x00007fff23c4f02e __exceptionPreprocess + 350 1 libobjc.A.dylib 0x00007fff50b97b20 objc_exception_throw + 48 2 CoreFoundation 0x00007fff23c6ff94 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132 3 UIKitCore 0x00007fff4787df39 -[UIResponder doesNotRecognizeSelector:] + 302

josebyte commented 4 years ago

Is working on Google Pay but when I try to move from test environment to production I have this error: "the merchant is not enabled for google pay" I have to configure something more?

sanctus671 commented 4 years ago

@josebyte see here: https://developers.google.com/pay/api/android/guides/test-and-deploy/request-prod-access

sanctus671 commented 4 years ago

Anyone else having issues with Apple Pay since iOS 13.3? It's suddenly stopped working since that update.

pookdeveloper commented 4 years ago

What package I have to install to use stripe google pay ? Thanks

colbytown commented 3 years ago

let request = { tokenIntent: { email: "test@email.com" name: "Trav Test", token: atob(message.paymentData), type: "Apple-Pay", currency: "gbp", } }

This request goes to your backend. the paymentData field is Stripe compatible. I'm using this in production at the moment taking payments happily. Perhaps if you share your code we can have a look and help debug?

@TravBradfield What are you calling on the stripe API side to complete this?

jcernjak commented 3 years ago

@ihadeed Is there any way to get Google Pay working with Ionic? I tried using the v2 branch and I'm getting GooglePay not supported. error. I would be very thankful for any information on this!

ihadeed commented 3 years ago

@ihadeed Is there any way to get Google Pay working with Ionic? I tried using the v2 branch and I'm getting GooglePay not supported. error. I would be very thankful for any information on this!

It's WIP on Cordova, currently available on Capacitor.

kvengerov commented 3 years ago
let request = {
  tokenIntent: {
    email: "test@email.com"
    name: "Trav Test",
    token: atob(message.paymentData),
    type: "Apple-Pay",
    currency: "gbp",
  }
}

this.paymentService.stripeWebHookRoute(request).subscribe(paymentRes => {
  console.log('Payment Res: ', paymentRes);
  console.log('Your booking is complete!');

Hello @TravBradfield I am doing data transfer from apple pay to stripe. I saw your implementation, but it is not clear to me which method from the stripe library you are calling. Perhaps this is paymentIntents.create()?

Phoenix-Alpha commented 3 years ago

@ihadeed, any progress with Apple Pay & Google Pay for cordova ? And does this plugin support Microsoft Pay?

sandy1198 commented 2 years ago

Thanks!! But I didn't make it work, I have the following crash error with this code after the setpublishablekey:

    const item = {
          merchantId: 'merchant.com.mycompanyid',
          country: 'ES',
          currency: 'EUR',
          items: [{
              label: "My label",
              amount: 100.00,
          }]
      };

      const success = (token, cb) => {
          this.completeOrder(token.id);   
          cb("true");                     
      }

      const error = (e) => {
          alert(e);
      }

      cordova.plugins.stripe.payWithApplePay(item, success, error);

Callback ID is CordovaStripe1176650167 APP INACTIVE [App.AppDelegate paymentAuthorizationViewController:didAuthorizePayment:completion:]: unrecognized selector sent to instance 0x6000016ffd00 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[App.AppDelegate paymentAuthorizationViewController:didAuthorizePayment:completion:]: unrecognized selector sent to instance 0x6000016ffd00' First throw call stack: ( 0 CoreFoundation 0x00007fff23c4f02e __exceptionPreprocess + 350 1 libobjc.A.dylib 0x00007fff50b97b20 objc_exception_throw + 48 2 CoreFoundation 0x00007fff23c6ff94 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132 3 UIKitCore 0x00007fff4787df39 -[UIResponder doesNotRecognizeSelector:] + 302

Same error coming if any update please let me know

my error You're using your Stripe testmode key. Make sure to use your livemode key when submitting to the App Store!

Callback ID is CordovaStripe851949724 THREAD WARNING: ['CordovaStripe'] took '17.274902' ms. Plugin should use a background thread. [General] Connection to remote alert view service failed