简体   繁体   中英

Stripe is creating a customer but not charging the card

Stripe was working perfectly fine before but somewhere it stopped working properly. Stripe will create a new customer, but not charge the card provided so I'm not sure whats going on.

Logs within Stripe:

Status       Description

 402 err      POST /v1/charges
 200 OK       POST /v1/customers
 200 OK       POST /v1/tokens

Response Body:

{
  "error": {
    "code": "missing",
    "doc_url": "https://stripe.com/docs/error-codes/missing",
    "message": "Cannot charge a customer that has no active card",
    "param": "card",
    "type": "card_error"
  }
}

(But the card is being provided)

I have app.js in the root file and the HTML that contains this file is in public within root:

<form action="/charge" method="post" id="payment-form" style="margin-top: 40px;">
          <div class="form-row">
            <label for="card-element">
            Reservation Deposit (Credit or Debit Card)
          </label>
            <div id="card-element"><!-- a Stripe Element will be inserted here. --></div>

            <div id="card-errors"></div>
          </div>

          <p class="agree-to-terms text-center">
            By submitting the request, you agree to our <a href="terms.html">Terms of Use</a>
          </p>

          <div class="question-container" style="margin-top: 30px;">
            <button id="finalBackBtn" type="button" class="back-btn">BACK</button>
            <button id="furnitureBtn" type="submit" class="text-center next-btn">SUBMIT</button>
          </div>
        </form>

<script type="text/javascript">
    //Create a Stripe client
    var stripe = Stripe('...');

    // Create an instance of Elements
    var elements = stripe.elements();

    // Custom styling can be passed to options when creating an Element.
    var style = {
      base: {
        ...
        }
      },
      invalid: {
        ...
      }
    };

    // Create an instance of the card Element
    var card = elements.create('card', {
      style: style
    });

    // Add an instance of the card Element into the `card-element` <div>
    card.mount('#card-element');

    // Handle real-time validation errors from the card Element.
    card.addEventListener('change', function(event) {
      var displayError = document.getElementById('card-errors');
      if (event.error) {
        displayError.textContent = event.error.message;
      } else {
        displayError.textContent = '';
      }
    });

    // Handle form submission
    var form = document.getElementById('payment-form');
    form.addEventListener('submit', function(event) {
      event.preventDefault();

      stripe.createToken(card).then(function(result) {
        if (result.error) {
          // Inform the user if there was an error
          var errorElement = document.getElementById('card-errors');
          errorElement.textContent = result.error.message;
        } else {
          // Send the token to your server
          stripeTokenHandler(result.token);
        }
      });
    });

    function stripeTokenHandler(token) {
      // Insert the token ID into the form so it gets submitted to the server
      var form = document.getElementById('payment-form');
      var hiddenInput = document.createElement('input');
      var totalAmount = document.createElement('input');
      var customerEmail = document.createElement('input');

      hiddenInput.setAttribute('type', 'hidden');
      hiddenInput.setAttribute('name', 'stripeToken');
      hiddenInput.setAttribute('value', token.id);

      // Getting the deposit amount
      totalAmount.setAttribute('type', 'hidden');
      totalAmount.setAttribute('name', 'totalAmount');
      totalAmount.setAttribute('value', Number(document.getElementById('new_text2').innerHTML) * 100);

      customerEmail.setAttribute('type', 'hidden');
      customerEmail.setAttribute('name', 'email');
      customerEmail.setAttribute('value', document.getElementById('emailA').innerHTML);

      form.appendChild(hiddenInput);
      form.appendChild(totalAmount);
      form.appendChild(customerEmail);

      var formData = JSON.stringify({
        mytoken: token.id,
        totalAmount: totalAmount.value,
        customerEmail: customerEmail.value
      });

      $.ajax({
        type: "POST",
        url: "/charge",
        data: formData,
        success: function() {
          alert("done")
        },
        dataType: "json",
        contentType: "application/json"
      });

      form.submit();
    }
  </script>

And lastly, my app.js file:

const express = require('express');
const stripe = require('stripe')('...');
const bodyParser = require('body-parser');
const app = express();

const port = process.env.PORT || 13441;


if (process.env.NODE_ENV && process.env.NODE_ENV === 'production') {
  app.use((req, res, next) => {
    if (!req.secure && req.headers['x-forwarded-proto'] !== 'https') {
      res.redirect('https://' + req.headers.host + req.url)
    } else {
      next();
    }
  })
}

// Set Static Folder
app.use(express.static('public'));
app.use(bodyParser.json());

// charge route
app.post('/charge', (req, res) => {
  const amount = req.body.totalAmount;
  const email = req.body.customerEmail;

  stripe.customers.create({
    email: email,
    source: req.body.mytoken
  })
  .then(customer =>  {
    stripe.charges.create({
    amount,
    description:'Muve deposit request',
    currency:'USD',
    customer:customer.id
  })})
  .then(charge => res.sendFile('public/confirmationPage.html', {root: __dirname}));
});


app.listen(port, () => {
  console.log(`Server started on port ${port}`);
});

Anyone know what's going on?

Your code is calling your /charge endpoint twice, because you use $.ajax but also do form.submit() . That is creating two customers, one of which has no sources because the token is only added in the ajax request, and that's the customer you are getting the error for.

Easy fix is to remove the form.submit() line.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM