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

Joh*_*nyK 8 stripe-payments reactjs aws-lambda gatsby netlify

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

Stripe 的文档非常简单,但该文档假设正在运行一台服务器。

以下代码是其文档中的服务器实现片段。

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!'));
Run Code Online (Sandbox Code Playgroud)

这是 Stripe 的付款流程。

Stripe 的支付处理流程

挑战:由于我要将内容转移到 Netlify(这是一个无服务器 CDN),因此我需要使用 Lambda 函数与 Stripe API 进行交互,而不是使用示例中的 Express 服务器实现。

Netlify 描述了在其平台上使用无服务器功能。

我能够运行这个愚蠢的小东西。但我知道如果我想的话如何在我的 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})
    };
}
Run Code Online (Sandbox Code Playgroud)

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

问题:/问有人可以帮助我理解如何思考这个问题吗?

我不知道这是否有帮助,但这是我的git 存储库

任何帮助将不胜感激。如果你们中有人有一些空闲时间并考虑通过 Zoom 会议在这方面指导我。我绝对会为你的时间付钱。

非常感谢!

约翰

rub*_*bie 18

我绝对可以帮助您开始使用 Serverless / Stripe。有多个 API 和库一开始很令人困惑,所以这希望对其他做同样事情的人有用。

Stripe API 有多种方法可以完成类似的操作,但这是一个基本流程,您可以使用 Netlify Lambdas(或任何类似的解决方案)在静态站点上安全地接受信用卡付款。

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

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

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);
Run Code Online (Sandbox Code Playgroud)

拉姆达

按如下方式更改 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
  }
Run Code Online (Sandbox Code Playgroud)

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

前端

假设您已按照链接示例加载了 Stripe 和 Elements,并且拥有基本的信用卡表单,则只需编辑提交处理程序即可。

首先调用你的paymentIntentslambda:

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

现在您可以使用 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,
    },
  },
});
Run Code Online (Sandbox Code Playgroud)

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

下一步

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

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

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

  • 鲁比,你是国王!非常感谢你的帮助!我现在摇摇欲坠。我在多个论坛上寻求帮助。你不仅是唯一一个回答的人,而且你粉碎了它。我很感激! (3认同)