Quickstarters
Comment construire un backend e-commerce ?
90 min
dans ce tutoriel pratique, vous allez créer une application e commerce complète et solide de a à z en utilisant un backend en tant que service en cours de route, vous maîtriserez une authentification utilisateur sécurisée, garantissant que seuls les acheteurs et les administrateurs autorisés ont accès des modèles de données intuitifs, conçus pour alimenter les catalogues de produits, les profils clients et les historiques de commandes des api restful et en temps réel, afin que votre frontend reste toujours synchronisé avec l'inventaire, les paniers et l'état de la commande des pipelines de déploiement automatisés, vous permettant de pousser des mises à jour en toute confiance et de revenir en arrière si quelque chose ne va pas à la fin, vous aurez non seulement une vitrine prête pour la production, mais aussi le savoir faire architectural pour étendre, évoluer et sécuriser toute application web découvrez l'application e commerce terminée en action à web e commerce app commençons! principaux enseignements configuration rapide du backend lancez et configurez un modèle de données e‑commerce complet en quelques minutes avec la plateforme low‑code de back4app flux utilisateurs sécurisés implémentez des processus d'inscription, de connexion et de déconnexion robustes en utilisant le cloud code et des jetons de session développement orienté api accédez à vos données via des points de terminaison rest/graphql auto générés et le sdk parse pour n'importe quel client logique métier dans le cloud code centralisez les opérations essentielles—crud produit, gestion du panier et paiement—tout en appliquant des permissions déploiement frontend conteneurisé emballez et déployez votre vitrine next js dans le déploiement web de back4app pour un hébergement cohérent et évolutif prérequis et configuration de l'environnement pour suivre ce tutoriel, assurez vous d'avoir les éléments suivants un compte back4app vous pouvez vous inscrire gratuitement sur le site web de back4app https //www back4app com/signup node js installé, vous permettant de gérer les dépendances avec npm ou yarn connaissance de javascript pour écrire du code cloud personnalisé et tirer parti du sdk de back4app compréhension de base des concepts de l'e commerce tels que l'authentification des utilisateurs, la gestion du catalogue de produits et le traitement des commandes git pour le contrôle de version, afin que vous puissiez suivre les modifications, revenir en arrière si nécessaire et collaborer sans effort s'assurer que vous avez les éléments ci dessus vous aidera à maximiser les capacités de back4app et à mettre en œuvre des fonctionnalités clés de commerce électronique sans vous laisser submerger créer et configurer votre compte back4app pour commencer à configurer votre backend de commerce électronique sur back4app, visitez back4app https //www back4app com et cliquez sur s'inscrire entrez votre adresse e mail, choisissez un mot de passe fort et fournissez les détails requis une fois que vous avez vérifié votre e mail, vous aurez accès au tableau de bord de back4app page d'inscription de back4app dans le tableau de bord, sélectionnez créer une nouvelle application ou créer une nouvelle application et donnez un nom à votre projet—quelque chose de descriptif afin que vous puissiez facilement le retrouver plus tard confirmez vos choix, puis attendez que le processus de création de l'application se termine le tableau de bord du projet affichera les classes, les analyses et les configurations creating a back4app app avec ces étapes, vous avez créé une plateforme de commerce électronique dans la section suivante, vous concevrez votre schéma de données et vous préparerez à la gestion des produits, au traitement des commandes et à l'authentification des utilisateurs conception de votre schéma de données de commerce électronique pour mettre en œuvre un backend évolutif et maintenable pour votre plateforme de commerce électronique, vous organiserez vos données autour de sept tables principales utilisateur , acheteur , vendeur , produit , panier , commande , et détailscommande chaque table joue un rôle spécifique dans le soutien de la fonctionnalité globale du système, et ensemble, elles forment un schéma normalisé et efficace commencez par la user table, qui sert de base à toutes les identités des utilisateurs chaque personne sur votre plateforme—quel que soit son rôle—s'authentifiera en utilisant cette table incluez des champs tels que username , password , et email pour gérer la connexion de base ajoutez emailverified pour suivre l'état de vérification, et authdata si vous prévoyez de prendre en charge les connexions tierces ou les flux oauth pour distinguer les acheteurs et les vendeurs, définissez un champ usertype ce champ vous permet de contrôler l'accès, de gérer les vues et de séparer les fonctionnalités en fonction des rôles des utilisateurs tout en maintenant un système de connexion unique et cohérent au lieu de mélanger tous les types d'utilisateurs dans une seule table, créez des tables séparées buyer et seller qui référencent user via le champ userid cela vous permet de stocker des données spécifiques aux rôles sans alourdir la table utilisateur principale la buyer table peut contenir des champs liés aux achats comme paymentinfo et shippingaddress , qui sont essentiels pour les processus de paiement et de livraison en revanche, la seller table suit les attributs pertinents pour les commerçants, tels que storename , bio , et phonenumber avec cette séparation, vous pouvez facilement gérer et interroger les acheteurs et les vendeurs indépendamment, tout en les reliant à leur identité partagée dans user votre produit table est l'endroit où les articles à vendre sont stockés chaque produit doit inclure des informations descriptives de base telles qu'un nom, une description détaillée et une ou plusieurs images pour la gestion des prix et des stocks, vous voudrez également inclure des champs pour le prix, le statut de disponibilité via un booléen isactive , et la quantité de stock sous quantityavailable il est crucial que chaque produit soit lié au vendeur qui l'a listé pour établir cette relation, ajoutez une sellerid clé étrangère qui référence la seller table cette structure garantit que chaque article de votre catalogue est lié à un marchand vérifié et rend le filtrage spécifique au vendeur simple pour gérer le comportement avant l'achat, introduisez une cart table chaque panier appartient à un utilisateur, donc incluez un userid champ qui se connecte à user stockez un tableau d'articles de panier items , chacun représentant un produit que l'utilisateur a l'intention d'acheter, ainsi que toute métadonnée dont vous avez besoin comme la quantité ou les options sélectionnées le suivi du totalprice du panier vous permet d'afficher rapidement des résumés de paiement sans recalculer les valeurs à chaque demande cette configuration prend en charge la fonctionnalité de base du panier et simplifie la persistance de session si vous trouvez la structure de tableau limitante—particulièrement si vous devez enregistrer des données plus complexes au niveau des articles—vous pouvez toujours refactoriser les articles dans une table séparée plus tard lorsqu'un acheteur passe une commande, vous enregistrerez la transaction dans la order table chaque commande est liée à un buyerid , référencant la buyer table pour garantir que l'acheteur est valide et autorisé en plus de ce lien, stockez la orderdate , le orderstatus , et la valeur monétaire totale sous le champ total cela vous donne un résumé clair de l'achat et soutient des flux de travail comme le suivi et l'exécution des commandes puisque chaque commande peut contenir plusieurs produits, vous aurez besoin d'une orderdetails table pour gérer les lignes individuelles cette table connecte chaque article à sa commande parente via orderid , et au produit acheté en utilisant productid pour enregistrer avec précision l'état de l'achat, incluez la quantité achetée et le prixunitaire au moment de la vente séparer les détails de la commande de cette manière vous permet de créer des rapports, de générer des factures et de gérer les retours ou ajustements avec précision ce schéma, avec sa séparation claire des préoccupations et son intégrité relationnelle, constitue une base solide pour votre système de commerce électronique avec le modèle de données maintenant aligné sur les flux de travail réels de votre plateforme, vous êtes prêt à commencer à l'implémenter dans votre backend commencez par configurer les tables user , acheteur , et vendeur , et construisez à partir de là configuration des classes dans le tableau de bord suivez les étapes ci dessous pour créer et lier vos entités dans back4app vous définirez des classes pour utilisateur , acheteur , vendeur , panier , produit , commande , et détailscommande , puis établissez des pointeurs pour représenter des relations telles que l'héritage, un à plusieurs et plusieurs à plusieurs accéder au navigateur de base de données ouvrez le tableau de bord de votre application et créez une nouvelle classe nommée utilisateur cliquez sur base de données dans le menu de gauche back4app dashboard création de la classe “utilisateur” back4app crée automatiquement une classe user la user classe est livrée avec les colonnes suivantes nom d'utilisateur mot de passe email etc pour ajouter la usertype colonne, sélectionnez ajouter une nouvelle colonne add new column fournissez le nom de la colonne, le type de données, la valeur par défaut, etc add usertype column remarque dans parse, chaque classe comprend un objectid par défaut, qui fonctionne comme la clé primaire cela signifie que objectid servira effectivement de userid dans votre modèle relationnel création de la classe “acheteur” pour créer la classe acheteur, retournez au navigateur de base de données et sélectionnez ajouter une classe create new class choisissez personnalisé et nommez le acheteur add buyer class ajoutez une colonne de pointeur appelée utilisateur , pointant vers la classe user create userid class cela simule l'“héritage” en référant à l' objectid , de l'utilisateur de base 3\ ajoutez les colonnes suivantes adressedelivraison (string) informationsdepaiement (string) lorsque vous créez un nouvel objet acheteur, vous le lierez à un enregistrement utilisateur existant en définissant acheteur utilisateur sur l'objectid de cet utilisateur création de la classe “vendeur” répétez le même processus pour créer une vendeur classe ajoutez une colonne pointeur nommée utilisateur référencant la classe utilisateur ajoutez ces colonnes supplémentaires nomdumagasin (string) bio (string) numérodetéléphone (number) création de la classe “produit” sélectionnez créer une classe à nouveau, en l'appelant produit ajoutez une colonne pointeur appelée vendeur pointant vers la classe vendeur (cela impose une relation un à plusieurs où un vendeur peut avoir plusieurs produits) ajoutez les colonnes suivantes nom (chaîne) description (chaîne) prix (nombre) quantitédisponible (nombre) estactif (booléen) images (tableau) stocke des objets qui représentent les images des produits création de la classe “panier” cliquez sur créer une classe , nommez la classe panier ajoutez une colonne pointeur appelée utilisateur pointant vers la classe utilisateur (cela lie chaque panier à un utilisateur spécifique) ensuite, ajoutez les colonnes suivantes pour représenter les articles dans le panier articles (tableau) stocke des objets qui représentent chaque article du panier chaque article peut être un objet comme { produit pointeur vers produit, quantité nombre } prixtotal (nombre) création de la classe “commande” créez une nouvelle classe nommée order ajoutez une colonne pointer appelée buyer qui pointe vers la classe buyer (indiquant qu'un acheteur peut avoir plusieurs commandes) incluez ces colonnes orderdate (date ou string, selon votre préférence) orderstatus (string) création de la classe “orderdetails” enfin, créez une classe nommée orderdetails ajoutez deux colonnes pointer order → référence order product → référence product ensuite, ajoutez les colonnes restantes quantity (nombre) unitprice (nombre) cette configuration permet une relation plusieurs à plusieurs entre order et product à travers orderdetails , puisque chaque commande peut inclure plusieurs produits, et chaque produit peut apparaître dans plusieurs commandes visualisation des relations voici un diagramme de relation d'entité simplifié (erd) reflétant les classes et leurs pointeurs dbschema2 une fois ces classes en place, vous pouvez gérer les inscriptions et les connexions via la classe user , créer des enregistrements spécialisés pour les acheteurs ou les vendeurs pour différents types d'utilisateurs, et stocker les informations sur les produits ou les commandes avec des références de clé étrangère claires en structurant votre base de données de cette manière, vous obtenez un design propre et maintenable pour toute application de commerce électronique avec votre schéma en place, vous êtes prêt à mettre en place l'authentification et l'autorisation pour restreindre qui peut lister des produits, passer des commandes ou effectuer des tâches administratives l'étape suivante vous montrera comment configurer des flux d'inscription et de connexion sécurisés qui s'appuient sur les rôles et les classes que vous venez de définir mise en œuvre de l'authentification avec back4app l'authentification sécurisée est centrale à toute plateforme de commerce électronique, vous aidant à protéger les comptes utilisateurs, les détails de paiement et les données personnelles back4app simplifie cela avec plusieurs méthodes—des combinaisons classiques de nom d'utilisateur/mot de passe aux connexions sociales ou aux flux basés sur des jetons—garantissant que vous pouvez offrir à vos acheteurs une expérience simple et sécurisée pour configurer l'authentification dans votre application de commerce électronique, vous utiliserez le code cloud le code cloud étend vos capacités backend en vous permettant d'écrire une logique métier personnalisée sans héberger vos propres serveurs cela signifie que vous pouvez valider des commandes, calculer des frais ou déclencher des notifications sur des événements spécifiques—entièrement au sein de l'infrastructure de back4app c'est un moyen idéal de gérer des transactions sensibles ou des processus de données qui nécessitent un contrôle strict et une exécution rapide pour activer le code cloud sur back4app, ouvrez le tableau de bord de votre application et localisez la section code cloud find cloud code lorsque vous cliquez sur code cloud , vous verrez un main js où vous pouvez commencer à implémenter des fonctions personnalisées cloud code pour mettre en œuvre le flux d'authentification dans back4app, vous devrez déployer certaines fonctions sur votre code cloud pour inscrire des utilisateurs, connecter des utilisateurs et déconnecter des utilisateurs enregistrer un nouvel utilisateur (acheteur par défaut) pour enregistrer un nouvel utilisateur, utilisez la méthode d'inscription de parse définissez des champs standard comme username , password , et email , et incluez un champ personnalisé pour indiquer le rôle soit buyer soit seller par défaut, les nouveaux utilisateurs se voient attribuer le rôle de buyer jusqu'à ce qu'ils choisissent de le changer pour commencer, créez un auth js fichier dans le répertoire cloud de votre code cloud et ajoutez le bloc de code ci dessous parse cloud define('signupuser', async (request) => { const { name, password, confirmpassword, email, shippingaddress, paymentinfo } = request params; // validate password match if (password !== confirmpassword) { throw new error('passwords do not match'); } const user = new parse user(); user set('username', name); user set('password', password); user set('email', email); user set('usertype', "buyer"); try { // sign up the user const signedupuser = await user signup(); console log('user registered ', signedupuser id); // create a buyer record linked to the new user const buyer = parse object extend('buyer'); const buyer = new buyer(); buyer set('user', signedupuser); buyer set('shippingaddress', shippingaddress); buyer set('paymentinfo', paymentinfo); const savedbuyer = await buyer save(); console log('buyer created ', savedbuyer id); return { success true, message 'user registered and buyer created', userid signedupuser id, buyerid savedbuyer id }; } catch (error) { console error('sign up failed ', error); throw new error('sign up failed ' + error message); } }); cette fonction cloud gère l'enregistrement des utilisateurs pour les acheteurs elle valide l'entrée, crée un nouvel utilisateur parse, attribue un rôle ( acheteur ), et stocke les données spécifiques aux acheteurs dans une classe acheteur séparée connexion des utilisateurs pour authentifier les utilisateurs, appelez la méthode intégrée de parse parse user login et renvoyez le jeton de session au client ajoutez le code suivant à votre auth js fichier pour implémenter cette logique dans votre backend de code cloud parse cloud define("loginuser", async (request) => { const { email, password } = request params; try { const user = await parse user login(email, password); // example block users with disabled flag if (user get("isdisabled")) { throw new parse error(403, "account is disabled"); } return { sessiontoken user getsessiontoken(), userid user id, }; } catch (error) { throw new parse error(101, "invalid credentials"); } }); cette fonction prend un email et un mot de passe du client, tente d'authentifier l'utilisateur et renvoie le jeton de session si cela réussit si le compte est signalé comme désactivé, il bloque l'accès et lance une erreur claire déconnexion pour implémenter la fonction de déconnexion pour votre backend, ajoutez le bloc de code ci dessous à votre auth js fichier parse cloud define('logoutuser', async (request) => { const sessiontoken = request headers\['x parse session token']; if (!sessiontoken) { throw new error('session token required'); } const sessionquery = new parse query(' session'); sessionquery equalto('sessiontoken', sessiontoken); const session = await sessionquery first({ usemasterkey true }); if (session) { await session destroy({ usemasterkey true }); } return { success true, message 'session invalidated' }; }); cela met fin de manière sécurisée à la session sur le backend, empêchant toute utilisation ultérieure du token avec ces fonctions cloud code en place, vous disposez maintenant d'un système d'authentification sécurisé qui enregistre les utilisateurs avec une logique basée sur les rôles authentifie et autorise l'accès en utilisant des tokens de session lie les comptes utilisateurs à des enregistrements spécifiques aux acheteurs prend en charge des flux de connexion et de déconnexion propres tire parti des outils de vérification de session et d'email intégrés de back4app construire la logique métier pour votre application ecommerce pour gérer les utilisateurs, les produits, les paniers et les transactions dans votre plateforme de commerce électronique, vous définirez une série de fonctions cloud code dans back4app créez un profil de vendeur pour un utilisateur qui souhaite offrir des produits sur la plateforme création d'un vendeur cette fonction met à jour le rôle de l'utilisateur actuel en vendeur et crée un vendeur avec des informations sur le magasin pour implémenter cela dans votre code cloud, créez d'abord un seller js fichier et ajoutez le bloc de code ci dessous parse cloud define('createseller', async (request) => { const currentuser = request user; // get the current logged in user if (!currentuser) { throw new error('user is not logged in'); } try { // check and update the user type const usertype = currentuser get('usertype'); if (usertype === 'buyer') { currentuser set('usertype', 'seller'); await currentuser save(); } // create the seller object const { businessname, bio, phone } = request params; const seller = parse object extend('seller'); const seller = new seller(); seller set('user', currentuser); seller set('storename', businessname); seller set('bio', bio); seller set('phonenumber', number(phone)); const newseller = await seller save(); console log('seller created ', newseller id); return { success true, message 'seller account created', sellerid newseller id }; } catch (error) { console error('error creating seller ', error); throw new error('error creating seller ' + error message); } }); cela garantit que seuls les utilisateurs authentifiés peuvent devenir des vendeurs, et cela lie le vendeur à l'utilisateur correspondant via un pointeur produit les produits sont listés par les vendeurs et peuvent être parcourus, interrogés et achetés par les acheteurs ces fonctions permettent aux vendeurs de créer, récupérer, mettre à jour et supprimer leurs produits, et fournissent également un accès aux produits pour les acheteurs créer un produit cette fonction ajoute un nouveau produit pour un vendeur connecté et attache jusqu'à trois images de produit pour l'implémenter dans votre code cloud, créez un product js fichier et ajoutez le bloc de code ci dessous parse cloud define("addproduct", async (request) => { // destructure parameters sent from the client const { name, description, price, quantityavailable, isactive, imagefiles } = request params; // optional check if user is logged in (request user is available when an active session exists) const currentuser = request user; if (!currentuser) { throw new error("unauthorized you must be logged in to add a product "); } // ensure the user is indeed a seller by checking their usertype const usertype = currentuser get("usertype"); if (usertype != "seller") { throw new error("this user is not a seller "); } const seller = parse object extend("seller"); const query = new parse query(seller); query equalto("userid", currentuser); // match the pointer field in seller const sellerobj = await query first({ usemasterkey true }); if (!sellerobj) { throw new error("no matching 'seller' object found for this user "); } if(!array isarray(imagefiles) || imagefiles length > 3) { throw new error("a maximum of 3 images are provided"); } // create the new product object const product = parse object extend("product"); const product = new product(); product set("seller", sellerobj); // pointer to the seller product set("name", name); product set("description", description); product set("price", number(price)); product set("quantityavailable", number(quantityavailable)); product set("isactive", isactive); product set("images", imagefiles); // save the product to the database try { const savedproduct = await product save(null, { usemasterkey true }); return savedproduct; } catch (error) { throw new error(`could not create product ${error message}`); } }); cette fonction vérifie que l'utilisateur est connecté et a un rôle de vendeur, qu'un objet vendeur correspondant existe, et qu'aucune soumission de plus de trois images n'est effectuée une fois validé, il stocke le produit et le lie au vendeur interrogation de tous les produits cette fonction récupère tous les produits dans le système, qui peuvent être utilisés pour construire une vitrine publique pour implémenter cela dans votre code cloud, ajoutez le bloc de code ci dessous à votre products js fichier parse cloud define("fetchallproducts", async (request) => { try { const product = parse object extend("product"); const query = new parse query(product); const products = await query find({ usemasterkey true }); // return products in a json friendly format return products map((product) => ({ id product id, sellerid product get("seller")? id, name product get("name"), description product get("description"), price product get("price"), quantityavailable product get("quantityavailable"), isactive product get("isactive"), createdat product createdat, updatedat product updatedat, })); } catch (error) { throw new error(`error fetching products ${error message}`); } }); cette fonction récupère les produits avec le usemasterkey drapeau, et les formate pour la consommation frontend interrogation d'un seul produit utilisez cette fonction lors de l'affichage des informations détaillées sur le produit aux acheteurs pour l'implémenter dans votre code cloud, ajoutez le bloc de code ci dessous à votre products js fichier parse cloud define("getsingleproduct", async (request) => { const { productid } = request params; const currentuser = request user; // ensure user is logged in if (!currentuser) { throw new error("you must be logged in to retrieve product information "); } if (!productid) { throw new error("missing required parameter productid "); } // query the product class const product = parse object extend("product"); const query = new parse query(product); query equalto("objectid", productid); try { const product = await query first({ usemasterkey true }); if (!product) { throw new error("product not found "); } // return a json friendly object return { objectid product id, name product get("name"), description product get("description"), price product get("price"), quantityavailable product get("quantityavailable"), isactive product get("isactive"), // optionally return more fields like images, category, etc }; } catch (error) { throw new error(`error fetching product ${error message}`); } }); cette fonction retourne les détails complets d'un produit pour un article elle vérifie qu'un productid valide est passé et s'assure que le demandeur est connecté interroger les produits du vendeur cette fonction permet à un vendeur de récupérer tous ses propres produits pour l'implémenter dans votre code cloud, ajoutez le bloc de code ci dessous à votre products js fichier parse cloud define("getsellerproducts", async (request) => { const currentuser = request user; // ensure the user is logged in if (!currentuser) { throw new error("you must be logged in to fetch seller products "); } // if your schema depends on verifying the user is truly a seller, you can check usertype const usertype = currentuser get("usertype"); if (usertype !== "seller") { throw new error("only sellers can view their own products "); } // if you want to retrieve products for the currently logged in seller // fetch the seller record that points to currentuser const seller = parse object extend("seller"); const sellerquery = new parse query(seller); sellerquery equalto("user", currentuser); const sellerrecord = await sellerquery first({ usemasterkey true }); if (!sellerrecord) { throw new error("no matching seller record found for the current user "); } // finally, fetch all products pointing to this seller const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("seller", sellerrecord); productquery limit(1000); // adjust or paginate as needed try { const products = await productquery find({ usemasterkey true }); // return a more friendly json structure return products map((prod) => ({ objectid prod id, name prod get("name"), description prod get("description"), price prod get("price"), quantityavailable prod get("quantityavailable"), isactive prod get("isactive"), createdat prod createdat, updatedat prod updatedat, })); } catch (error) { throw new error(`error fetching seller products ${error message}`); } }); cette fonction confirme que l'utilisateur est un vendeur, localise l'enregistrement associé de seller et interroge la classe product en utilisant un pointeur vers le vendeur les vendeurs utilisent cela pour récupérer tous leurs propres produits suppression d'un produit cette fonction garantit que seul le vendeur qui a créé un produit peut le supprimer pour mettre cela en œuvre dans votre code cloud, ajoutez le bloc de code ci dessous à votre products js fichier parse cloud define("deleteproduct", async (request) => { const { productid } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to delete a product "); } const usertype = currentuser get("usertype"); if (usertype !== "seller") { throw new error("only sellers can delete products "); } if (!productid) { throw new error("missing required parameter productid "); } // 1 find the seller record for the current user const seller = parse object extend("seller"); const sellerquery = new parse query(seller); sellerquery equalto("user", currentuser); const sellerrecord = await sellerquery first({ usemasterkey true }); if (!sellerrecord) { throw new error("no matching seller record found for the current user "); } // 2 fetch the product with a query that ensures the user owns it const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("objectid", productid); productquery equalto("seller", sellerrecord); // must match the correct seller const product = await productquery first({ usemasterkey true }); if (!product) { throw new error("product not found or you do not have permission to delete it "); } // 3 destroy the product try { await product destroy({ usemasterkey true }); return { message "product deleted successfully ", productid }; } catch (error) { throw new error(`error deleting product ${error message}`); } }); cette fonction confirme la propriété de l'utilisateur et supprime ensuite le produit de la base de données mise à jour d'un produit permettre aux vendeurs de modifier les détails d'un produit en utilisant cette fonction pour l'implémenter dans votre code cloud, ajoutez le bloc de code ci dessous à votre products js fichier parse cloud define("updateproduct", async (request) => { const { productid, name, description, price, quantityavailable, isactive } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to update a product "); } const usertype = currentuser get("usertype"); if (usertype !== "seller") { throw new error("only sellers can update products "); } if (!productid) { throw new error("missing required parameter productid "); } // 1 find the seller record for the current user const seller = parse object extend("seller"); const sellerquery = new parse query(seller); sellerquery equalto("user", currentuser); const sellerrecord = await sellerquery first({ usemasterkey true }); if (!sellerrecord) { throw new error("no matching seller record found for the current user "); } // 2 fetch the product const product = parse object extend("product"); const query = new parse query(product); query equalto("objectid", productid); query equalto("seller", sellerrecord); // must match the seller to ensure ownership const product = await query first({ usemasterkey true }); if (!product) { throw new error("product not found or you do not have permission to modify it "); } // 3 update product fields if (name !== undefined) product set("name", name); if (description !== undefined) product set("description", description); if (price !== undefined) product set("price", price); if (quantityavailable !== undefined) product set("quantityavailable", quantityavailable); if (isactive !== undefined) product set("isactive", isactive); // 4 save changes try { const updatedproduct = await product save(null, { usemasterkey true }); return { objectid updatedproduct id, name updatedproduct get("name"), description updatedproduct get("description"), price updatedproduct get("price"), quantityavailable updatedproduct get("quantityavailable"), isactive updatedproduct get("isactive"), }; } catch (error) { throw new error(`error updating product ${error message}`); } }); cela garantit que l'utilisateur est un vendeur, confirme la propriété du produit et met à jour uniquement les champs qui sont fournis dans la demande panier les panier fonctions permettent aux acheteurs de gérer les articles qu'ils souhaitent acheter ces fonctions incluent l'ajout au panier, la mise à jour des quantités, la visualisation du contenu et la suppression d'articles ajout au panier cette fonction ajoute un produit au panier de l'acheteur ou met à jour la quantité si le produit existe déjà pour l'implémenter, créez un cart js fichier et ajoutez le bloc de code ci dessous parse cloud define("addtocart", async (request) => { const { productid, quantity } = request params; // ensure there is a currently logged in user const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to modify the cart "); } if (!productid || !quantity) { throw new error("missing required parameters productid and quantity "); } // 1 fetch or create the user's cart const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", currentuser); let cart = await cartquery first({ usemasterkey true }); if (!cart) { cart = new cart(); cart set("user", currentuser); cart set("items", \[]); // initialize empty array cart set("totalprice", 0); // initialize price } // 2 fetch the product for price details (or any other attributes you need) const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("objectid", productid); const product = await productquery first({ usemasterkey true }); if (!product) { throw new error("product not found "); } const productprice = product get("price") || 0; // 3 insert or update the item in the cart const cartitems = cart get("items") || \[]; // check if this product is already in the cart const existingitemindex = cartitems findindex( (item) => item product objectid === productid ); if (existingitemindex >= 0) { // if product is already in cart, update the quantity cartitems\[existingitemindex] quantity += quantity; } else { // otherwise, add a new entry cartitems push({ product { type "pointer", classname "product", objectid productid, }, quantity quantity }); } // 4 recalculate total price // e g , summation of productprice quantity for each cart item let total = 0; for (const item of cartitems) { if (item product objectid === productid) { // use productprice from the newly fetched product total += productprice item quantity; } else { // this is a simplified approach ideally, you'd also store a price attribute on each item // or re fetch each product's price // for demonstration, we'll just skip them } } cart set("items", cartitems); cart set("totalprice", total); // 5 save the cart object try { const savedcart = await cart save(null, { usemasterkey true }); return { message "cart updated successfully", cartid savedcart id, items savedcart get("items"), totalprice savedcart get("totalprice"), }; } catch (error) { throw new error(`error saving cart ${error message}`); } }); il garantit que l'utilisateur est authentifié, valide le produit, met à jour la liste des articles et recalcule le prix total du panier interroger le panier récupérer le contenu du panier de l'utilisateur actuel, y compris les détails des produits et les sous totaux pour mettre cela en œuvre, ajoutez le bloc de code ci dessous à votre cart js fichier parse cloud define("getcart", async (request) => { if (!request user) throw "user must be logged in "; const user = request user; const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", user); cartquery include("items product"); // deep include const cart = await cartquery first(); if (!cart) return { items \[], totalprice 0 }; const items = cart get("items") || \[]; const parseditems = \[]; for (const item of items) { const product = item product; parseditems push({ productid product id, name product get("name"), price product get("price"), image product get("image")? url() || null, quantity item quantity, subtotal product get("price") item quantity, }); } return { cartid cart id, items parseditems, totalprice cart get("totalprice") || 0, }; }); cette fonction utilise include("items product") pour récupérer les données de produit imbriquées en une seule requête modifier le panier mettez à jour la quantité d'un article dans le panier ou supprimez le complètement si la nouvelle quantité est zéro pour mettre cela en œuvre, ajoutez le bloc de code ci dessous à votre cart js fichier parse cloud define("updatecart", async (request) => { const { productid, newquantity } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to update the cart "); } if (!productid || newquantity === undefined) { throw new error("missing required parameters productid and newquantity "); } // fetch or create the user's cart const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", currentuser); let cart = await cartquery first({ usemasterkey true }); if (!cart) { // if there's no existing cart, create one cart = new cart(); cart set("user", currentuser); cart set("items", \[]); cart set("totalprice", 0); } let cartitems = cart get("items") || \[]; // find the item matching the productid const itemindex = cartitems findindex( (item) => item product id === productid ); if (itemindex === 1) { throw new error("product not found in cart please add it first "); } // if newquantity <= 0, remove the item from the cart if (newquantity <= 0) { cartitems splice(itemindex, 1); } else { // otherwise, update the quantity cartitems\[itemindex] quantity = newquantity; } // recalculate total by fetching current prices from each product let total = 0; if (cartitems length > 0) { const product = parse object extend("product"); // for each item in the cart, fetch the product to get its price for (const item of cartitems) { const productquery = new parse query(product); productquery equalto("objectid", item product objectid); const product = await productquery first({ usemasterkey true }); if (product) { const productprice = product get("price") || 0; total += productprice item quantity; } } } // update and save the cart cart set("items", cartitems); cart set("totalprice", total); try { const updatedcart = await cart save(null, { usemasterkey true }); return { message "cart updated successfully", cartid updatedcart id, items updatedcart get("items"), totalprice updatedcart get("totalprice"), }; } catch (error) { throw new error(`error updating cart ${error message}`); } }); il revalide tous les prix des produits lors de la mise à jour pour garantir une précision totale supprimer du panier cette fonction supprime un produit du panier de l'utilisateur pour l'implémenter, ajoutez le bloc de code ci dessous à votre cart js fichier parse cloud define("removefromcart", async (request) => { const { productid } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to remove items from the cart "); } if (!productid) { throw new error("missing required parameter productid "); } // fetch the user's cart const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", currentuser); const cart = await cartquery first({ usemasterkey true }); if (!cart) { throw new error("no existing cart found for this user "); } let cartitems = cart get("items") || \[]; // filter out the item with the specified productid const filtereditems = cartitems filter( (item) => item product id !== productid ); // if nothing changed, the product wasn't in the cart if (filtereditems length === cartitems length) { throw new error("product not found in cart "); } // recalculate the cart total let total = 0; if (filtereditems length > 0) { const product = parse object extend("product"); for (const item of filtereditems) { const productquery = new parse query(product); productquery equalto("objectid", item product objectid); const product = await productquery first({ usemasterkey true }); if (product) { const productprice = product get("price") || 0; total += productprice item quantity; } } } // update and save the cart cart set("items", filtereditems); cart set("totalprice", total); try { const updatedcart = await cart save(null, { usemasterkey true }); return { message "item removed from cart", cartid updatedcart id, items updatedcart get("items"), totalprice updatedcart get("totalprice"), }; } catch (error) { throw new error(`error removing item from cart ${error message}`); } }); il filtre l'élément du tableau du panier et recalcule le total avant de sauvegarder commande ces fonctions gèrent le processus de commande—de la création de commandes à la récupération de l'historique des commandes d'un vendeur créer une commande cette fonction convertit le panier de l'acheteur en une commande officielle pour mettre cela en œuvre, créez un order js fichier et ajoutez le bloc de code ci dessous parse cloud define("createorder", async (request) => { const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to place an order "); } // ensure the user is a buyer (assumes buyer class with user pointer) const buyer = parse object extend("buyer"); const buyerquery = new parse query(buyer); buyerquery equalto("user", currentuser); const buyer = await buyerquery first({ usemasterkey true }); if (!buyer) { throw new error("only buyers can place orders "); } // retrieve the cart for the user const cart = parse object extend("cart"); const cartquery = new parse query(cart); cartquery equalto("user", buyer get("user")); // assuming the user pointer is stored in buyer const cart = await cartquery first({ usemasterkey true }); if (!cart || !cart get("items") || cart get("items") length === 0) { throw new error("cart is empty"); } const items = cart get("items"); let totalamount = 0; // adjust stock and calculate total order price const orderdetails = \[]; for (const item of items) { const productid = item product id; const quantity = item quantity; const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("objectid", productid); const product = await productquery first({ usemasterkey true }); if (!product) { throw new error(`product with id ${productid} not found`); } const availablequantity = product get("quantityavailable"); if (availablequantity < quantity) { throw new error(`not enough stock for product ${product get("name")}`); } // reduce the product quantity product set("quantityavailable", availablequantity quantity); await product save(null, { usemasterkey true }); const unitprice = product get("price"); totalamount += unitprice quantity; // prepare order detail entry orderdetails push({ product, quantity, unitprice }); } // create the new order object const order = parse object extend("order"); const order = new order(); order set("buyer", buyer); // set the buyer pointer order set("total", totalamount); // set the total amount order set("orderstatus", "pending"); // set the order status order set("orderdate", new date()); // set the order date // save the order to the database try { const savedorder = await order save(null, { usemasterkey true }); // create orderdetails for each item const orderdetails = parse object extend("orderdetails"); for (const detail of orderdetails) { const orderdetail = new orderdetails(); orderdetail set("order", savedorder); orderdetail set("product", detail product); orderdetail set("quantity", detail quantity); orderdetail set("unitprice", detail unitprice); await orderdetail save(null, { usemasterkey true }); } // optionally, clear the cart after saving the order cart set("items", \[]); await cart save(null, { usemasterkey true }); return savedorder; } catch (error) { throw new error(`could not create order ${error message}`); } }); il valide l'acheteur, vérifie la disponibilité des stocks, réduit l'inventaire des produits, économise à la fois commande et détailsdecommande , et vide le panier après une commande réussie obtenir les commandes des vendeurs cette fonction récupère toutes les commandes qui incluent des produits vendus par le vendeur actuel pour l'implémenter, ajoutez le bloc de code ci dessous à votre order js fichier parse cloud define("getsellerorders", async (request) => { const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to view your orders "); } if (currentuser get("usertype") !== "seller") { throw new error("only sellers can access this endpoint "); } try { const seller = parse object extend("seller"); const seller = await new parse query(seller) equalto("userid", currentuser) first({ usemasterkey true }); if (!seller) { throw new error("seller profile not found "); } // find products by this seller const product = parse object extend("product"); const productquery = new parse query(product); productquery equalto("seller", seller); const products = await productquery find({ usemasterkey true }); if (!products || products length === 0) { return \[]; } // get product ids const productids = products map(product => product id); // find order details containing these products const orderdetails = parse object extend("orderdetails"); const orderdetailsquery = new parse query(orderdetails); orderdetailsquery containedin("product", products); const orderdetails = await orderdetailsquery find({ usemasterkey true }); if (!orderdetails || orderdetails length === 0) { return \[]; } const orderids = \[ new set(orderdetails map(detail => detail get("order") id))]; // query orders for these ids const order = parse object extend("order"); const orderquery = new parse query(order); orderquery containedin("objectid", orderids); orderquery include("buyer"); const orders = await orderquery find({ usemasterkey true }); // return the orders return orders map(order => ({ id order id, total order get("total"), status order get("orderstatus"), date order get("orderdate"), buyer order get("buyer") })); } catch (error) { throw new error(`could not fetch orders ${error message}`); } }); il localise les produits appartenant au vendeur, interroge orderdetails pour ces produits, récupère les commandes correspondantes et renvoie une structure simplifiée incluant les informations de l'acheteur mise à jour du statut de la commande cette fonction bascule le statut d'une commande entre « en attente » et « terminé » pour l'implémenter, ajoutez le bloc de code ci dessous à votre order js fichier parse cloud define("updateorder", async (request) => { const { orderid } = request params; const currentuser = request user; if (!currentuser) { throw new error("you must be logged in to view your orders "); } if (currentuser get("usertype") !== "seller") { throw new error("only sellers can access this endpoint "); } // validate the input parameter if (!orderid) { throw new error("missing required field orderid"); } try { // find the order with the specified orderid const order = parse object extend("order"); const query = new parse query(order); query equalto("objectid", orderid); const order = await query first({ usemasterkey true }); if (!order) { throw new error("order not found"); } // check current status // update the order status if (order get("orderstatus") === "completed") { order set("orderstatus", "pending"); } else { order set("orderstatus", "completed"); } // save the updated order await order save(null, { usemasterkey true }); return { success true, message "order status updated to completed" }; } catch (error) { throw new error(`could not update order status ${error message}`); } }); cela garantit que seuls les vendeurs peuvent effectuer cette action et que la commande existe avant de mettre à jour le statut ces fonctions backend donnent à votre application de commerce électronique la capacité de gérer en toute sécurité toutes les opérations essentielles listes de produits, paniers d'acheteurs, commandes et inventaire des vendeurs, directement dans back4app en utilisant cloud code pour vous assurer que vous pouvez accéder à ces fonctions cloud de l'extérieur, vous devez enregistrer tous vos fichiers de code cloud dans votre main js fichier, vous pouvez le faire en ajoutant le bloc de code ci dessous à votre main js fichier //main js require(" /auth js") require(" /cart js") require(" /order js") require(" /product js") require(" /seller js") création de l'interface utilisateur pour construire visuellement votre vitrine de commerce électronique, vous utiliserez v0 dev pour ce faire, commencez par visiter v0 dev http //v0 dev créez un compte si vous n'en avez pas déjà un une fois votre compte configuré, vous pouvez commencer à créer votre interface utilisateur pour créer votre interface utilisateur, entrez l'invite ci dessous create an e commerce web application with authentication features and a buyer and seller feature l'invite construira une application de commerce électronique next js avec les fonctionnalités demandées create ecommerce app en utilisant la fonction d'aperçu, vous pouvez naviguer à travers l'application pour confirmer que tout fonctionne comme prévu s'il y a des complications ou si vous souhaitez ajouter plus de fonctionnalités, vous pouvez passer une autre invite et v0 modifiera l'application par exemple, passez l'invite the seller can create, add, delete and update products cette invite modifiera l'application, créant des pages où le vendeur peut effectuer des opérations crud modify ecommerce app enfin, passez l'invite do not sort products by categories and remove the categories page and input fields, remove the second and third step from the process of becoming a seller and add a bio input field to the first step, users should only sign in with email, and enhance the seller functionality to fully support product management (crud operations) cette invite fera les dernières modifications à l'application pour obtenir un aperçu de l'application modifiée, cliquez sur le voir bouton dans la section surlignée de l'image ci dessus une fois que vous êtes sûr que l'application est ce que vous voulez, l'étape suivante consiste à obtenir le projet sur votre appareil local pour ce faire, cliquez sur le bouton de téléchargement que v0 génère avec la réponse de l'invite bouton de téléchargement cliquer sur le bouton révélera un menu déroulant avec un lien et un télécharger zip bouton menu déroulant ensuite, cliquez sur le télécharger zip bouton une fois que vous avez terminé de télécharger le zip, ouvrez votre terminal et créez un nouveau dossier appelé ecommerce app dans votre répertoire préféré mkdir ecommerce app maintenant, extrayez le contenu du dossier zip dans le dossier ecommerce app accédez au répertoire ecommerce app sur votre terminal et installez les dépendances nécessaires pour ce faire, exécutez la commande suivante cd ecommerce app npm install après avoir installé les dépendances, exécutez la npm run dev commande sur votre terminal pour voir le projet sur votre serveur localhost intégrer votre frontend avec votre backend pour connecter votre frontend avec les fonctions cloud code dans votre backend back4app, vous utiliserez le sdk javascript parse le sdk vous permet d'authentifier les utilisateurs, d'appeler des fonctions backend et d'interagir avec les modèles de données de votre application de manière sécurisée et efficace pour configurer le sdk, exécutez la commande suivante dans le répertoire de votre projet dans votre terminal npm install parse ensuite, créez un lib/parse js fichier pour configurer la connexion dans ce fichier, saisissez le bloc de code ci dessous import parse from "parse/dist/parse min js"; parse initialize("your app id", "your javascript key"); parse serverurl = "https //parseapi back4app com"; export default parse; remplacez your app id et your javascript key par les identifiants trouvés dans votre tableau de bord back4app sous app settings cette configuration de base garantit que le sdk sait comment se connecter à votre projet spécifique maintenant que vous avez connecté votre frontend à votre backend, vous pouvez commencer à écrire des fonctions pour appeler les fonctions de code cloud que vous avez définies dans votre application back4app authentification sur le client cette section montre comment gérer l'inscription, la connexion et la déconnexion des utilisateurs dans votre frontend en utilisant le sdk parse chaque fonction correspond à une fonction de code cloud ou à une méthode sdk que vous avez implémentée dans votre backend back4app dans votre application, le app/auth/register répertoire contient la logique pour inscrire des utilisateurs dans le page tsx définissez l'état formdata cet état contiendra les identifiants nécessaires pour inscrire un utilisateur l'état formdata devrait ressembler à ceci const \[formdata, setformdata] = usestate({ name "", email "", password "", confirmpassword "", shippingaddress "", paymentinfo "", }); avec les identifiants passés dans le formdata , vous pouvez appeler la signupuser fonction cloud que vous avez définie dans votre application back4app assurez vous d'importer parse depuis le lib/parse js import parse from "@/lib/parse"; const handlesubmit = async(e react formevent) => { e preventdefault(); try { const response = await parse cloud run("signupuser", { name formdata name, email formdata email, password formdata password, confirmpassword formdata confirmpassword, shippingaddress formdata shippingaddress, paymentinfo formdata paymentinfo, }); console log("signup successful ", response); } catch (error any) { console error("signup failed ", error); } } cette fonction s'exécutera lorsque vous soumettez le formulaire d'inscription elle appelle la signupuser fonction cloud définie dans le cloud code la fonction passe les identifiants de l'utilisateur et les données spécifiques à l'acheteur (comme les informations d'expédition et de paiement) enfin, elle enregistre la réponse si l'opération est réussie ou imprime une erreur si elle échoue connexion des utilisateurs pour connecter un utilisateur, utilisez la loginuser fonction de code cloud dans votre backend accédez au app/auth/login répertoire de votre application dans le page tsx fichier, v0 aura créé l'état contenant les informations d'identification de l'utilisateur dont vous avez besoin pour connecter l'utilisateur, il vous suffit de passer ces informations d'identification à la loginuser fonction par exemple import parse from "@/lib/parse"; const handlesubmit = async (e react formevent) => { e preventdefault(); setisloading(true); try { const result = await parse cloud run("loginuser", { email, password }); // log in using returned session token await parse user become(result sessiontoken); console log("user logged in with session ", result sessiontoken); setisloading(false); router push("/"); // proceed to app } catch (error) { console error("login failed ", error); } }; cette fonction invoque la fonction cloud loginuser , envoyant les informations d'identification de connexion de l'utilisateur au serveur après avoir reçu un jeton de session valide en réponse, elle utilise parse user become pour authentifier le client et établir la session comme appartenant à l'utilisateur connecté déconnexion des utilisateurs pour déconnecter un utilisateur de manière sécurisée, vous appellerez à la fois parse user logout() et votre fonction cloud code personnalisée logoutuser cela garantit que le jeton de session est effacé à la fois sur le client et invalidé sur le serveur vous trouverez le bouton de déconnexion dans votre composant d'en tête ce composant se trouvera dans votre components dossier dans le répertoire racine dans le composant, définissez cette fonction const handlelogout = async () => { const sessiontoken = parse user current()? get("sessiontoken"); if (sessiontoken) { await parse user become(sessiontoken); // ensures proper context await parse cloud run("logoutuser"); // delete the session on server } await parse user logout(); // clear the local session }; cette fonction déconnectera un utilisateur et effacera la session à la fois sur le client et le serveur dans la partie jsx du composant, liez la fonction au bouton de déconnexion en utilisant l'événement onclick par exemple \<dropdownmenuitem onclick={handlelogout}> logout \</dropdownmenuitem> intégration des vendeurs cette section montre une fonction permettant aux acheteurs de mettre à niveau leur compte et de s'inscrire en tant que vendeurs dans votre application, naviguez vers le app/seller/register répertoire dans ce répertoire, vous trouverez votre page tsx fichier où vous définirez la fonction qui appelle la createseller fonction cloud cette fonction est responsable de la création d'un profil de vendeur pour l'utilisateur actuel dans le page tsx fichier, modifiez l'état formdata pour qu'il ressemble à ceci const \[formdata, setformdata] = usestate({ phone "", bio "", businessname "", }); remplacez la logique dans la fonction handlesubmit créée par v0 par la logique ci dessous const handlesubmit = async (e react formevent) => { e preventdefault(); try { const result = await parse cloud run("createseller", { businessname formdata businessname, bio formdata bio, phone formdata phone, }); console log("seller created ", result sellerid); } catch (error) { console error("error creating seller ", error); } }; appelez cette fonction lors de la soumission du formulaire pour créer un profil de vendeur pour vos utilisateurs gestion des produits utilisez ces appels de fonction dans votre frontend pour gérer les opérations de produit en tant que vendeur création d'un produit pour appeler la fonction de code cloud qui ajoute un produit à la base de données, localisez le app/seller/products/new répertoire dans ce répertoire se trouve votre page tsx fichier, dans ce fichier se trouve un formulaire ce formulaire prend les informations pour le produit, y compris les images modifiez l'état du produit pour qu'il ressemble à ceci const \[product, setproduct] = usestate({ name "", price "", description "", stock "", status "active", }); créez également un état pour conserver vos images const \[images, setimages] = usestate\<file\[]>(\[]); maintenant, écrivez une fonction pour gérer l'ajout des images à la base de données cette fonction devrait ressembler à ceci const handleimageupload = async (event) => { event preventdefault(); try { let name = "image jpg"; const file = new parse file(name, event target files\[0]); const photo = await file save(); setimages((prev) => \[ prev, photo]); console log("file saved ", file); alert(`image uploaded successfully`); } catch (error) { console error("error saving file ", error); } }; liez cette fonction à l'entrée responsable du téléchargement de fichiers en utilisant l' onchange événement ensuite, définissez la fonction handlesubmit cette fonction appelle le addproduct code cloud tout en passant les informations nécessaires comme ceci const handlesubmit = async (e react formevent) => { e preventdefault(); try { interface addproductparams { name string; description string; price number; quantityavailable number; isactive boolean; } interface addproductresponse { id string; } parse cloud run\<addproductresponse, addproductparams>("addproduct", { name product name, description product description, price product price, quantityavailable product stock, isactive product status === "active", imagefiles images, }) then((response) => { console log("product created ", response id); }); } catch (error) { console error("error creating product ", error); } }; cet appel soumet les données du produit—y compris les images—au backend pour créer une nouvelle annonce récupérer tous les produits cet appel récupère l'ensemble du catalogue pour les annonces de produits publiques ou un fil d'accueil pour créer la fonction qui appelle la fetchallproducts fonction cloud, naviguez vers le app/products répertoire dans le page tsx fichier, ajoutez ce code interface product { id string; name string; description string; price number; image? string; } const \[products, setproducts] = usestate\<product\[]>(\[]); async function getallproducts() { try { const response = await parse cloud run("fetchallproducts"); console log("products fetched ", response); return response; } catch (error) { console error("error fetching products ", error); throw error; } } ce bloc de code ci dessus définit une interface pour les produits et un products état la getallproducts fonction appelle la fonction cloud fetchallproducts pour obtenir tous les produits dans la base de données notez que vous devez appeler la getallproducts fonction ci dessus à l'intérieur d'un useeffect() hook pour récupérer et afficher les produits au chargement de la page comme ceci useeffect(() => { getallproducts() then((products) => { setproducts(products); }) catch((error) => { console error("error fetching products ", error); }); }, \[]); obtenir un produit unique cet appel récupère les détails complets d'un produit spécifique naviguez vers le \[id] dossier dans votre app/products répertoire ce dossier contient le page tsx fichier qui contiendra la logique pour récupérer les détails d'un produit unique dans le page tsx fichier, écrivez ce code interface product { id string; name string; description string; price number; images? string\[]; quantityavailable number; } const \[product, setproduct] = usestate\<product>({ id "", name "", description "", price 0, images \[], quantityavailable 0, }); async function getsingleproduct() { try { const response = await parse cloud run("getsingleproduct", {productid params id}); console log("product fetched ", response); return response; } catch (error) { console error("error fetching products ", error); throw error; } } useeffect(() => { getsingleproduct() then((product) => { setproduct(product); }) catch((error) => { console error("error fetching products ", error); }); }, \[]); ce bloc de code définit l'interface pour l'objet produit, configure une variable d'état product avec des valeurs par défaut la getsingleproduct fonction appelle votre getsingleproduct fonction de code cloud en utilisant un productid des paramètres de route ce useeffect hook s'exécute une fois lorsque le composant est monté mettre à jour un produit lorsqu'un vendeur modifie un produit, appelez cette fonction avec les champs mis à jour pour mettre à jour les produits, vous avez besoin d'un formulaire avec des champs de saisie collectant les nouvelles données, vous pouvez trouver ce formulaire dans le page tsx fichier situé dans le app/seller/products/\[id]/edit répertoire avant de mettre à jour un produit, vous devez récupérer le produit et pour ce faire, ajoutez ce code à votre page tsx fichier const \[product, setproduct] = usestate({ id "", name "", price "", description "", stock "", images \["", "", ""], status "active", }); useeffect(() => { async function fetchproduct() { try { const response = await parse cloud run("getsingleproduct", { productid params id, }); setproduct({ id response objectid, name response name || "", price string(response price ?? "0"), description response description || "", stock string(response quantityavailable ?? "0"), // fallback to placeholders if actual image data is not provided images \[ response image1 || `/placeholder svg?height=500\&width=500\&text=product`, response image2 || `/placeholder svg?height=500\&width=500\&text=productview+2`, response image3 || `/placeholder svg?height=500\&width=500\&text=productview+3`, ], status response isactive ? "active" "out of stock", }); } catch (error) { console error("error fetching product ", error); } } fetchproduct(); }, \[]); ce code récupère les détails d'un produit unique depuis votre backend back4app avec la getsingleproduct fonction de code cloud et stocke les détails dans l'état du composant product pour les afficher comme valeur par défaut dans votre formulaire avant de le modifier après avoir récupéré les détails du produit, vous pouvez modifier les détails à l'aide du formulaire après avoir rempli le formulaire, la soumission du formulaire appellera une handlesubmit fonction qui contiendra la logique pour mettre à jour votre produit votre handlesubmit fonction devrait ressembler à ceci const handlesubmit = async (e react formevent) => { e preventdefault(); try { await parse cloud run("updateproduct", { productid product id, name product name, description product description, price parsefloat(product price), quantityavailable parseint(product stock, 10), isactive product status === "active", }); } catch (error) { console error("error updating product ", error); } }; cette fonction appelle votre updateproduct fonction cloud code et envoie un objet avec les données du produit mises à jour supprimer un produit utilisez cette fonction pour supprimer un produit après confirmation du vendeur pour supprimer un produit, vous devez ajouter une handledelete fonction qui contient la logique nécessaire pour supprimer le produit vous définirez la handledelete fonction dans le page tsx fichier dans le app/seller/products/\[id]/edit répertoire const handledelete = async () => { const confirmdelete = confirm( "are you sure you want to delete this product? this action cannot be undone " ); if (!confirmdelete) return; try { await parse cloud run("deleteproduct", { productid product id, }); } catch (error) { console error("error deleting product ", error); } }; la handledelete fonction confirme d'abord l'intention de l'utilisateur avant d'appeler la deleteproduct fonction de code cloud définie dans votre backend liez la handledelete fonction au bouton de suppression dans la partie jsx du composant par exemple \<button type="button" variant="destructive" onclick={handledelete} \> \<trash2 classname="h 4 w 4 mr 2" /> delete product \</button> obtenir les produits du vendeur utilisez ceci pour récupérer tous les produits appartenant au vendeur actuellement connecté vous définirez la fonction pour gérer la récupération des produits du vendeur dans le page tsx fichier dans le app/seller/dashboard répertoire dans le fichier, écrivez ce code const \[products, setproducts] = usestate< { objectid string; name string; price number; quantityavailable number; sales number; isactive boolean; }\[] \>(\[]); useeffect(() => { async function fetchproducts() { try { const result = await parse cloud run("getsellerproducts"); setproducts(result); } catch (error) { console error("error fetching products ", error); } }; fetchproducts(); }, \[]); ce bloc de code définit l'état products et utilise le hook useeffect pour appeler la fonction fetchproducts une fois au chargement la fonction fetchproducts appelle la fonction de code cloud getsellerproducts et met à jour l'état products avec le résultat de l'appel gestion du panier ces appels permettent aux acheteurs de gérer leur panier avant de passer une commande ajouter au panier cet appel ajoute un produit sélectionné au panier de l'utilisateur ou incrémente sa quantité localisez le fichier page tsx dans le répertoire app/products et ajoutez les lignes de code suivantes async function handleaddtocart(productid string, quantity number = 1) { try { const response = await parse cloud run("addtocart", { productid, quantity, }); console log("add to cart success ", response); } catch (error) { console error("failed to add to cart ", error); } } la fonction handleaddtocart accepte productid et une quantité optionnelle comme arguments et appelle le code cloud addtocart sur votre backend cette fonction doit s'exécuter lorsque vos utilisateurs cliquent sur le bouton "ajouter au panier" dans votre carte produit par exemple \<button classname="w full" size="sm" onclick={() => handleaddtocart(product id)}> \<shoppingcart classname="h 4 w 4 mr 2" /> add to cart \</button> dans le fichier, écrivez ce code voir le panier utilisez ceci pour récupérer le contenu du panier et afficher un résumé en direct du panier pour ce faire, naviguez vers le page tsx fichier dans le app/cart répertoire, puis ajoutez le bloc de code ci dessous interface cartitem { id string; // product's objectid name string; price number; quantity number; image string; } const \[cartitems, setcartitems] = usestate\<cartitem\[]>(\[]); useeffect(() => { async function fetchcart() { try { const response = await parse cloud run("getcart"); const parsed = response items map((item) => ({ id item productid, name item name, price item price, quantity item quantity, image item image, })); setcartitems(parsed); } catch (error) { console error("failed to fetch cart ", error); } } fetchcart(); }, \[]); le bloc de code ci dessus définit la structure des données du panier dans le frontend avec l'interface cartitem , définit l'état cartitems qui contient les articles du panier il utilise également useeffect pour déclencher la fonction fetchcart une fois au chargement de la page la fonction fetchcart appelle la fonction de code cloud getcart et récupère le panier depuis votre backend elle utilise la méthode map pour convertir le format backend en format frontend avant de sauvegarder les données du panier traitées dans l'état cartitems mettre à jour l'élément du panier cet appel change la quantité d'un produit spécifique dans le panier dans le page tsx fichier dans le app/cart répertoire, vous trouverez une updatequantity fonction remplacez cette fonction par celle ci dessous const updatequantity = async (productid string, newquantity number) => { if (newquantity < 1) return; try { await parse cloud run("updatecart", { productid, newquantity, }); console log("updated the cart"); } catch (error) { console error("failed to update cart item ", error); } }; cette fonction prend deux paramètres, productid et la quantité mise à jour que l'utilisateur souhaite définir newquantity elle appelle votre updatecart fonction cloud et envoie à la fois le productid et le newquantity comme paramètres vous liez cette fonction aux boutons +/ en utilisant l'événement onclick comme ceci \<div classname="flex items center gap 2"> \<button variant="outline" size="icon" classname="h 8 w 8" onclick={() => updatequantity(item id, item quantity 1)} \> \<minus classname="h 3 w 3" /> \<span classname="sr only">decrease quantity\</span> \</button> \<span classname="w 8 text center">{item quantity}\</span> \<button variant="outline" size="icon" classname="h 8 w 8" onclick={() => updatequantity(item id, item quantity + 1)} \> \<plus classname="h 3 w 3" /> \<span classname="sr only">increase quantity\</span> \</button> \</div> retirer du panier retire un article complètement du panier pour ce faire, ajoutez le bloc de code ci dessous au page tsx fichier dans le app/cart répertoire dans ce fichier const removeitem = async (productid string) => { try { await parse cloud run("removefromcart", { productid, }); setcartitems((items) => items filter((item) => item id !== productid)); } catch (error) { console error("failed to remove item ", error); } }; cette fonction, removeitem , retire un produit spécifique du panier de l'utilisateur en appelant la fonction cloud removefromcart sur le backend la fonction met également à jour l'état local du panier dans le frontend pour refléter le changement liez cette fonction au bouton "retirer l'article", comme ceci \<button variant="ghost" size="icon" classname="h 8 w 8 text muted foreground" onclick={() => removeitem(item id)} \> \<trash2 classname="h 4 w 4" /> \<span classname="sr only">remove item\</span> \</button> gestion des commandes ces fonctions gèrent la création et le suivi des commandes pour les acheteurs et les vendeurs créer une commande cela crée une commande à partir du contenu actuel du panier de l'utilisateur vous définissez également cette fonction dans le page tsx fichier dans le app/cart répertoire la fonction contenant la logique pour créer la commande devrait ressembler à ceci const handleorder = async () => { try { const user = parse user current(); if (!user) { throw new error("you must be logged in to place an order "); } const result = await parse cloud run("createorder"); console log("order created successfully ", result); } catch (error any) { console error("failed to create order ", error); } }; cette fonction, handleorder , gère le processus de paiement en passant une commande via votre backend back4app elle vérifie si un utilisateur est connecté, puis appelle la createorder fonction cloud pour convertir le panier actuel de l'utilisateur en une commande officielle pour appeler cela lors du paiement, liez la fonction au bouton "checkout" en utilisant l'événement onclick par exemple \<button classname="w full" onclick={handleorder}>proceed to checkout\</button> voir les commandes des vendeurs les vendeurs peuvent utiliser cet appel pour voir les commandes qui incluent leurs produits définissez cette fonction dans le page tsx fichier dans le app/seller/dashboard répertoire ajoutez les lignes de code suivantes au fichier page tsx const \[ordersdata, setordersdata] = usestate<{ id string; total number; buyer string; date date; status string; }\[] \>(\[]); async function fetchsellerorders() { try { const orders = await parse cloud run("getsellerorders"); console log("seller orders ", orders); setordersdata(orders); } catch (err) { console error("error fetching seller orders ", err); } }; ce code récupère une liste de commandes qui incluent les produits du vendeur et les stocke dans l'état local ordersdata pour affichage dans un tableau de bord vendeur ou une vue de gestion des commandes assurez vous d'appeler la fonction dans un useeffect hook afin que la fonction s'exécute une fois au chargement de la page mettre à jour une commande cela bascule le statut d'une commande entre "en attente" et "complété" définissez cette fonction dans le page tsx fichier dans le app/seller/dashboard répertoire la fonction devrait ressembler à ceci const handleupdate = async (id string) => { const confirmupdate = confirm( "are you sure you want to update this order?" ); if (!confirmupdate) return; try { await parse cloud run("completeorder", { orderid id, }); console log("updated order"); } catch (error) { console error("error updating order ", error); } }; cette fonction, handleupdate , met à jour le statut d'une commande existante en appelant la fonction cloud nommée completeorder sur votre backend back4app liez cette fonction à un bouton "éditer" dans la partie jsx du composant comme ceci \<button variant="ghost" size="icon" onclick={() => {handleupdate(order id)}}> \<pencil classname="h 4 w 4" /> \<span classname="sr only">view\</span> \</button> déployer le frontend sur les conteneurs back4app les conteneurs back4app offrent un moyen simplifié de conditionner et de déployer votre application frontend au lieu de jongler avec des services d'hébergement séparés, vous pouvez stocker toutes les dépendances dans une image docker, garantissant des performances cohérentes et simplifiant la maintenance cette approche basée sur des conteneurs est particulièrement utile pour les applications next js, où vous pouvez optimiser les builds pour la vitesse et la fiabilité pour containeriser votre application, créez un dockerfile pour définir comment votre application est construite et servie voici un exemple de dockerfile pour une application next js \# stage 1 build the next js app from node 20 alpine as builder workdir /app copy package json package lock json / run npm install copy run npm run build \# stage 2 run the next js app from node 20 alpine workdir /app copy from=builder /app / expose 3000 cmd \["npm", "start"] après avoir créé votre dockerfile, créez un dockerignore et ajoutez ces commandes \# node modules (reinstalled in docker) node modules \# next js build output next out \# logs npm debug log yarn debug log yarn error log pnpm debug log \# env files (optional — only if you handle secrets another way) env env local env development env production env test \# os / ide / editor junk ds store thumbs db vscode idea \# git git gitignore maintenant, vous pouvez construire et tester votre application localement pour ce faire, exécutez la commande suivante dans votre terminal docker build t ecommerce app docker run p 3000 3000 ecommerce app ouvrez http //localhost 3000 pour vous assurer que votre site fonctionne correctement une fois que vous avez vérifié que tout fonctionne comme prévu localement, il est temps de pousser votre code sur github et de le déployer via back4app assurez vous que votre code est engagé et poussé vers un dépôt github cela permettra à back4app d'accéder à votre projet pour le déploiement dans votre compte back4app, allez sur votre tableau de bord et cliquez sur le tableau de bord menu déroulant en haut de l'écran menu du tableau de bord dans le menu déroulant, sélectionnez plateforme de déploiement web plateforme de deploiement web cela vous amènera à la page de déploiement de l'application web page de deploiement de lapplication web cliquez sur le déployer une application web bouton pour commencer le processus de déploiement lien repo github ensuite, cliquez sur importer le dépôt github et choisissez le dépôt qui contient votre dockerfile attribuez un nom à votre projet (par exemple, ecommerce back4app) suivez la configuration guidée pour construire et déployer votre application une fois le déploiement terminé, back4app affichera une page de confirmation comme celle ci déploiement réussi la zone surlignée dans l'image ci dessus est l'url où votre application est en ligne vous pouvez l'utiliser pour visualiser et tester votre application directement dans un navigateur web une fois déployé, utilisez le tableau de bord back4app pour surveiller les journaux de construction, suivre la santé des conteneurs et revenir à des versions précédentes si nécessaire le tableau de bord affiche des mises à jour en temps réel sur l'état des conteneurs, ce qui facilite la détection des erreurs et le maintien d'un environnement stable pour vos utilisateurs avec les conteneurs, vous bénéficiez d'une solution frontend flexible et portable qui s'associe parfaitement à votre backend back4app, ouvrant la voie à des versions cohérentes et sans tracas vous pouvez visiter le site e commerce construit dans ce tutoriel ici https //ecommerceback4app mcphit37 b4a run/ conclusion félicitations, vous avez maintenant assemblé chaque couche d'une pile e commerce prête pour la production et éprouvée configuration du back end de la provision de votre compte back4app à la modélisation des utilisateurs, des produits et des commandes sécurité & apis mise en œuvre d'une authentification robuste et exposition de vos données via des points de terminaison rest et graphql logique métier & mises à jour en temps réel automatisation des flux de travail avec cloud code et diffusion des changements en direct via livequery déploiement du front end intégration du sdk javascript et expédition d'une vitrine next js dans les conteneurs back4app quelle est la suite ? plongez dans la documentation de back4app https //www back4app com/docs et le guide de la plateforme parse https //docs parseplatform org pour des références approfondies, ou rejoignez le forum communautaire pour obtenir des conseils avancés et des applications d'exemple de la part des mainteneurs et d'autres développeurs cette fondation n'est que le début—étendez la davantage en intégrant des webhooks et des tâches planifiées, en connectant des passerelles de paiement, ou en construisant une application mobile compagnon continuez à itérer, refactoriser et faire évoluer votre code—et regardez votre vitrine grandir avec vos ambitions