Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stripe with Google pay and Apple pay #1

Closed
filipnaumoski opened this issue Nov 18, 2019 · 25 comments
Closed

Stripe with Google pay and Apple pay #1

filipnaumoski opened this issue Nov 18, 2019 · 25 comments

Comments

@filipnaumoski
Copy link

How can I integrate Google pay and Apple pay using this capacitor plugin in ionic 4?
I don't see any documentation for this.

Thanks!

@ihadeed
Copy link
Member

ihadeed commented Nov 18, 2019

@filipnaumoski

I haven't had a chance to document the plugin yet.

You can take a look at the declaration file here:
https://github.com/zyra/capacitor-stripe/blob/master/packages/plugin/src/definitions.ts#L77-L156

Quick example:

import { Plugins } from '@capacitor/core';
const { StripePlugin } = Plugins;

// apple pay

// Option A: Charges
StripePlugin.payWithApplePay({
    merchantId: 'merchant.test.com', // apple merchant id
    country: 'CA', // 2 letter country code
    currency: 'CAD', // currency code
    items: [
      // list your items here so the user knows what they're paying for
      // tax + total are optional
      {
         label: 'Blue Tshirt',
         amount: 50,
      },
      {
         label: 'Tax',
         amount: 10,
      },
      {
         label: 'Total',
         amount: 60,
      }
    ]
})
.then((res) => {
  // send token to API and handle charge (res.token)
  // then call finalizeApplePayTransaction with the result to dismiss the UI modal
  StripePlugin.finalizeApplePayTransaction({ success: true })
})
.catch(err => {
  // something went wrong
  // user cancelled, integration issue, timeout ..etc
});

// Option #2: Payment Intents
StripePlugin.confirmPaymentIntent({
  clientSecret: 'secret from API',
  applePayOptions: { /* same as above */ },
})
.then(res => {
  // dismiss the apple pay modal in the UI
  // check with your server that everything is fine, depending on your PaymentIntent implementation
  StripePlugin.finalizeApplePayTransaction({ success: true })
})
.catch(err => {
  StripePlugin.finalizeApplePayTransaction({ success: false })
})



// google pay
StripePlugin.startGooglePayTransaction({
  // options not available in definitions file
  // can find some of them here: https://github.com/zyra/capacitor-stripe/blob/master/packages/plugin/android/src/main/java/ca/zyra/capacitor/stripe/StripePlugin.kt#L407-L483
})
.then(res => {
  StripePlugin.confirmPaymentIntent({ fromGooglePay: true });
})
.catch(err => {

});

@filipnaumoski
Copy link
Author

filipnaumoski commented Nov 19, 2019

Hello @ihadeed
I have issue with android build after set up capacitor stripe plugin.
Also on Apple Pay request i got error message "Unable to parse apple pay options: The operation couldn't be completed. (CapacitorStripe.StripePluginError error 0.)"

Android build issue

e: /PATH/node_modules/capacitor-stripe/android/src/main/java/ca/zyra/capacitor/stripe/StripePlugin.kt: (296, 24): None of the following functions can be called with the arguments supplied: 
@UiThread public final fun confirmPayment(activity: Activity, confirmPaymentIntentParams: ConfirmPaymentIntentParams): Unit defined in com.stripe.android.Stripe
@UiThread public final fun confirmPayment(fragment: Fragment, confirmPaymentIntentParams: ConfirmPaymentIntentParams): Unit defined in com.stripe.android.Stripe
e: /PATH/node_modules/capacitor-stripe/android/src/main/java/ca/zyra/capacitor/stripe/StripePlugin.kt: (296, 39): Cannot access class 'android.support.v7.app.AppCompatActivity'. Check your module classpath for missing or conflicting dependencies
e: /PATH/node_modules/capacitor-stripe/android/src/main/java/ca/zyra/capacitor/stripe/StripePlugin.kt: (328, 24): None of the following functions can be called with the arguments supplied: 
@UiThread public final fun confirmSetupIntent(activity: Activity, confirmSetupIntentParams: ConfirmSetupIntentParams): Unit defined in com.stripe.android.Stripe
@UiThread public final fun confirmSetupIntent(fragment: Fragment, confirmSetupIntentParams: ConfirmSetupIntentParams): Unit defined in com.stripe.android.Stripe
e: /PATH/node_modules/capacitor-stripe/android/src/main/java/ca/zyra/capacitor/stripe/StripePlugin.kt: (328, 43): Cannot access class 'android.support.v7.app.AppCompatActivity'. Check your module classpath for missing or conflicting dependencies
e: /PATH/node_modules/capacitor-stripe/android/src/main/java/ca/zyra/capacitor/stripe/StripePlugin.kt: (473, 31): Type inference failed: fun <TResult : AutoResolvableResult!> resolveTask(p0: Task<TResult!>, p1: Activity, p2: Int): Unit
cannot be applied to
(Task<PaymentData!>!,AppCompatActivity!,Int)

e: /PATH/node_modules/capacitor-stripe/android/src/main/java/ca/zyra/capacitor/stripe/StripePlugin.kt: (475, 21): Cannot access class 'android.support.v7.app.AppCompatActivity'. Check your module classpath for missing or conflicting dependencies
e: /PATH/node_modules/capacitor-stripe/android/src/main/java/ca/zyra/capacitor/stripe/StripePlugin.kt: (475, 21): Type mismatch: inferred type is AppCompatActivity! but Activity was expected

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':capacitor-stripe:compileDebugKotlin'.
> Compilation error. See log for more details
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/4.10.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 7s
35 actionable tasks: 16 executed, 19 up-to-date```

@ihadeed
Copy link
Member

ihadeed commented Nov 19, 2019

Regarding the Android build:
Your app needs to use AndroidX which isn't available in Capacitor latest version yet. See this PR for details.

To use Android X now you can do one of the following:

Install capacitor-android from that PR: there are some instructions here that I haven't tested but they should work.

or, here is what I did:

  1. Follow these steps (add 2 lines to gradle.properties, and run a built-in Android Studio tool)
  2. compile the app and go to any file that's causing a compile error. Remove any invalid imports in the file and re-import using the suggestion given by Android Studio (which will be an AndroidX library import)

@ihadeed
Copy link
Member

ihadeed commented Nov 19, 2019

That iOS error must be coming from this function: https://github.com/zyra/capacitor-stripe/blob/master/packages/plugin/ios/Plugin/Helper.swift#L172

It's possible that I did not implement the custom errors properly which is why you're seeing that generic error message.

I noticed I made a mistake in my example. I wrote merchantId but it's merchantIdentifier.

Check the following:

  • you provided all required fields: merchantIdentifier, country, currency, items
  • need at least one item in items array`
  • each item must have a label and an amount
    • amount must be numeric
    • amount must be greater than 0

@filipnaumoski
Copy link
Author

filipnaumoski commented Nov 21, 2019

Hey @ihadeed

Regarding the Android build:
Your app needs to use AndroidX which isn't available in Capacitor latest version yet. See this PR for details.

To use Android X now you can do one of the following:

Install capacitor-android from that PR: there are some instructions here that I haven't tested but they should work.

or, here is what I did:

  1. Follow these steps (add 2 lines to gradle.properties, and run a built-in Android Studio tool)
  2. compile the app and go to any file that's causing a compile error. Remove any invalid imports in the file and re-import using the suggestion given by Android Studio (which will be an AndroidX library import)

After capacitor android installation from PR I got this error message when i call function from this plugin on web and mobile (setPublishableKey('KEY'); startGooglePayTransaction(); payWithApplePay(); etc.)

Error: Uncaught (in promise): StripePlugin does not have web implementation.

p.s. I stuck with all of this, i need more info for set up this plugin and i need to implement all stripe payments like a credit card, gPay and iPay very soon.
Also i got same error message after changed merchantId to merchantIdentifier

@ihadeed
Copy link
Member

ihadeed commented Nov 27, 2019

@filipnaumoski thanks for the feedback

Looking into it now as I'm integrating it into an app. Will publish any necessary fixes soon.

@filipnaumoski
Copy link
Author

@ihadeed I managed to resolve the issue with GooglePay. The issue was in MainActivity.java - to be more specific, it was missing add(StripePlugin.class) in the bridge initialization function.

Additionally, there was an issue with Stripe API POST request in web.js, therefore I made some modification in CallStripeAPI function:

headers: Object.assign({ 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json', 'Authorization': ;Bearer ${key}' }, extraHeaders),
remove mode: 'no-cors'

Please, let me know if you have some update in regards to ApplePay. I am still working on this, however I haven't manage to find solution yet.

@ihadeed
Copy link
Member

ihadeed commented Nov 27, 2019

Thanks @filipnaumoski , I implemented your fix for the web and it seems to work well now.

As for iOS, I just ran a test and managed to successfully use Apple Pay. A few things to double check:

  1. I made another mistake above with the Apple Pay example. The parameters must be wrapped with applePayOptions. Example:
await Capacitor.Plugins.StripePlugin.payWithApplePay({ applePayOptions: { ... } });
  1. Make sure the merchant id is valid. See this guide for details: https://stripe.com/docs/apple-pay#merchantid

@ihadeed
Copy link
Member

ihadeed commented Nov 27, 2019

Releasing a new version now with the recent fixes/updates.

Breaking changes:

  • the plugin is now called Stripe instead of StripePlugin so you will need to update the imports (TypeScript & Android)
  • startGooglePayTransaction is now payWithGooglePay
  • google pay options must be in a googlePayOptions property:
Stripe.payWithGooglePay({ googlePayOptions: { ... } });

Probably will get rid of payWithGooglePay completely and just have an option to pass googlePayOptions in confirmPaymentIntent since there is no other use for it. But that will be in the next releases.

@san4ezgig
Copy link

Pls, add to "installation" that Stripe.setPublishableKey call need before plugin usage

@ihadeed
Copy link
Member

ihadeed commented Jan 16, 2020

@san4ezgig will do as soon as I get a chance to work on the docs. For now if it requires the publishable key it should throw a console error message.

@josebyte
Copy link

josebyte commented Jan 17, 2020

Hi! I'm using the version 0.4.0 and I want to pay with stripe in Applepay and Googlepay.
I copy the code above and adapt it like that but didn't work:

    confirmWithGooglePay() {
        Stripe.payWithGooglePay({
            clientSecret: 'mysecretstripekey',
            googlePayOptions: { // just demo options
                currencyCode: 'EUR',
                totalPrice: 1.00,
                totalPriceStatus: 'FINAL',
                allowedAuthMethods: ['PAN_ONLY'],
                allowedCardNetworks: ['VISA', 'MASTERCARD']
            },
        }).then(res => {
            console.log(res)
            this.result = res;
            Stripe.confirmPaymentIntent({clientSecret: 'mysecretstripekey', fromGooglePay: true });
            })
            .catch(err => {
                console.log(err)
                this.error = err;
            });
    }

What I'm doing wrong? The error is: "No such Payment_intent"
Can I use TEST environment? How?

@josebyte
Copy link

Please, can you give us a working example for test it?

@san4ezgig
Copy link

san4ezgig commented Jan 22, 2020

@josebyte
const { token } = await Stripe.payWithApplePay({ applePayOptions: { merchantIdentifier: MERCHANT_IDENTIFIER, items: [ { label: name, amount: price, }, ], currency: 'USD', country: 'US', }, });

0.4.0 version

@josebyte
Copy link

Thank you @san4ezgig :)
Do you have an example like this also for GooglePay?
Now I have a token key "tok_" but I need a charge "ch_". How can I get the charge?

Thanks in advance!!

@hellokingdom
Copy link

@ihadeed I managed to resolve the issue with GooglePay. The issue was in MainActivity.java - to be more specific, it was missing add(StripePlugin.class) in the bridge initialization function.

Additionally, there was an issue with Stripe API POST request in web.js, therefore I made some modification in CallStripeAPI function:

headers: Object.assign({ 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json', 'Authorization': ;Bearer ${key}' }, extraHeaders),
remove mode: 'no-cors'

Please, let me know if you have some update in regards to ApplePay. I am still working on this, however I haven't manage to find solution yet.

DId you manage to get Apple Pay working? I have the same error as you:

"Unable to parse apple pay options: The operation couldn't be completed. (CapacitorStripe.StripePluginError error 0.)"

@Seanmclem
Copy link

Seems like some docs are getting added
https://github.com/zyra/capacitor-stripe/tree/master/.docs/pages

@Seanmclem
Copy link

Seanmclem commented Feb 19, 2020

@ihadeed I was able to add Google pay to my app, but I'm not sure I did it right. I used my server-side to initialize a payment_intent for the clientSecret.. Is that right?

After using payWithGooglePay, it returns nothing, and I go straight to confirmPaymentIntent, but I need to interact with the paymentMethod before I confirm.

Edit: actually nevermind I don't know what I was thinking. Apple wouldn't let me set up an app subscription using the official Apple pay API. I need to use a webview and web APIs.

@JoshuvaGeorge03
Copy link

JoshuvaGeorge03 commented Mar 9, 2020

@ihadeed I am having below error, when i try to do paywithGooglePay in my app.

let me summarized the steps to reproduce the issue.

When I invoke payWithGooglePay, then action sheet is opened, followed up with the error alert box pops up.

Request failed:

Unexpected developer error, please try again later.

Please advice, what this means? And also please advice, how to do payment with google pay and apple pay?

@JoshuvaGeorge03
Copy link

JoshuvaGeorge03 commented Mar 9, 2020

@ihadeed I have found out the reason for the above error. Please see below

03-09 11:54:24.137 13820 13820 W WalletMerchantError: Error in loadPaymentData: PaymentDataRequest.allowedPaymentMethods[0].parameters.allowedCardNetworks[0] = AMERICAN_EXPRESS is not a valid enum value for this field.
03-09 11:54:27.606 13820 13820 W WalletMerchantError: Error in loadPaymentData: PaymentDataRequest.allowedPaymentMethods[0].parameters.allowedCardNetworks[0] = AMERICAN_EXPRESS is not a valid enum value for this field.
03-09 11:54:43.038 13820 13820 W WalletMerchantError: Error in loadPaymentData: PaymentDataRequest.allowedPaymentMethods[0].parameters.allowedCardNetworks[0] = AMERICAN_EXPRESS is not a valid enum value for this field.


03-09 11:55:14.504 13820 13820 W WalletMerchantError: Error in loadPaymentData: PaymentDataRequest.allowedPaymentMethods[0].parameters.allowedCardNetworks[0] = UNKNOWN is not a valid enum value for this field.
03-09 11:56:18.973 13820 13820 W WalletMerchantError: Error in loadPaymentData: PaymentDataRequest.allowedPaymentMethods[0].parameters.allowedCardNetworks[0] = UNKNOWN is not a valid enum value for this field.
03-09 11:56:21.028 13820 13820 W WalletMerchantError: Error in loadPaymentData: PaymentDataRequest.allowedPaymentMethods[0].parameters.allowedCardNetworks[0] = UNKNOWN is not a valid enum value for this field.
03-09 11:56:24.536 13820 13820 W WalletMerchantError: Error in loadPaymentData: PaymentDataRequest.allowedPaymentMethods[0].parameters.allowedCardNetworks[0] = UNKNOWN is not a valid enum value for this field.

and please advice, why UNKNOWN is not valid enum and Why AMERICAN_EXPRESS not a valid enum. But these values are present in enum.

If i put visa or master card in allowed card networks payment sheet opens with out any alert box

@JoshuvaGeorge03
Copy link

JoshuvaGeorge03 commented Mar 10, 2020

@ihadeed Please respond for my queries, I am having lot of issues with this plugin. I need you clarification and guidance for this.

When I do confirm payment Intent with googlePayOptions, I got below error. I create payment intent from server. and then passing my client secret to stripe plugin cofirm payment intent. But I got the error. Please see the below code and advice.

const stripePublishable = await this.
        cinchSrv.fs.doc$<any>('${environment.appConfig.commerceAccount}/meta/stripe-publishable')
        .pipe(take(1)).toPromise();
      await Stripe.setPublishableKey({ key: stripePublishable.publishableKey });
      await Stripe.confirmPaymentIntent({
        clientSecret: cs,
        googlePayOptions: {
          merchantName: 'test',
          totalPrice: 100,
          totalPriceStatus: 'FINAL',
          currencyCode: 'NOK',
          allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
          allowedCardNetworks: [ 'MASTERCARD', 'VISA'],
        }
"unable to complete transaction: You cannot confirm this PaymentIntent because it's missing a payment method. You can either update the PaymentIntent with a payment method and then confirm it again, or confirm it again directly with a payment method."

I can't able to use payWithGooglePay also, because it return void rather than token response. Please advice.

@Sahil624
Copy link

Hi,
I am getting an error
ERROR Error: Uncaught (in promise): Stripe does not have web implementation..
Not sure if some setup issues or something. Can add more info if wanted about the issue.
Thanks.

@bolekro
Copy link

bolekro commented Apr 28, 2020

After using payWithGooglePay, it returns nothing, and I go straight to confirmPaymentIntent, but > I need to interact with the paymentMethod before I confirm.

See pull request #9 for payWithGooglePay fix

@ihadeed ihadeed closed this as completed Jun 21, 2020
ihadeed pushed a commit that referenced this issue Dec 31, 2020
@madmacc
Copy link

madmacc commented May 11, 2021

Hi,
I am getting an error
ERROR Error: Uncaught (in promise): Stripe does not have web implementation..
Not sure if some setup issues or something. Can add more info if wanted about the issue.
Thanks.

@bolekro I got this error when I had forgotten to run npx cap sync ios. Once I did that I moved on to the next error.

@madmacc
Copy link

madmacc commented May 11, 2021

@ihadeed Thanks for the example. It worked well for me.

Is there a way to use this for a Stripe Connect account?
Or do I have to put the Stripe Public Key for each account when I configure with Stripe.setPublishableKey() ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants