【问题标题】:How do I write a Lambda function for my Stripe integration?如何为我的 Stripe 集成编写 Lambda 函数?
【发布时间】:2023-04-10 21:03:01
【问题描述】:

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

Stripe's documentation 非常简单,但文档假设其中一个正在运行服务器。

以下代码是他们文档中的服务器实现 sn-p。

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

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

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

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

非常感谢!

约翰

【问题讨论】:

    标签: reactjs aws-lambda stripe-payments gatsby netlify


    【解决方案1】:

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

    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

    如下更改 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,然后我们将其返回给客户端。

    前端

    假设您已像链接示例中那样加载了 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,
        },
      },
    });
    

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

    后续步骤

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

    当然,您还需要处理我忽略的许多不同的错误。

    使用的版本是 2021-06-12 列出的所有条带库的最新版本

    【讨论】:

    • 红宝石你是国王!非常感谢你的帮助!我现在摇摆不定。我在多个论坛上寻求帮助。不仅你是唯一一个回答的人,而且你把它粉碎了。我很感激!
    • 不要忘记投票以帮助其他人找到答案;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 2020-12-02
    • 2017-10-28
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多