【问题标题】:Stripe succesfully creating customer without card detailsStripe 成功创建没有卡详细信息的客户
【发布时间】:2021-03-13 04:32:48
【问题描述】:

在这里完成 web/Stripe 新手。我构建了一个 iOS 应用,但我想使用的收款方式在 iOS 上是不允许的,所以我必须为其设置一个网站。

该网站使用 HTML/CSS,并在 Heroku 上托管一个节点后端。该网站是一个简单的网站,它获取用户的姓名和卡片详细信息,但目前我的实现存在问题。

在 app.get() 中,我创建了一个客户和一个 setupIntent,然后当用户单击站点上的一个按钮(只是客户端 js 中的一个事件监听器)时,它会被填写。

我的问题是,当我创建客户时,每次加载页面时都会创建一个空客户。如果我删除此客户,则不会在加载时添加额外的客户,并且会创建正确的客户,但不会将卡附加到客户的帐户!

我确信这是我的一个基本错误,因为我匆忙学习网络开发以让应用接受付款(我们收到了应用审核团队的意外拒绝,基本上是说我们的应用永远不会只要在应用程序上提供卡片详细信息就可以接受)。

提前感谢任何/所有帮助。

干杯!

乔什

服务器端:

const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
require('dotenv').config()

const app = express();

app.set('view engine', 'ejs');

app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));

const Stripe = require('stripe');
const stripe = Stripe(process.env.SECRET_KEY);


app.get('/', async (req, res) => {
  var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
  const customer = await stripe.customers.create({
    email: fullUrl.split('=')[1] //This gets the email sent in the URL from the app
  });
  const intent = await stripe.setupIntents.create({
    customer: customer.id,
    payment_method_types: ['card'],
  });

  console.log(fullUrl)
  console.log(fullUrl.split('=')[1])

  res.render('index', { client_secret: intent.client_secret });
})

app.listen(process.env.PORT || 3000);

客户端:

var stripe = Stripe('livePublicKeyIsHere');
// const firebase = require("firebase");
// require("firebase/firestore");

var elements = stripe.elements();
var cardElement = elements.create('card');
cardElement.mount('#card-element');
    
var db = firebase.firestore();

var cardholderName = document.getElementById('cardholder-name');
var setupForm = document.getElementById('setup-form');
var clientSecret = setupForm.dataset.secret;


const queryString = window.location.search;
const email = queryString.split('=')[1];

setupForm.addEventListener('submit', function(ev) {
  ev.preventDefault();
  stripe.confirmCardSetup(
    clientSecret, {
      payment_method: {
        card: cardElement,
        billing_details: {
          name: cardholderName.value
        },
      },
    }
  ).then(function(result) {
    if (result.error) {
      console.log("Error!!!" + result.error.message);
      window.alert("There's an error: " + result.error.message);
    } else {
      console.log("Success!!!");
      window.alert("Account created! Download and log into the app in order to continue.");
      addUserToFirestore(email)
    }
  });
});


function addUserToFirestore(email) {
  createUserOnFirestore(email);
  db.collection("Users").doc(email).collection("Settings").doc("info").set({
      cardDetailsAdded: true
    })
    .then(() => {
      console.log("Document successfully written!");
    })
    .catch((error) => {
      console.error("Error writing document: ", error);
    });
}

function createUserOnFirestore(email) {
  db.collection("Users").doc(email).set({
      exists: true
    })
    .then(() => {
      console.log("Document successfully written!");
    })
    .catch((error) => {
      console.error("Error writing document: ", error);
    });
}

【问题讨论】:

    标签: javascript node.js stripe-payments


    【解决方案1】:

    原因是因为您使用的是get 而不是post。当您的用户单击该按钮时,它应该向您的服务器发出POST 请求以生成您已经完成的SetupIntent 对象。您还应该存储用户和创建的Customer 之间的关系映射,因此当用户添加新卡时,您并不总是创建新的Customer,而是将新卡添加到现有的Customer 对象.

    【讨论】:

    • 啊,我有点困惑 - 在 app.get() 中,它呈现了客户端密码为 intent.client_secret 的页面: const intent = await stripe.setupIntents.create({ payment_method_types : ['卡片'], }); res.render('index', { client_secret: intent.client_secret });如果您在 POST 请求中创建 setupIntent,它如何发送客户端密钥?
    • SetupIntent 应该只在需要时生成,而不是在每次加载页面时生成。您可以使用res.json(...)POST 请求中返回响应。
    【解决方案2】:

    虽然using a customer is recommended,最终提供customer (API ref) 是可选的。您也可以单独attach a payment method to a customer,只要您在使用它进行付款之前这样做。

    请注意,除非附加给客户,否则付款方式只能一次性使用。

    【讨论】:

      猜你喜欢
      • 2016-08-08
      • 2018-05-21
      • 1970-01-01
      • 2021-09-09
      • 2020-03-28
      • 2016-12-14
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多