Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

DanielRønfeldt's avatar

Stripe wrongfully showing 0,00 amount to be charged

Hello,

I'm using a Vue-powered payment form built with simple Stripe Elements, where the users are subscribing to a paid yearly plan. The payments are successfully made, but the main problem is that during the 3D Secure payment process (we are operating in Europe, where 3DS payment checks are mandatory), the amount that is shown to the user is 0,00. Which is not only incorrect, but more importantly, confusing to the person about to making the payment.

As I described it in the image below, I am suspecting that this is happening because the credit card is first verified and "set up" on Stripe's end (an operation that apparently charges the card a "null" value), and then, subsequently, it will actually charge the amount we set up as the service's price. To our users, this is confusing and misleading.

screenshot

Here's my subscribeNow() method, which will run when a "Pay Now" button is clicked.

subscribeNow() {
  // ... some form validation logic...
  
  let _this = this;
  
  // Create a hashed Stripe token from the CardNumber Element
  _this.stripe.createToken(_this.cardNumber, {
    // ...
  })
  .then(function (result) {
    if( result.token ) { // we have a token, try to confirm setting up the card on Stripe
      //console.log('result.token = ', result.token); // OKAY !!!
      
      _this.stripe.confirmCardSetup(
        _this.intentToken.client_secret,
        {
          payment_method: {
            card: _this.cardNumber, // YES, the CardNumber Element CAN BE used in here
            
            billing_details: {
              name: _this.name, // filled up by the user
              email: _this.email, // filled up by the user
              phone: _this.phone, // filled up by the user
            }
          }
        }
      )
      .then(function (result) {
        // console.log('Result of stripe.confirmCardSetup(): ', result); // OKAY!!!
        
        // If NO setup intent was returned (pga card rejected osv)...
        if( undefined === result.setupIntent ) {
          // console.log('OnboardingStripeForm.vue > subscribeNow() method: CardSetup response: FAILED!!!');
          
          // ... some notification by using [result.error.message] incoming from Stripe 
          
          return; // exit method
        } // undefined === result.setupIntent
        
        // Otherwise, i.e. the setup intent was successful...
        if( "succeeded" === result.setupIntent.status ) {
          // console.log('OnboardingStripeForm.vue > subscribeNow() method: CardSetup response: SUCCESS!!!');
          
          _this.paymentMethods['default'] = result.setupIntent.payment_method;
          _this.paymentMethodSelected = _this.paymentMethods['default'];
          
          /**
           * Send an async (AXIOS-powered) request to the API to create a new subscription.
           * This in turn will run a method in PaymentController.php, which will simply 
           * make use of the Stripe method $user->newSubscription()->create()
           */
          _this.createNewSubscription();
          
          // Clear out card data
          _this.name = _this.email = _this.phone = '';
          _this.cardNumber.clear();
          _this.cardExpiry.clear();
          _this.cardCvc.clear();
          
        } else { // "succeeded" !== result.setupIntent.status
          // console.log('OnboardingStripeForm.vue > subscribeNow() method: CardSetup response: FAILED!!!');
        } // "succeeded" === result.setupIntent.status
      }.bind(this));
    } else if( result.error ) {
      // console.log('Error in subscribeNow() method: Stripe token NOT created: ', result.error);
      
      // ... some notification by using [result.error.message] incoming from Stripe 
    }
  }.bind(this));
},

Any idea on how to make the actual amount to be charged, visible to the user, during the 3DS screen?

Many thanks.

0 likes
8 replies
martinbean's avatar

@danielrønfeldt Why do you have properties for _cardNumber, _cardExpiry and _cardCvc? These should not be touching your server at all.

DanielRønfeldt's avatar

@martinbean they're merely references to the existing Stripe Elements. Configured like this:

/**
 * Configures Stripe by setting up the elements and creating the card element.
 */
configureStripe() {
  let _this = this;
  
  this.stripe = Stripe( this.stripePublicKey );
  this.elements = this.stripe.elements({
    locale: 'da'
  });
  
  this.cardNumber = this.elements.create('cardNumber', {
    showIcon: true,
    placeholder: 'Kortnummer',
    iconStyle: 'solid',
    style: this.elementStyles,
    class: this.elementClasses,
  });
  this.cardNumber.mount('#card-number-new');
  this.cardNumber.on('change', function (evt) {
    if( evt.error ) {
      // handle complete error...
      _this.cardNumberCompleted = false;
    } else if( evt.complete ) {
      _this.cardNumberCompleted = true;
    } else {
      _this.cardNumberCompleted = false;
    }
  });
  
  this.cardExpiry = this.elements.create('cardExpiry', {
    placeholder: 'Udløbsdato',
    showIcon: true,
    style: this.elementStyles,
    iconStyle: 'solid',
    class: this.elementClasses,
  });
  this.cardExpiry.mount('#card-expiry-new');
  this.cardExpiry.on('change', function (evt) {
    if( evt.error ) {
      // handle complete error...
      _this.cardExpiryCompleted = false;
    } else if( evt.complete ) {
      _this.cardExpiryCompleted = true;
    } else {
      _this.cardExpiryCompleted = false;
    }
  });
  
  this.cardCvc = this.elements.create('cardCvc', {
    placeholder: 'CVC-kode',
    showIcon: true,
    style: this.elementStyles,
    iconStyle: 'solid',
    class: this.elementClasses,
  });
  this.cardCvc.mount('#card-cvc-new');
  this.cardCvc.on('change', function (evt) {
    if( evt.error ) {
      _this.cardCvcCompleted = false;
      // handle complete error...
    } else if( evt.complete ) {
      _this.cardCvcCompleted = true;
    } else {
      _this.cardCvcCompleted = false;
    }
  });
},
DanielRønfeldt's avatar

@martinbean the Stripe Elements I'm using are only being instantiated client-side, so there's no problem with them residing on my server, did I understand it correctly? Or?

Juanjo's avatar

@DanielRønfeldt Hi Daniel, I have exactly same problem. Is weird to show zero amount and a few seconds later charge an amount.

It shouldn't be shown this zero.

Did you resolved it?

Please or to participate in this conversation.