Dans ce tutoriel, je vais vous montrer comment configurer Stripe dans un projet Astro, de la création d'un nouveau projet à la gestion des webhooks et à la création de sessions de paiement.
Pour commencer, nous devons créer un nouveau projet Astro à l'aide de la commande suivante :
npm create astro@latest
La version d'Astro utilisée est la 4.16.5
Ensuite, installez le package Stripe.
npm i stripe
La version de Stripe utilisée est la 17.2.0
Créez un fichier appelé src/lib/stripe.ts pour initialiser Stripe et gérer sa configuration :
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', });
Rien d'extraordinaire ici, juste le fait que l'apiVersion est basée sur la version stripe (pour 17.2.0 c'est 2024-09-30.acacia)
Après cela, créez un nouveau fichier dans src/lib/get-prices.ts et ajoutez ce qui suit :
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; }
Ici, nous allons configurer les prix.
Les Webhooks permettent à Stripe d'informer votre serveur des événements (tels que la fin des paiements). Pour écouter ces événements en local, nous avons besoin des éléments suivants :
"stripe:listen": "stripe listen --forward-to http://localhost:4321/api/webhooks/stripe"
Vous devrez également installer la CLI Stripe, qui permet à votre serveur local de recevoir les événements Stripe. Plus de détails sur la façon d'installer la CLI Stripe sont disponibles sur https://docs.stripe.com/stripe-cli.
Après cela, exécutez :
npm run stripe:listen
Il peut vous demander de vous connecter et après cela, vous devriez voir un message similaire :
Ready! You are using Stripe API Version. Your webhook signing secret is whsec_something
A la racine de votre projet, créez un fichier .env avec le contenu suivant :
STRIPE_SECRET_KEY=your_secret_key_from_stripe STRIPE_SIGNING_SECRET=signing_key_from_stripe_cli
Pour un style de base et pour gérer les requêtes backend, ajoutez les intégrations Tailwind CSS et Node.js à votre projet :
npx astro add tailwind npx astro add node
Vous pouvez en savoir plus sur les actions dans Astro sur https://docs.astro.build/en/guides/actions/.
Nous allons maintenant créer une action pour gérer le processus de paiement. Créez un fichier sur src/actions/index.ts avec le code suivant :
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, }; }, }), };
Ici, nous prenons simplement le priceId du frontend, recherchez-le dans notre liste de prix. Si nous le trouvons, nous créons une session de paiement Stripe et envoyons l'URL au frontend. Pour la session Stripe, nous devrons spécifier une URL de réussite/annulation, où l'utilisateur devra être redirigé après le paiement. De plus, nous avons la possibilité d'ajouter des métadonnées supplémentaires que nous recevrons dans notre webhook. Ici, vous ajoutez généralement le priceId et le userId.
Maintenant, affichons les fiches de prix et intégrons le bouton de paiement. Ajoutez le code suivant à 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>
Ici, nous récupérons les prix sur le serveur, et nous créons des fiches pour chacun des prix. Ensuite, pour chaque prix, nous disposons d'un formulaire qui appelle l'action précédemment définie afin de recevoir la session de stripe checkout. Après cela, nous redirigeons l'utilisateur vers la page Stripe.
Enfin, gérez les événements de webhook Stripe. Créez le fichier src/pages/api/webhooks/stripe.ts avec le code suivant :
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', }, }, ); } };
Ce webhook écoute l'événement checkout.session.completed de Stripe. Dès réception de l'événement, vous pouvez mettre à jour votre base de données, appliquer des modifications au compte de l'utilisateur ou déclencher toute autre action post-paiement.
C'est ça ! En suivant ces étapes, vous pouvez intégrer avec succès Stripe dans votre projet Astro. Plutôt facile, non ?
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!