首页 > web前端 > js教程 > 如何将 Stripe 添加到 Astro

如何将 Stripe 添加到 Astro

Susan Sarandon
发布: 2024-10-17 20:44:02
原创
1089 人浏览过

How to add Stripe to Astro

将 Stripe 与 Astro 集成:分步指南

在本教程中,我将向您展示如何在 Astro 项目中设置 Stripe,从创建新项目到处理 Webhooks 和创建结帐会话。

第 1 步:创建一个新的 Astro 项目

首先,我们需要使用以下命令创建一个新的 Astro 项目:

npm create astro@latest
登录后复制

正在使用的Astro版本是4.16.5

第2步:安装Stripe

接下来,安装 Stripe 软件包。

npm i stripe
登录后复制

正在使用的Stripe版本是17.2.0

第3步:配置Stripe

创建一个名为 src/lib/stripe.ts 的文件来初始化 Stripe 并处理其配置:

import Stripe from 'stripe';

if (!import.meta.env.STRIPE_SECRET_KEY) {
    throw new Error('Missing Stripe secret key');
}

export const stripe = new Stripe(import.meta.env.STRIPE_SECRET_KEY, {
    apiVersion: '2024-09-30.acacia',
});
登录后复制

这里没什么特别的,只是 apiVersion 基于 stripe 版本(17.2.0 是 2024-09-30.acacia )

之后在 src/lib/get-prices.ts 中创建一个新文件并添加以下内容:

export async function getPrices() {
    const data = [
        {
            id: 1,
            amount: 1000,
            title: 'One time Price 1',
        },
        {
            id: 2,
            amount: 1000,
            title: 'One time Price 2',
        },
        {
            id: 3,
            amount: 1500,
            credits: 10,
            title: '10 credits',
        },
        {
            id: 4,
            amount: 3000,
            credits: 25,
            title: '25 credits',
        },
    ];
    return data;
}
登录后复制

在这里,我们将配置价格。

步骤 4:为 Webhooks 设置 Stripe CLI

Webhooks 允许 Stripe 向您的服务器通知事件(例如付款完成)。要在本地收听这些事件,我们需要以下内容:

"stripe:listen": "stripe listen --forward-to http://localhost:4321/api/webhooks/stripe"
登录后复制

您还需要安装 Stripe CLI,它允许您的本地服务器接收 Stripe 事件。有关如何安装 Stripe CLI 的更多详细信息,请访问 https://docs.stripe.com/stripe-cli。

之后,运行:

npm run stripe:listen
登录后复制

它可能会要求您登录,之后您应该会看到类似的消息:

Ready! You are using Stripe API Version. Your webhook signing secret is whsec_something
登录后复制

步骤5:配置环境变量

在项目的根目录中,创建一个包含以下内容的 .env 文件:

STRIPE_SECRET_KEY=your_secret_key_from_stripe
STRIPE_SIGNING_SECRET=signing_key_from_stripe_cli
登录后复制

第 6 步:添加 Tailwind CSS 和 Node.js

对于基本样式和处理后端请求,请将 Tailwind CSS 和 Node.js 集成添加到您的项目中:

npx astro add tailwind
npx astro add node
登录后复制

第 7 步:创建 Stripe Checkout 操作

您可以在 https://docs.astro.build/en/guides/actions/ 阅读有关 Astro 中操作的更多信息。

我们现在将创建一个操作来处​​理结帐过程。使用以下代码在 src/actions/index.ts 创建一个文件:

import { ActionError, defineAction } from "astro:actions";
import { z } from "astro:schema";
import { getPrices } from "../lib/get-prices";
import { stripe } from "../lib/stripe";

export const server = {
  createCheckout: defineAction({
    input: z.object({
      priceId: z.number(),
    }),
    accept: "form",
    handler: async (input) => {
      const prices = await getPrices();
      const price = prices.find((p) => p.id === input.priceId);

      if (!price) {
        throw new ActionError({
          code: "NOT_FOUND",
          message: "Price not found.",
        });
      }

      const baseUrl = 'http://localhost:4321'; // replace with your production URL

      const stripeSession = await stripe.checkout.sessions.create({
        mode: "payment",
        payment_method_types: ["card"],
        line_items: [
          {
            quantity: 1,
            price_data: {
              unit_amount: price.amount,
              currency: "usd",
              product_data: {
                name: price.title,
                description: `Buy ${price.title} product`,
              },
            },
          },
        ],
        metadata: {
          priceId: price.id,
        },
        success_url: `${baseUrl}/?stripe=success`,
        cancel_url: `${baseUrl}/?stripe=cancel`,
      });

      if (!stripeSession.url) {
        throw new ActionError({
          code: "NOT_FOUND",
          message: "Could not create Stripe session",
        });
      }

      return {
        url: stripeSession.url,
      };
    },
  }),
};
登录后复制

在这里,我们只是从前端获取priceId,在我们的价格列表中查找它。如果找到它,我们将创建一个 stripe checkout 会话并将 url 发送到前端。对于 stripe 会话,我们需要指定成功/取消 url,用户应在付款后重定向到该 URL。此外,我们还可以添加我们将收到的额外元数据到我们的 webhook 中。这里通常添加priceId和userId。

第 8 步:渲染结账表单

现在,让我们显示定价卡并集成结账按钮。将以下代码添加到 src/pages/index.astro:

---
import Layout from '../layouts/Layout.astro';
import { getPrices } from '../lib/get-prices';
import { actions } from 'astro:actions';

const prices = await getPrices();

const result = Astro.getActionResult(actions.createCheckout);
if (result && !result.error) {
    return Astro.redirect(result.data.url)
}
---

<Layout title="Welcome to Astro.">
    <h1 class="text-center text-5xl font-bold text-gray-200">Pricing</h1>
    <ul class="mt-12 grid grid-cols-1 gap-10 md:grid-cols-2 lg:grid-cols-3 p-4">
        {
            prices.map((price) => (
                <li class="mx-auto w-full max-w-5xl space-y-4 rounded-lg bg-gray-900 p-8 text-white">
                    <h2 class="text-2xl font-bold">{price.title}</h2>
                    <p class="mt-4 text-3xl font-bold">${price.amount / 100}</p>
                    <form method="POST" action={actions.createCheckout}>
                        <input type="hidden" name="priceId" value={price.id} />
                        <button class="bg-blue-500 text-white hover:bg-blue-600 p-4">
                            Buy
                        </button>
                    </form>
                </li>
            ))
        }
    </ul>
</Layout>
登录后复制

在这里,我们在服务器上获取价格,并为每个价格创建卡片。然后,对于每个价格,我们都有一个调用先前定义的操作的表单,以便接收条带结帐会话。之后,我们将用户重定向到条纹页面。

第 9 步:为 Stripe 创建 Webhook

最后,处理 Stripe webhook 事件。使用以下代码创建文件 src/pages/api/webhooks/stripe.ts:

import type { APIRoute } from 'astro';
import type Stripe from 'stripe';
import { stripe } from '../../../lib/stripe';

type Metadata = {
    priceId: string;
};

export const POST: APIRoute = async ({ request }) => {
    const signature = request.headers.get('stripe-signature');
    if (!signature) {
        return new Response(JSON.stringify({ error: 'Invalid signature' }), {
            status: 400,
            headers: {
                'Content-Type': 'application/json',
            },
        });
    }

    const stripeSigningSecret = import.meta.env.STRIPE_SIGNING_SECRET as string;
    try {
        const event = stripe.webhooks.constructEvent(
            await request.text(),
            signature,
            stripeSigningSecret,
        );

        const completedEvent = event.data.object as Stripe.Checkout.Session & {
            metadata: Metadata;
        };

        if (event.type === 'checkout.session.completed') {
            console.log('Paid', completedEvent.amount_total);
            console.log('Metadata', completedEvent.metadata);

            // Update your database or user status here
        }
        return new Response(JSON.stringify({ success: true, error: null }), {
            status: 200,
            headers: {
                'Content-Type': 'application/json',
            },
        });
    } catch (err) {
        return new Response(
            JSON.stringify({
                success: false,
                error: (err as { message: string }).message,
            }),
            {
                status: 500,
                headers: {
                    'Content-Type': 'application/json',
                },
            },
        );
    }
};

登录后复制

此 webhook 侦听来自 Stripe 的 checkout.session.completed 事件。收到事件后,您可以更新数据库、对用户帐户应用更改或触发任何其他付款后操作。

结论

就是这样!通过执行以下步骤,您可以成功地将 Stripe 集成到您的 Astro 项目中。很简单吧?

以上是如何将 Stripe 添加到 Astro的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板