NextJS Templates
Tutoriel d'application de facturation avec Next.js, Vercel et Back4app
26 min
dans ce tutoriel, nous allons construire une application complète d' invoicing app en utilisant next js comme frontend, back4app comme backend, et des services supplémentaires comme clerk pour l'authentification, stripe pour les paiements, et resend pour les notifications par e mail ce guide vous expliquera comment configurer l'authentification, la gestion des factures, le traitement des paiements, et le déploiement sur vercel 1\ prérequis avant de commencer, assurez vous d'avoir ce qui suit un compte back4app ( inscrivez vous ici https //www back4app com/ ) un compte clerk ( clerk io https //clerk dev/ ) pour l'authentification un compte stripe ( stripe com https //stripe com/ ) pour le traitement des paiements un compte resend ( resend io https //resend io/ ) pour les notifications par e mail node js et npm installés ( installation de node js https //nodejs org/ ) 2\ configuration du backend (back4app) 2 1 créer un nouveau projet dans back4app connectez vous à back4app et créez un nouveau projet accédez au data browser et créez les classes suivantes 2 2 modèles de données (classes) 2 2 1 utilisateur (géré automatiquement par clerk) identifiant d'objet nom d'utilisateur email 2 2 2 organisation créer une classe appelée organisation ajouter les colonnes suivantes nom (string) le nom de l'organisation ownerid (pointer< user>) pointe vers la classe user (créée automatiquement par clerk) membres (array\<pointer< user>>) un tableau d'utilisateurs qui appartiennent à cette organisation 2 2 3 client créer une classe appelée client ajouter ces colonnes nom (string) nom du client email (string) email du client organizationid (pointer) organisation à laquelle ce client appartient 2 2 4 facture créer une classe appelée facture ajouter ces colonnes numerodefacture (string) identifiant unique de la facture idclient (pointer) lien vers le client idorganisation (pointer) lien vers l'organisation montant (number) montant total de la facture statut (string) options incluent 'brouillon', 'envoyé', 'payé' et 'en retard' datelimite (date) la date d'échéance de la facture articles (array) la liste des articles dans la facture 2 2 5 paiement créer une classe appelée paiement ajouter ces colonnes idfacture (pointer) lien vers la facture associée montant (number) montant du paiement idsessionstripe (string) l'id de la session stripe statut (string) statut du paiement (par exemple, 'en attente', 'réussi', 'échoué') 3\ configuration du frontend (next js) 3 1 créer un projet next js commencez par configurer votre projet next js avec typescript, tailwind css et les composants shadcn/ui npx create next app\@latest invoicing app typescript cd invoicing app npm install tailwindcss postcss autoprefixer npx tailwindcss init 3 2 configurer tailwind css configurez tailwind en mettant à jour le tailwind config js et en ajoutant les styles à globals css dans tailwind config js module exports = { content \[ ' /pages/ / {js,ts,jsx,tsx}', ' /components/ / {js,ts,jsx,tsx}', ], theme { extend {}, }, plugins \[], }; dans styles/globals css @tailwind base; @tailwind components; @tailwind utilities; 3 3 installer le sdk parse et des services supplémentaires installez les dépendances nécessaires pour parse, clerk, stripe et resend npm install parse @clerk/clerk next stripe resend 3 4 initialiser le sdk parse dans next js dans pages/ app tsx , initialisez le sdk parse avec vos identifiants back4app import { clerkprovider } from '@clerk/clerk react'; import parse from 'parse'; parse initialize('your app id', 'your javascript key'); parse serverurl = 'https //parseapi back4app com'; function myapp({ component, pageprops }) { return ( \<clerkprovider> \<component { pageprops} /> \</clerkprovider> ); } export default myapp; remplacez 'your app id' et 'your javascript key' par vos identifiants back4app 4\ mise en œuvre de l'authentification des utilisateurs 4 1 intégration de clerk pour l'authentification configurez clerk pour l'authentification allez sur le tableau de bord de clerk, créez une application et récupérez vos clés api mettez à jour votre env local fichier avec les clés de clerk next public clerk frontend api=your clerk frontend api clerk api key=your clerk api key maintenant créez pages/sign in tsx et pages/sign up tsx pour la fonctionnalité de connexion et d'inscription en utilisant les composants de clerk dans pages/sign in tsx import { signin } from '@clerk/clerk react'; export default function signinpage() { return \<signin />; } dans pages/sign up tsx import { signup } from '@clerk/clerk react'; export default function signuppage() { return \<signup />; } 5\ gestion des organisations et des clients 5 1 créer des organisations les utilisateurs peuvent créer des organisations dont ils sont propriétaires créez une page pages/organizations/new\ tsx pour créer de nouvelles organisations import { usestate } from 'react'; import parse from 'parse'; export default function neworganization() { const \[name, setname] = usestate(''); const handlecreateorganization = async () => { const organization = parse object extend('organization'); const organization = new organization(); organization set('name', name); organization set('ownerid', parse user current()); try { await organization save(); alert('organization created successfully!'); } catch (error) { console error('error creating organization ', error); } }; return ( \<div> \<h1>create new organization\</h1> \<input type="text" value={name} onchange={(e) => setname(e target value)} placeholder="organization name" /> \<button onclick={handlecreateorganization}>create\</button> \</div> ); } 5 2 gestion des clients créez une page de gestion des clients pages/customers/new\ tsx pour ajouter de nouveaux clients import { usestate } from 'react'; import parse from 'parse'; export default function newcustomer() { const \[name, setname] = usestate(''); const \[email, setemail] = usestate(''); const handlecreatecustomer = async () => { const customer = parse object extend('customer'); const customer = new customer(); customer set('name', name); customer set('email', email); customer set('organizationid', parse user current() get('organizationid')); try { await customer save(); alert('customer created successfully!'); } catch (error) { console error('error creating customer ', error); } }; return ( \<div> \<h1>create new customer\</h1> \<input type="text" value={name} onchange={(e) => setname(e target value)} placeholder="customer name" /> \<input type="email" value={email} onchange={(e) => setemail(e target value)} placeholder="customer email" /> \<button onclick={handlecreatecustomer}>create\</button> \</div> ); } 6\ gestion des factures 6 1 créer des factures créez une page de création de factures pages/invoices/new\ tsx pour générer de nouvelles factures import { usestate } from 'react'; import parse from 'parse'; export default function newinvoice() { const \[invoicenumber, setinvoicenumber] = usestate(''); const \[amount, setamount] = usestate(0); const handlecreateinvoice = async () => { const invoice = parse object extend('invoice'); const invoice = new invoice(); invoice set('invoicenumber', invoicenumber); invoice set('amount', amount); invoice set('organizationid', parse user current() get('organizationid')); try { await invoice save(); alert('invoice created successfully!'); } catch (error) { console error('error creating invoice ', error); } }; return ( \<div> \<h1>create new invoice\</h1> \<input type="text" value={invoicenumber} onchange={(e) => setinvoicenumber(e target value)} placeholder="invoice number" /> \<input type="number" value={amount} onchange={(e) => setamount(parsefloat(e target value))} placeholder="amount" /> \<button onclick={handlecreateinvoice}>create\</button> \</div> ); } 6 2 visualisation des factures créer une page pages/invoices/index tsx pour voir toutes les factures avec des options de tri et de filtrage import { useeffect, usestate } from 'react'; import parse from 'parse'; export default function invoiceslist() { const \[invoices, setinvoices] = usestate(\[]); useeffect(() => { const fetchinvoices = async () => { const invoice = parse object extend('invoice'); const query = new parse query(invoice); const results = await query find(); setinvoices(results); }; fetchinvoices(); }, \[]); return ( \<div> \<h1>invoices\</h1> {invoices map(invoice => ( \<div key={invoice id}> \<h2>invoice #{invoice get('invoicenumber')}\</h2> \<p>amount ${invoice get('amount')}\</p> \<p>status {invoice get('status')}\</p> \</div> ))} \</div> ); } 7\ traitement des paiements (intégration stripe) 7 1 configurer stripe checkout pour traiter les paiements, intégrez stripe dans pages/invoices/\[id] tsx , implémentez la création de lien de paiement en utilisant stripe checkout import { userouter } from 'next/router'; import { useeffect, usestate } from 'react'; import stripe from 'stripe'; export default function invoicedetail() { const router = userouter(); const { id } = router query; const \[invoice, setinvoice] = usestate(null); useeffect(() => { if (!id) return; const fetchinvoice = async () => { const invoice = parse object extend('invoice'); const query = new parse query(invoice); query equalto('objectid', id); const result = await query first(); setinvoice(result); }; fetchinvoice(); }, \[id]); const handlepayinvoice = async () => { const stripe = new stripe(process env stripe secret key); const session = await stripe checkout sessions create({ payment method types \['card'], line items \[ { price data { currency 'usd', product data { name `invoice #${invoice get('invoicenumber')}` }, unit amount invoice get('amount') 100, }, quantity 1, }, ], mode 'payment', success url window\ location origin + '/success', cancel url window\ location origin + '/cancel', }); window\ location href = session url; }; if (!invoice) return \<div>loading \</div>; return ( \<div> \<h1>invoice #{invoice get('invoicenumber')}\</h1> \<p>amount ${invoice get('amount')}\</p> \<button onclick={handlepayinvoice}>pay now\</button> \</div> ); } 8\ notifications par e mail (intégration de renvoi) 8 1 envoi d'emails de factures configurer resend pour envoyer des emails de factures aux clients import { resend } from 'resend'; export default async function sendinvoiceemail(invoiceid) { const resend = new resend(process env resend api key); const invoice = await fetchinvoicedetails(invoiceid); // function to fetch invoice details const customer = await fetchcustomerdetails(invoice customerid); await resend sendemail({ from 'no reply\@invoicingapp com', to customer email, subject `invoice #${invoice invoicenumber}`, html `\<h1>invoice #${invoice invoicenumber}\</h1>\<p>amount ${invoice amount}\</p>`, }); } 9\ déploiement sur vercel pour déployer l'application sur vercel, installez le cli vercel et déployez npm install g vercel vercel configurez les variables d'environnement pour clerk, stripe, resend et back4app dans le tableau de bord vercel avant le déploiement 10\ conclusion dans ce tutoriel, nous avons construit une application complète de facturation avec next js, intégré back4app pour le backend, clerk pour l'authentification, stripe pour les paiements, et resend pour les notifications par email nous avons couvert la gestion des utilisateurs et des organisations, la création de factures, le traitement des paiements et le déploiement