简体   繁体   English

Stripe 成功创建没有卡详细信息的客户

[英]Stripe succesfully creating customer without card details

Complete web/Stripe newbie here.在这里完成 web/Stripe 新手。 I built an iOS app, but the method of taking payments that I wanted to use isn't allowed on iOS, so I had to set up a website for it.我构建了一个 iOS 应用程序,但是我想使用的收款方式在 iOS 上是不允许的,所以我不得不为它建立一个网站。

The website uses HTML/CSS, with a node backend hosted on Heroku.该网站使用 HTML/CSS,节点后端托管在 Heroku 上。 The website is a simple site that takes the name and card details of the user, but there's currently an issue with my implementation.该网站是一个简单的网站,它获取用户的姓名和卡片详细信息,但目前我的实现存在问题。

In app.get(), I create a customer and a setupIntent, and then this gets filled out when the user clicks a button on the site (just an event listener in js on the client-side).在 app.get() 中,我创建了一个客户和一个 setupIntent,然后当用户单击站点上的一个按钮(只是客户端 js 中的一个事件监听器)时,它会被填写。

My issue is, when I create a customer it creates an empty customer every time the page is loaded.我的问题是,当我创建客户时,每次加载页面时都会创建一个空客户。 If I remove this customer, there is no extra customer being added on load, and the correct customer is created, but there is no card attached to the customer's account!如果我删除了这个客户,加载时不会添加额外的客户,并且创建了正确的客户,但是客户的帐户没有附加卡!

I'm sure this is a basic error on my part, as I rushed through learning web dev in order to get the app to accept payments (we got an unexpected rejection from the App Review team, basically saying our app will never be acccepted as long as it takes card details on the app).我确信这是我的一个基本错误,因为我匆忙学习 web 开发以便让应用程序接受付款(我们收到了应用程序审查团队的意外拒绝,基本上说我们的应用程序永远不会被接受为只要它需要应用程序上的卡详细信息)。

Thanks in advance for any/all help.提前感谢您的任何/所有帮助。

Cheers!干杯!

Josh乔什

Server-side:服务器端:

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

Client-side:客户端:

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

The reason is because you're using get instead of post .原因是因为您使用的是get而不是post When your user clicks the button, it should fire a POST request to your server to generate a SetupIntent object which you have already done.当您的用户单击该按钮时,它应该向您的服务器发出POST请求以生成您已经完成的SetupIntent object。 You also should store a relation mapping between your user and the Customer that is created, so you don't always create a new Customer when user adds a new card, instead you add the new card to existing Customer object.您还应该存储您的用户和创建的Customer之间的关系映射,因此当用户添加新卡时您并不总是创建新Customer ,而是将新卡添加到现有Customer object。

While using a customer is recommended , ultimately it is optional to provide a customer ( API ref ).虽然建议使用客户,但最终可以选择提供customerAPI ref )。 You can also attach a payment method to a customer separately, as long as you do so before using it for a payment.您还可以将付款方式单独附加到客户,只要您在使用它进行付款之前这样做。

Note that unless attached to a customer, a payment method is one-time-use only.请注意,除非附加给客户,否则付款方式仅限一次性使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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