Stripe正在创建客户,但未向卡收费

时间:2018-06-27 17:08:19

标签: javascript node.js stripe-payments

Stripe之前运行正常,但在某处停止正常运行。 Stripe将创建一个新客户,但不会对所提供的卡收费,因此我不确定会发生什么。

Stripe内的日志:

Status       Description

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

响应正文:

{
  "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"
  }
}

(但正在提供卡)

我在根文件中有 app.js ,并且包含此文件的 HTML 在根目录中是公开的:

<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>

最后,我的 app.js 文件:

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}`);
});

任何人都知道发生了什么事吗?

1 个答案:

答案 0 :(得分:2)

您的代码两次调用/charge终结点,因为您既使用$.ajax,又做了form.submit()。那就是创建两个客户,其中一个没有源,因为令牌仅添加到ajax请求中,而这就是您要为其提供错误的客户。

简单的解决方法是删除form.submit()行。