Maison  >  Article  >  interface Web  >  Comment ajouter Stripe à Astro

Comment ajouter Stripe à Astro

Susan Sarandon
Susan Sarandonoriginal
2024-10-17 20:44:021007parcourir

How to add Stripe to Astro

Intégrer Stripe à Astro : un guide étape par étape

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.

Étape 1 : Créer un nouveau projet Astro

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

Étape 2 : Installation de Stripe

Ensuite, installez le package Stripe.

npm i stripe

La version de Stripe utilisée est la 17.2.0

Étape 3 : Configuration de Stripe

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.

Étape 4 : Configuration de Stripe CLI pour les Webhooks

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

Étape 5 : configuration des variables d'environnement

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

Étape 6 : Ajout de Tailwind CSS et Node.js

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

Étape 7 : Création d'une action de paiement Stripe

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.

Étape 8 : rendu du formulaire de paiement

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.

Étape 9 : Création d'un webhook pour 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.

Conclusion

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn