首页 文章

在数据库中存储Stripe付款的最佳做法?

提问于
浏览
0

我想知道是否存在某种“约定”或其他最佳实践,用于在数据库中存储条带支付数据 . 网上真的缺乏信息,因为我自己这样做,我想从别人那里得到一些反馈 .

我的网站的基本设置是有一个商店有几个产品 . 还可以选择订阅,每月接收这些产品 .

所以我设置了两条邮政路线 . 一个用于购买产品,另一个用于订购 . 这些使用Stripe API . 对于订单,我使用 stripe.charge ,对于订阅,我从 stripe.customer 创建客户并订阅他们的计划 .

对于 stripe.charges ,我保存返回到数据库中的对象 . 这包含所有费用数据 . 有一个webhook发送为 charge.succeeded ,如果 charge succeeded . 我不存储这些数据 . 也许我应该在这里存储充电ID,而不是整个充电对象 . 我把它存储如下:

ORDER ROUTE

module.exports = async (req, res) => {
try {
    const charge = await stripe.charges.create({
        amount: req.session.cart.totalPrice,
        currency: 'usd',
        source: req.body.id
    });

    const order = await new Order({
        user: req.user,
        cart: req.session.cart,
        stripeCharge: charge
    }).save();

    req.session.cart = new Cart({});    
    res.sendStatus(200);

} catch (e) {
    console.log(e);
}
};

对于订阅,它有点复杂,因为创建的客户对象不包含任何费用ID . 所以我将客户ID保存到该用户模型 . 如果订阅处理正常,Stripe将触发6个webhook . 我存储 customer.subscription.createdcustomer.createdcharge.succeededinvoice.created . 我存储客户对象,如下所示:

SUBSCRIPTION ROUTE

module.exports = async (req, res) => {
try {
    if(!req.user.hasSubscription) {
        const customer = await stripe.customers.create({
            email: req.body.email,
            source: req.body.id,
            plan: 'pro'
        });

        await new Subscription({
            user: req.user,
            customerId: customer.id
        }).save();

        req.user.hasSubscription = true;
        await req.user.save();
        res.send(req.user);
    }

} catch (e) {
    console.log(e);
}
};

如您所见,我在Mongoose User 模型上设置了一个布尔值 hasSubscription . 如果是这样,则不会创建任何客户,因此不会设置任何订阅 . 如果为false,则从创建的客户对象中保存客户ID . 然后在webhook路由中,我将上面的4个事件保存到正确的用户,按客户ID匹配 . 我认为,我可以在这里节省更少的数据,可能记录任何订阅和任何取消 . 我保存webhook事件如下:

WEBHOOKS ROUTE

module.exports = async (req, res) => {
try {
    const data = {};        

    if (req.body.type === 'customer.subscription.created') {
        await Subscription.findOneAndUpdate({ customerId: 
        req.body.data.object.customer }, {
            $set: {
                'stripe_data.customer_subscription_created': 
                 req.body.data.object
            }
        }, {
            new: true
        });
        res.sendStatus(200);            
    };

 …//OTHER STRIPE EVENTS SIMILAR TO ABOVE…

 }

我存储的数据超出了我可能需要的安全数据,而且我在某处读到了建议存储足够数据对于合法合规的好处 . 但是,由于Stripe将所有内容存储在仪表板中,我可以看到您的观点,即一个简单的识别信息,如充电ID就足够了 .

我仍然处于测试模式,但我认为Stripe只发送卡的最后4位数字,并且到期年份如下:

exp_year: 2042 last4: '4242'

关于将机密信息保存到数据库:我没有看到任何更敏感的信息被暴露 . 卡片本身由Stripe创建的ID引用 .

1 回答

  • 1

    Stripes security docs中,它提到 Out-of-scope card data that can be safely stored . Jake T.的评论确实是答案 - 从API返回的所有内容都可以存储 .

    Card type, expiration date, and last four digits are not subject to PCI compliance .

相关问题