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

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

有人知道这是怎么回事吗?

最佳答案

您的代码调用您的 /charge 端点两次,因为您使用 $.ajax 但也执行 form.submit()。这将创建两个客户,其中一个没有来源,因为 token 仅添加在 ajax 请求中,这就是您收到错误的客户。

简单的修复方法是删除 form.submit() 行。

关于javascript - Stripe 正在创建客户但未向卡收费,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51068137/

相关文章:

javascript - 焦点轮廓在右侧断开 - 未完全包裹元素

javascript - Firebase Cloud Functions 的 Node RESTful API

javascript - 我可以导入 babel-polyfill 模块而不是全部导入吗?

javascript - Stripe 自定义结帐未发布

stripe-payments - Stripe 在测试环境中不向客户发送发票电子邮件

javascript - ember.js:指定 Controller 内的组件

javascript - 我的 JavaScript 小部件中的 css 与目标页面 css 冲突

javascript - Jquery .offset() setter 不起作用

javascript - 使用 'opn' npm 模块在 Docker 中未处理的 promise 拒绝

javascript - 使用 javascript 中的浏览器化模块