DanielRønfeldt's avatar

How to access the values of Stripe Elements?

Hello Laracasts Community,

I'm building a subscription payment form driven by stand-alone Stripe Elements for each of the "Card Number", "Card Expiry", and "Card CVC" fields. I am aware of the fact that I could've simply used a Card element, but I need the flexibility provided by stand-alone elements, and therefore a simple Card element is an absolute no-go in this case.

I've got almost everything figured out (including backend - routes, controllers etc), but now I'm stuck because I simply have no idea on how to access the user-provided values of the input fields of type cardNumber, cardExpiry nor cardCvc.

In other words, within the subscribeNow() method, I indend to send the user-provided card details over to Stripe. In order to do so, I'm trying to get the value within each of the 3 Elements described above. None of them is playing nicely, as in, they don't seem to allow me to access their values. What's the correct approach to this problem?

My Elements are set up like so:

<!-- within the template tag -->

<div class="row">
  <!-- Empty divs to mount each necessary Stripe Element into  -->
  <div id="card-number-new"></div>
  <div id="card-expiry-new"></div>
  <div id="card-cvc-new"></div>
</div>
// within the script tag > methods

configureStripe() { // it's called after component mounting
  this.stripe = Stripe( this.sripePublicKey );
  this.elements = this.stripe.elements({ locale: 'da' });
  
  this.cardNumber = this.elements.create('cardNumber', {
    showIcon: true,
    placeholder: 'Kortnummer',
  });
  this.cardNumber.mount('#card-number-new');
  
  this.cardExpiry = this.elements.create('cardExpiry', {
    placeholder: 'Udløbsdato',
    showIcon: true,
  });
  this.cardExpiry.mount('#card-expiry-new');
  
  this.cardCvc = this.elements.create('cardCvc', {
    placeholder: 'CVC-kode',
    showIcon: true,
  });
  this.cardCvc.mount('#card-cvc-new');
}

Below there is my subscribeNow() method (simplified code). The method is attached to the @click event on an arbitrary button I'm using for testing purposes, which is not displayed unless all three card fields are properly filled in.

subscribeNow() {
  this.stripe.confirmCardSetup(
    this.intentToken.client_secret, {
      payment_method: {
        card: {
          number: this.cardNumber, // <<< PROBLEM HERE, undefined
          exp_month: this.cardExpiry.exp_month, // <<< PROBLEM HERE, undefined
          exp_year: this.cardExpiry.exp_year, // <<< PROBLEM HERE, undefined
          cvc: this.cvc, // <<< PROBLEM HERE, undefined
        },
        
        // Card owner's details
        billing_details: {
          // ommitted for brevity
        }
      },
    }
  )
  .then( function(result) {
    console.log(result);
  }.bind(this) );
}
0 likes
5 replies
martinbean's avatar
Level 80

@danielrønfeldt No, no, no.

You don’t access the values on your server at all, as that defeats the entire point of using Stripe Elements.

You use Stripe Elements to tokenise a payment method, and then you use the token in your code; not the actual payment information itself.

Please, read up on how to actually use Stripe and tokenised payment methods. Because as soon as any payment details information (card number, CVC, etc) touches your server, you then have the burden of PCI compliance. Whereas if you just let Stripe do its job and handle payment details for you, the PCI compliance burden stays their side.

This is why Stripe Elements has a single, all-in-one element: because you never deal with the individual components (card number, CVC) but rather the token Stripe creates from those details.

2 likes
jlrdw's avatar

@danielrønfeldt you really need to read all of this, and do this stuff legally.

https://stripe.com/guides/pci-compliance

Don't look at just small parts of stripe, learn all well if using stripe. And follow their documentation. You are not supposed to deal with the cc at all on your server.

If you are unsure how to do this, I'd suggest you hire a consultant to assist you in getting it correct.

2 likes

Please or to participate in this conversation.