Rumah >hujung hadapan web >tutorial js >Bagaimana untuk menambah Stripe ke Astro
Dalam tutorial ini, saya akan menunjukkan kepada anda cara menyediakan Stripe dalam projek Astro, daripada membuat projek baharu kepada mengendalikan webhook dan membuat sesi pembayaran.
Untuk bermula, kita perlu mencipta projek Astro baharu menggunakan arahan berikut:
npm create astro@latest
Versi Astro yang digunakan ialah 4.16.5
Seterusnya, pasang pakej Stripe.
npm i stripe
Versi Stripe yang digunakan ialah 17.2.0
Buat fail dipanggil src/lib/stripe.ts untuk memulakan Stripe dan mengendalikan konfigurasinya:
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', });
Tiada yang menarik di sini, hanya fakta bahawa apiVersion adalah berdasarkan versi jalur (untuk 17.2.0 ialah 2024-09-30.acacia )
Selepas itu buat fail baharu dalam src/lib/get-prices.ts dan tambah yang berikut:
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; }
Di sini, kami akan mengkonfigurasi harga.
Webhooks membenarkan Stripe memberitahu pelayan anda tentang acara (seperti penyelesaian pembayaran). Untuk mendengar acara ini di tempatan, kami memerlukan perkara berikut:
"stripe:listen": "stripe listen --forward-to http://localhost:4321/api/webhooks/stripe"
Anda juga perlu memasang Stripe CLI, yang membolehkan pelayan setempat anda menerima acara Stripe. Butiran lanjut tentang cara memasang Stripe CLI boleh didapati di https://docs.stripe.com/stripe-cli.
Selepas itu, jalankan:
npm run stripe:listen
Ia mungkin meminta anda log masuk dan selepas itu anda akan melihat mesej yang serupa:
Ready! You are using Stripe API Version. Your webhook signing secret is whsec_something
Dalam akar projek anda, buat fail .env dengan kandungan berikut:
STRIPE_SECRET_KEY=your_secret_key_from_stripe STRIPE_SIGNING_SECRET=signing_key_from_stripe_cli
Untuk penggayaan asas dan untuk mengendalikan permintaan bahagian belakang, tambahkan penyepaduan Tailwind CSS dan Node.js pada projek anda:
npx astro add tailwind npx astro add node
Anda boleh membaca lebih lanjut mengenai tindakan dalam Astro di https://docs.astro.build/en/guides/actions/.
Kami kini akan membuat tindakan untuk mengendalikan proses pembayaran. Cipta fail di src/actions/index.ts dengan kod berikut:
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, }; }, }), };
Di sini, kami hanya mengambil priceId dari bahagian hadapan, cari dalam senarai harga kami. Jika kami menemuinya, kami membuat sesi pembayaran berjalur dan menghantar url ke bahagian hadapan. Untuk sesi stripe, kami perlu menentukan url kejayaan/membatalkan, di mana pengguna harus diubah hala selepas pembayaran. Selain itu, kami mempunyai kemungkinan untuk menambah metadata tambahan yang akan kami terima ke dalam webhook kami. Di sini anda biasanya menambah priceId dan userId.
Sekarang, mari paparkan kad harga dan sepadukan butang daftar keluar. Tambahkan kod berikut pada 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>
Di sini, kami mengambil harga pada pelayan, dan kami mencipta kad untuk setiap harga. Kemudian, untuk setiap harga, kami mempunyai borang yang memanggil tindakan yang ditakrifkan sebelum ini untuk menerima sesi pembayaran berjalur. Selepas itu, kami mengubah hala pengguna ke halaman jalur.
Akhir sekali, kendalikan acara webhook Stripe. Buat fail src/pages/api/webhooks/stripe.ts dengan kod berikut:
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 ini mendengar acara checkout.session.completed daripada Stripe. Setelah menerima acara tersebut, anda boleh mengemas kini pangkalan data anda, menggunakan perubahan pada akaun pengguna atau mencetuskan sebarang tindakan pasca pembayaran yang lain.
Itu sahaja! Dengan mengikuti langkah-langkah ini, anda boleh berjaya menyepadukan Stripe ke dalam projek Astro anda. Agak mudah kan?
Atas ialah kandungan terperinci Bagaimana untuk menambah Stripe ke Astro. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!