0

I am having two different problems integrating the new stripe version into my ionic v3 app.(please no suggestions on upgrading to ionic v5. That is not possible for our team right now!)

In my ionDidLoad i have:

var stripe = Stripe('pk_test_OwV8RfgF7JQp1FEW3OfqmPpz');
  var elements = stripe.elements();
  var style = {
    base: {
      color: "#32325d",
    }
  };

  var card = elements.create("card", { style: style });
  card.mount("#card-element");

  card.addEventListener('change', ({error}) => {
    const displayError = document.getElementById('card-errors');
    if (error) {
      displayError.textContent = error.message;
    } else {
      displayError.textContent = '';
    }
  });

  var form = document.getElementById('payment-form');

  form.addEventListener('submit', function(ev) {
    ev.preventDefault();

    stripe.confirmCardPayment( this.clientSecret, {
      payment_method: {
        card: card,
        billing_details: {
          name: 'Jenny Rosen'
        }
      }
    }).then(function(result) {
      if (result.error) {
        // Show error to your customer (e.g., insufficient funds)
        console.log(result.error.message);
      } else {
        // The payment has been processed!
        if (result.paymentIntent.status === 'succeeded') {

          /****  this.postOrder(); */

          // Show a success message to your customer
          // There's a risk of the customer closing the window before callback
          // execution. Set up a webhook or plugin to listen for the
          // payment_intent.succeeded event that handles any business critical
          // post-payment actions.
        }
      }
    });
  });

Problem #1: var stripe = Stripe('pk_test_*******************') VSCode is giving me the dreaded red squiggly line under "Stripe('pk_test...). The error from VS Code is "Value of type 'typeof Stripe' is not callable. Did you mean to include 'new'?ts(2348)" I am have googled etc. but am at a loss as to how to clear this error. I tried declaring "Stripe" but it didn't help. I know that Stripe is a reference in StripeJS.

Problem #2: stripe.confirmCardPayment( this.clientSecret, {... Again, the red squiggly line, this time under "this.clientSecret". this.clientSecret is defined in my app by the return of the paymentIntents call to my server as follows:

this.inStockService.paymentIntentRoutine(this.ot).subscribe(res => {
        this.clientSecret = res;
      });

The error from VSCode is "Property 'clientSecret' does not exist on type 'HTMLElement'.ts(2339)". I am not enough of a developer yet to understand what or why this is happening.

If anyone can help me solve these problems I would be forever grateful.

detourOfReason
  • 325
  • 1
  • 3
  • 11
  • For the second issue, it's because `this` gets rebound to the DOM element that triggered the event inside that form submit handler : https://stackoverflow.com/a/44153734/9769731 So usually that's why you see people using `self` for globals or so on. For the first issue, I've never used typescript so I don't know. The stripe.js library doesn't have typescript definitions, so you should probably just exclude these lines from the checker. – karllekko Feb 28 '20 at 10:27
  • @karllekko - Thanks. Re 2nd issue. That actually makes a lot of sense. I am gonna try to see what I can do about changing the scope. I am still at a loss as to #1 but I am working on it. – detourOfReason Feb 28 '20 at 16:21
  • for the first issue - how exactly do you import Stripe? just a script tag in the index.html from their source? – Sergey Rudenko Feb 28 '20 at 16:23
  • @ Sergey Rudenko -- yes, just a script tag in the index.html. I am implementing your suggestions below now and will update as soon as possible. – detourOfReason Feb 28 '20 at 17:28

1 Answers1

1

Issue #1:

Provided you imported Stripe via <script src="https://js.stripe.com/v3/"></script> in your index.html - the Stripe object becomes available via window global object as window.Stripe, you need to declare Stripe in the component right after your imports:

> declare var Stripe: any;

Or access stripe via window['Stripe'] in your code, which is also not great.

Also you could install types for Stripe version you are using to prevent TypeScript issues. Here is v3:

npm install --save @types/stripe-v3.

Issue #2:

You need to leverage fat arrow functions to prevent 'this' pointing at your anonymous function scope:

form.addEventListener('submit', ev => {

    ev.preventDefault();

    stripe.confirmCardPayment( this.clientSecret, {
      payment_method: {
        card: card,
        billing_details: {
          name: 'Jenny Rosen'
        }
      }
    }).then( result => {
      if (result.error) {
        // Show error to your customer (e.g., insufficient funds)
        console.log(result.error.message);
      } else {
        // The payment has been processed!
        if (result.paymentIntent.status === 'succeeded') {

          /****  this.postOrder(); */

          // Show a success message to your customer
          // There's a risk of the customer closing the window before callback
          // execution. Set up a webhook or plugin to listen for the
          // payment_intent.succeeded event that handles any business critical
          // post-payment actions.
        }
      }
    });
  });
Sergey Rudenko
  • 8,809
  • 2
  • 24
  • 51