Julian Porter
Julian Porter

Reputation: 217

Stripe 'card' not defined

I am following this tutorial: https://stripe.com/docs/billing/subscriptions/fixed-price. They never instantiate a variable called card, which leads me to believe that card is a stripe component that comes with "https://js.stripe.com/v3/". When I run the frontend, I get the following error: payment_portal:214 Uncaught ReferenceError: card is not defined. The error occurs in this codeblock, right here createPaymentMethod({ card });:

form.addEventListener('submit', function (ev) {
  ev.preventDefault();
  
  // If a previous payment was attempted, get the latest invoice
  const latestInvoicePaymentIntentStatus = localStorage.getItem(
    'latestInvoicePaymentIntentStatus'
  );
  
  if (latestInvoicePaymentIntentStatus === 'requires_payment_method') {
    const invoiceId = localStorage.getItem('latestInvoiceId');
    const isPaymentRetry = true;
    // create new payment method & retry payment on invoice with new payment method
    createPaymentMethod({
      card,
      isPaymentRetry,
      invoiceId,
    });
  } else {
    // create new payment method & create subscription
    createPaymentMethod({ card });
  }
});

I am going to dig through "https://js.stripe.com/v3/" to see if I can find an instance of card. Any help would be greatly appreciated.

Upvotes: 2

Views: 1528

Answers (1)

Shababb Karim
Shababb Karim

Reputation: 3703

I think you missed a few instructions and the doc certainly didn't help. By card I think the stripe doc meant cardElement from the other examples.

Here's a step-by-step guide I think which might help you:

First create elements instance. You probably have already done this. Keep this part of code in the global scope for simplicity:

var stripe = Stripe('<test-key>');
var elements = stripe.elements();

Now, you have stripe elements, which is stripe's way of binding your form element to a stripe card element. You probably have a form like this:

<body>
  <form id="subscription-form">
    <div id="card-element" class="MyCardElement">
      <!-- Elements will create input elements here -->
    </div>

    <!-- We'll put the error messages in this element -->
    <div id="card-errors" role="alert"></div>
    <button type="submit">Subscribe</button>
  </form>
</body>

The form input id is card-element, we will use this input element to be bounded to stripe card. We will do this inside window.onload:

window.onload = function() {

   var cardElement = elements.create("card");

   // This card element is the card that you are looking for 
   cardElement.mount("#card-element");

   
}

Over here, the cardElement is the card instance that you need to pass on form submit. I guess they forgot to rename in this example.

So the code should be something like this, notice I have changed the variable name from card to cardElement:

window.onload = function() {

   var cardElement = elements.create("card");

   // This card element is the card that you are looking for 
   cardElement.mount("#card-element");

   form.addEventListener('submit', function (ev) {
        ev.preventDefault();
​
        // If a previous payment was attempted, get the latest invoice
        const latestInvoicePaymentIntentStatus = localStorage.getItem(
           'latestInvoicePaymentIntentStatus'
        );
​
        if (latestInvoicePaymentIntentStatus === 'requires_payment_method') {
           const invoiceId = localStorage.getItem('latestInvoiceId');
           const isPaymentRetry = true;
           // create new payment method & retry payment on invoice with new payment 
           method
            createPaymentMethod({
               cardElement,
               isPaymentRetry,
               invoiceId,
            });
        } else {
           // create new payment method & create subscription
           createPaymentMethod({ cardElement });
        }
    });
}

Hopefully this works and the guys at Stripe fix the confusion with their examples.

Upvotes: 4

Related Questions