如何为我的 Stripe 集成编写 Lambda 函数?

How do I write a Lambda function for my Stripe integration?

背景: 我正在使用 Gatsby -> Netlify 将我们的销售页面迁移到无服务器 CDN,并且我正在尝试实施 Stripe 自定义支付流程,因为我们想要自定义我们的结账形式。我在这里的一个登陆页面上实现了 Stripe Checkout,但这不是我们想要的。 Landing Page

Stripe's documentation 非常简单,但文档假定一个是 运行ning 一台服务器。

下面的代码是他们文档中的服务器实现片段。

const express = require("express");
const app = express();
// This is your real test secret API key.
const stripe = require("stripe")("sk_test_51J085aDDSnMNt7v1ZO3n5fxobP6hhEhf1uC2SDmkHGIX8fCnxFiSMrxITKu06ypYUHYAMHVZ1lhc5Fqm7UoVa6dx00XvV5PZzG");

app.use(express.static("."));
app.use(express.json());

const calculateOrderAmount = items => {
  // Replace this constant with a calculation of the order's amount
  // Calculate the order total on the server to prevent
  // people from directly manipulating the amount on the client
  return 1400;
};

app.post("/create-payment-intent", async (req, res) => {
  const { items } = req.body;
  // Create a PaymentIntent with the order amount and currency
  const paymentIntent = await stripe.paymentIntents.create({
    amount: calculateOrderAmount(items),
    currency: "usd"
  });

  res.send({
    clientSecret: paymentIntent.client_secret
  });
});

app.listen(4242, () => console.log('Node server listening on port 4242!'));

这是 Stripe 的支付流程。

Stripe's Payment Processing Flow

挑战: 由于我将我们的内容移动到无服务器 CDN Netlify,我需要使用 Lambda 函数与 Stripe 交互 API 而不是他们示例中的快速服务器实现。

Netlify 在此处描述了在其平台上使用 serverless functions

我能够 运行 这个愚蠢的小东西。但是我知道如果我想在我的 React 应用程序中请求输出...

exports.handler = async function(event, context, callback) {
    const { STRIPE_PUBLISHABLE_KEY } = process.env;
    console.log("I am the Hello World Lambda function.")
    return {
        statusCode: 200,
        body: JSON.stringify({message: STRIPE_PUBLISHABLE_KEY})
    };
}

我知道我在这里展示了我的技术水平,但正如我父亲所说:羞耻总比痛苦好。

问题:/请教谁能帮我理解一下这个问题是怎么想的?

我不知道这是否有帮助,但这是我的 git repository

任何帮助将不胜感激。如果你们中的任何人有几个空闲周期,并且会考虑通过缩放会议来指导我。我绝对会为你的时间付出代价。

非常感谢!

约翰

我绝对可以帮助您开始使用 Serverless / Stripe。有多个 APIs 和库一开始很混乱,因此希望这对其他人做同样的事情有用。

Stripe API 有很多方法可以做类似的事情,但这是一个基本流程,您可以使用 Netlify Lambdas(或任何类似的解决方案)在静态网站上安全地接受信用卡付款).

我假设您使用 Stripe 的 Elements 信用卡表格 react

基本原则是我们需要在“服务器”端(即在 lambda 中)执行使用 Stripe secret 的操作,其余的我们可以在客户端执行。

import React from 'react';
import ReactDOM from 'react-dom';
import {loadStripe} from '@stripe/stripe-js';
import {
  CardElement,
  Elements,
  useStripe,
  useElements,
} from '@stripe/react-stripe-js';

const CheckoutForm = () => {
  const stripe = useStripe();
  const elements = useElements();

  // we will edit this
  const handleSubmit = async (event) => {
    event.preventDefault();
    const {error, paymentMethod} = await stripe.createPaymentMethod({
      type: 'card',
      card: elements.getElement(CardElement),
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <CardElement />
      <button type="submit" disabled={!stripe}>
        Pay
      </button>
    </form>
  );
};

const stripePromise = loadStripe('pk_test_abc123');

const App = () => (
  <Elements stripe={stripePromise}>
    <CheckoutForm />
  </Elements>
);

ReactDOM.render(<App />, document.body);

拉姆达

按如下方式更改 lambda 的主体:

  const stripe = require("stripe")(process.env.STRIPE_SECRET);
  const { amount, currency = "gbp" } = JSON.parse(event.body);

  try {
    const paymentIntent = await stripe.paymentIntents.create({
      amount,
      currency,
    });
    return {
      statusCode: 200, // http status code
      body: JSON.stringify({
        paymentIntent
      }),
    };
  } catch (e) {
    // handle errors
  }

在这里,我们使用您的条带密钥初始化条带库,我们仅使用金额和货币创建最小的 paymentIntent,然后我们 return 将其发送给客户端。

前端

假设您已经像链接示例中那样加载了 Stripe 和 Elements,并且有一个基本的信用卡表单,您只需要编辑提交处理程序。

首先调用你的 paymentIntents lambda:

// handleSubmit()
const intent = await fetch("/.netlify/functions/payment-intent", {
  method: "POST",
  body: JSON.stringify({
      amount: 500,
    }),
  });
const { paymentIntent } = await intent.json();

现在您可以使用 paymentIntent 来确认用户输入的银行卡详细信息。 (paymentIntent 包含确认付款所需的 client_secret。)

// if you've followed the example, this is already done
import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
const stripe = useStripe();
const elements = useElements();

// now back to handleSubmit()
await stripe.confirmCardPayment(paymentIntent.client_secret, {
  payment_method: {
    card: elements.getElement(CardElement),
    billing_details: {
      email: profile.email,
    },
  },
});

这里我们使用javascriptAPI的confirmCardPayment方法来确认使用我们刚刚设置的paymentIntent中的client_secret支付。信用卡详细信息由 elements.getElement 方法处理。我们还提供用户的电子邮件,以便将收据发送给他们。

后续步骤

这是一个非常基本的通过条带接受付款的无服务器实现。您可以查看不同的 API 来设置客户并使用他们的 ID 进行付款、设置订阅等等。

当然你也会想要处理我忽略的许多不同的错误。

使用的版本是 2021 年 6 月 12 日列出的所有条带库的最新版本