简体   繁体   English

在 MERN 堆栈中使用 Stripe 存储信用卡号

[英]Store a credit card number with Stripe in MERN stack

I'm using MERN stack for an application with whom an user can create companies.我正在将 MERN 堆栈用于用户可以创建公司的应用程序。

A company has multiple fields that the user must introduce: name, address, phone, email, etc and also information about the credit card like: credit card number (16 digits), expiration date (MM/YY) and CCV (XYZ).一家公司有多个用户必须输入的字段:姓名、地址、电话、email 等,还有信用卡信息,如:信用卡号(16 位)、有效期(MM/YY)和 CCV(XYZ)。

The problem is that now all of this information is stored in the database which for sure it's not okay.问题是现在所有这些信息都存储在数据库中,这肯定不行。

I'm using Formik for fields validation and the app has this structure:我正在使用 Formik 进行字段验证,应用程序具有以下结构:

React:反应:

import React from 'react';
import { Redirect } from 'react-router-dom';
import { Formik, Form, Field } from 'formik';
import { Input, Button, Label, Grid } from 'semantic-ui-react';
import * as Yup from 'yup';

export default class CreateCompanyForm extends React.PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      name: '',
      creditCardNumber: '',
      creditCardDate: '',
      creditCardCCV: '',
    };
  }

  onChange = (e, { name, value }) => {
    this.setState({ [name]: value });
  };

  handleSubmit = values => {
    // creates the company
  };

  render() {
    const { redirectCreate } = this.state;

    if (redirectCreate) {
      return <Redirect to="/companies" />;
    }

    const initialValues = {
      name: '',
      creditCardNumber: '',
      creditCardDate: '',
      creditCardCCV: '',
    };
    // Yup validation rules
    const requiredErrorMessage = 'This field is required';
    const validationSchema = Yup.object({
      name: Yup.string().required(requiredErrorMessage),
      creditCardNumber: Yup.string().required(requiredErrorMessage),
      creditCardDate: Yup.string().required(requiredErrorMessage),
      creditCardCCV: Yup.string().required(requiredErrorMessage),
    });
    return (
      <>
        <Button form="amazing">Create company</Button>
        <Formik
          htmlFor="amazing"
          initialValues={initialValues}
          validationSchema={validationSchema}
          onSubmit={values => this.handleSubmit(values)}>
          {({ errors, touched }) => (
            <Form id="amazing">
              <div>
                <Grid columns={2}>
                  <Grid.Column>
                    <Label>Company name</Label>
                    <Field name="name" as={Input} />
                    <div className="add-fridge-error">
                      {touched.name && errors.name ? errors.name : null}
                    </div>
                  </Grid.Column>
                </Grid>

                <Grid.Column>
                  <Label>Credit card number</Label> // credit card number
                  <Field
                    name="creditCardNumber"
                    as={Input}                    
                  />
                  <div>
                    {touched.creditCardNumber && errors.creditCardNumber
                      ? errors.creditCardNumber
                      : null}
                  </div>
                </Grid.Column>

                <Grid.Column>
                  <Label>Date</Label> // expiration date
                  <Field name="creditCardDate" as={Input} placeholder="MM/YY" />
                  <div>
                    {touched.creditCardDate && errors.creditCardDate
                      ? errors.creditCardDate
                      : null}
                  </div>
                </Grid.Column>

                <Grid.Column>
                  <Label>CCV</Label> // CCV information
                  <Field name="creditCardCCV" as={Input} />
                  <div>
                    {touched.creditCardCCV && errors.creditCardCCV
                      ? errors.creditCardCCV
                      : null}
                  </div>
                </Grid.Column>
              </div>
            </Form>
          )}
        </Formik>
      </>
    );
  }
}

Node.js: Node.js:

const { Company } = require('../models');

module.exports = {
  create: (req, res) => {
    if (!req.body) {
      res.status(400).send({
        message: 'Not enough information',
      });
    }

    const {
      name,
      creditCardNumber,
      creditCardDate,
      creditCardCCV,
    } = req.body.company;
   

    const company = new Company({
      name,
      creditCardNumber,
      creditCardDate,
      creditCardCCV,
    });

    company
      .save()
      .then(data => {
        res.send(data);
      })
      .catch(err => {
        res.status(500).send({ message: err.message });
      });
  },

}

Mongoose model: Mongoose model:

const { Schema } = mongoose;

const companySchema = new Schema(
  {
    name: {
      type: String,
      required: true,
    },
    creditCardNumber: {
      type: String,
      required: true,
    },
    creditCardDate: {
      type: String,
      required: true,
    },
    creditCardCCV: {
      type: String,
      required: true,
    },
  },
  { timestamps: true }
);

This code works for creatin a new company but it stores all the information in the database.此代码适用于创建一家新公司,但它将所有信息存储在数据库中。

My question is if it's possible to add Stripe functionality over this approach in order to avoid storing the card information in the database?我的问题是是否可以通过这种方法添加 Stripe 功能以避免将卡信息存储在数据库中? If yes, how should this be done?如果是,应该怎么做?

Stripe uses a tokenization process on the client-side that prevents credit card details from ever landing on your server. Stripe 在客户端使用令牌化过程,以防止信用卡详细信息登陆您的服务器。

You can create a Customer object via the Stripe API and a Payment Source for the Customer object.您可以通过条带 API 和客户 object 的付款来源创建客户object。

For your implementation server-side, I'd recommend the official Stripe npm package .对于服务器端的实施,我推荐官方Stripe npm package

Client-side, use react-stripe-checkout library.客户端,使用react-stripe-checkout库。

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

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