From 30c98c972e59e1ffa6a3472d16247d236394cebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabrice=20PENHO=C3=8BT?= Date: Fri, 28 Aug 2020 12:18:22 +0200 Subject: [PATCH] =?UTF-8?q?Revue=20script=20API=20retour=20paiement=20WebP?= =?UTF-8?q?ortage=20avec=20prise=20en=20compte=20des=20abonnements=20renou?= =?UTF-8?q?vel=C3=A9s=20apr=C3=A8s=20un=20d=C3=A9lai.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controllers/payment.js | 181 +++++++++++++++++++--------------- front/public/img/tirelire.jpg | Bin 0 -> 21557 bytes front/public/merci.html | 61 ++++++++++++ lang/fr/payment.js | 4 +- 4 files changed, 166 insertions(+), 80 deletions(-) create mode 100644 front/public/img/tirelire.jpg create mode 100644 front/public/merci.html diff --git a/controllers/payment.js b/controllers/payment.js index 728935b..c92a883 100644 --- a/controllers/payment.js +++ b/controllers/payment.js @@ -33,100 +33,125 @@ exports.getOneUserPayments = async (req, res, next) => exports.saveUserPaymentInfos = async (req, res, next) => { - // exemple d'url : WP-infos.html?dom=NOM_DE_DOMAINE_DU_BOUTON&ref=ID_DU_USER&mt=MONTANT_TTC&cmd=CODE_COMMANDE_WEBPORTAGE&cl=NOM+DU+CLIENT&hKey=le_hash_en_md5 - // dom=wikilerni.com&ref=5&mt=24&cmd=de11de&cl=monsieur+dugenoux&hKey=998dccdef52bd27dc0a674941c0e9340 + // exemple d'url Ok : WP-infos.html?dom=wikilerni.com&ref=21&mt=24&cmd=de11de&cl=monsieur+dugenoux&hKey=1b42653d28ecd07b9b3ba202770a1a45 try { - require('dotenv').config(); - const db = require("../models/index"); - const md5 = require("md5"); - const montantsAbonnement=["12","24", "60", "120"]; - // !! attention req.query enlève les caractères spéciaux comme les "+" des paramètres de l'url. Il vaut donc mieux utiliser req.url pour comparer avec le hash au reste de la chaîne. - const testUrl=req.url.slice(req.url.indexOf("?")+1,req.url.lastIndexOf("&")); - console.log(testUrl); - console.log(md5(testUrl+process.env.MD5_WP)); - if(md5(testUrl+process.env.MD5_WP)!==req.query.hKey) // le hashage est effectué après le remplacement des caractères spéciaux dans l'url. - throw { message: txt.paymentUrlFail+testUrl }; - else if(req.query.ref==="" || montantsAbonnement.indexOf(req.query.mt) === -1) - throw { message: txt.paymentDatasFail+testUrl }; - else + // l'utilisateur étant incité à venir sur l'API, on le redirige vers le site + // ex url retour : /payment/WP-infos.html?article=nomArticle&ht=montantHT&client=nomClient + if(req.query.article!=undefined) { - const client=await userCtrl.searchUserById(req.query.ref); - if(!client) - throw { message: txt.paymentUserNotFound+testUrl }; + res.writeHead(302, { "Location": config.siteUrl+"/merci.html" }); + res.end(); + } + else + { + require('dotenv').config(); + const ndDaysSubscription=365;// nombre de jour de l'abonnement + const ndDaysGodFather=30;// nombre de jour en plus si parrainage + const db = require("../models/index"); + const md5 = require("md5"); + const montantsAbonnement=["12","24","60","120"]; + // !! attention req.query enlève les caractères spéciaux comme les "+" des paramètres de l'url. Il vaut donc mieux utiliser req.url pour comparer avec le hash au reste de la chaîne. + const testUrl=req.url.slice(req.url.indexOf("?")+1,req.url.lastIndexOf("&")); + console.log(testUrl); + console.log(md5(testUrl+process.env.MD5_WP)); + if(md5(testUrl+process.env.MD5_WP)!==req.query.hKey) // le hashage est effectué après le remplacement des caractères spéciaux dans l'url. + throw { message: txt.paymentUrlFail+testUrl }; + else if(req.query.ref==="" || montantsAbonnement.indexOf(req.query.mt) === -1) + throw { message: txt.paymentDatasFail+testUrl }; else { - // Si cet utilisateur a un parrain on le remercie et lui ajoute 30 jours d'abonnement - // Cela impacte aussi la durée de l'abonnement commandé par l'utilisateur - let numberOfDays=365; - if(client.User.GodfatherId) + const client=await userCtrl.searchUserById(req.query.ref); + if(!client) + throw { message: txt.paymentUserNotFound+testUrl }; + else { - const parrain=await userCtrl.searchUserById(client.User.GodfatherId); - if(parrain) + // Si cet utilisateur a un parrain on le remercie et lui ajoute 30 jours d'abonnement + // Cela impacte aussi la durée à ajouter à l'abonnement du client + let numberOfDays=ndDaysSubscription; + if(client.User.GodfatherId) { - parrain.Subscription.numberOfDays+=30; - numberOfDays+=30; - await db["Subscription"].update({ ...parrain.Subscription }, { where: { UserId : client.User.GodfatherId }, fields: ["numberOfDays"], limit:1 }); - userCtrl.creaUserJson(client.User.GodfatherId); - const mapMail = + const parrain=await userCtrl.searchUserById(client.User.GodfatherId); + if(parrain) { - USER_NAME: parrain.User.name - }; - const mailDatas= - { - mailSubject: txt.mailPaymentThankGodfatherSubject, - mailPreheader: txt.mailPaymentThankGodfatherSubject, - mailTitle: txt.mailPaymentThankGodfatherSubject, - mailHeaderLinkUrl: config.siteUrl+"/"+configTpl.userHomePage, - mailHeaderLinkTxt: txt.mailPaymentLinkTxt, - mailMainContent: tool.replaceAll(txt.mailPaymentThankGodfatherBodyHTML, mapMail), - linksCTA: [{ url:config.siteUrl+"/"+configTpl.userHomePage, txt:txt.mailPaymentLinkTxt }], - mailRecipientAddress: parrain.User.email + addDays(parrain, ndDaysGodFather); + numberOfDays+=ndDaysGodFather; + await db["Subscription"].update({ ...parrain.Subscription }, { where: { UserId : client.User.GodfatherId }, fields: ["numberOfDays"], limit:1 }); + userCtrl.creaUserJson(client.User.GodfatherId); + const mapMail = + { + USER_NAME: parrain.User.name + }; + const mailDatas= + { + mailSubject: txt.mailPaymentThankGodfatherSubject, + mailPreheader: txt.mailPaymentThankGodfatherSubject, + mailTitle: txt.mailPaymentThankGodfatherSubject, + mailHeaderLinkUrl: config.siteUrl+"/"+configTpl.userHomePage, + mailHeaderLinkTxt: txt.mailPaymentLinkTxt, + mailMainContent: tool.replaceAll(txt.mailPaymentThankGodfatherBodyHTML, mapMail), + linksCTA: [{ url:config.siteUrl+"/"+configTpl.userHomePage, txt:txt.mailPaymentLinkTxt }], + mailRecipientAddress: parrain.User.email + } + await toolMail.sendMail(parrain.User.smtp, parrain.User.email, txt.mailPaymentThankGodfatherSubject, tool.replaceAll(txt.mailPaymentThankGodfatherBodyTxt, mapMail), "", mailDatas); } - await toolMail.sendMail(parrain.User.smtp, parrain.User.email, txt.mailPaymentThankGodfatherSubject, tool.replaceAll(txt.mailPaymentThankGodfatherBodyTxt, mapMail), "", mailDatas); + else + res.alerte=txt.paymentGodfatherNotFound+client.User.GodfatherId; } - else - res.alerte=txt.paymentGodfatherNotFound+client.User.GodfatherId; - } - const infosClient= - { - clientName: req.query.cl, - amount: req.query.mt, - codeCommande: req.query.cmd, - UserId: client.User.id, - numberOfDays: client.Subscription.numberOfDays+numberOfDays - }; - await db["Payment"].create({ ...infosClient }, { fields: ["clientName", "amount", "codeCommande", "UserId"] }); - await db["Subscription"].update({ ...infosClient }, { where: { UserId : infosClient.UserId }, fields: ["numberOfDays"], limit:1 }); - userCtrl.creaUserJson(infosClient.UserId); - // mail remerciement abonné - const mapMail2 = - { - SITE_NAME: config.siteName, - USER_NAME: client.User.name, - NBDAYS: numberOfDays - }; - const mailDatas2 = - { - mailSubject: txt.mailPaymentThankSubject, - mailPreheader: txt.mailPaymentThankSubject, - mailTitle: txt.mailPaymentThankSubject, - mailHeaderLinkUrl: config.siteUrl+"/"+configTpl.userHomePage, - mailHeaderLinkTxt: txt.mailPaymentLinkTxt, - mailMainContent: tool.replaceAll(txt.mailPaymentThankBodyHTML, mapMail2), - linksCTA: [{ url:config.siteUrl+"/"+configTpl.userHomePage, txt:txt.mailPaymentLinkTxt }], - mailRecipientAddress: client.User.email + addDays(client, numberOfDays); + const infosClient= + { + clientName: req.query.cl, + amount: req.query.mt, + codeCommande: req.query.cmd, + UserId: client.User.id, + numberOfDays: client.Subscription.numberOfDays + }; + await db["Payment"].create({ ...infosClient }, { fields: ["clientName", "amount", "codeCommande", "UserId"] }); + await db["Subscription"].update({ ...infosClient }, { where: { UserId : infosClient.UserId }, fields: ["numberOfDays"], limit:1 }); + userCtrl.creaUserJson(infosClient.UserId); + const mapMail2 = + { + SITE_NAME: config.siteName, + USER_NAME: client.User.name, + NBDAYS: numberOfDays + }; + const mailDatas2 = + { + mailSubject: txt.mailPaymentThankSubject, + mailPreheader: txt.mailPaymentThankSubject, + mailTitle: txt.mailPaymentThankSubject, + mailHeaderLinkUrl: config.siteUrl+"/"+configTpl.userHomePage, + mailHeaderLinkTxt: txt.mailPaymentLinkTxt, + mailMainContent: tool.replaceAll(txt.mailPaymentThankBodyHTML, mapMail2), + linksCTA: [{ url:config.siteUrl+"/"+configTpl.userHomePage, txt:txt.mailPaymentLinkTxt }], + mailRecipientAddress: client.User.email + } + await toolMail.sendMail(client.User.smtp, client.User.email, txt.mailPaymentThankSubject, tool.replaceAll(txt.mailPaymentThankBodyTxt, mapMail2), "", mailDatas2); + // + info admin site + await toolMail.sendMail(0, config.adminEmail, txt.mailPaymentAdminNoticeSubject, txt.mailPaymentAdminNoticeBodyTxt.replace("EMAIL", client.User.email), txt.mailPaymentAdminNoticeBodyHTML.replace("EMAIL", client.User.email)); + res.status(200).json(true); } - await toolMail.sendMail(client.User.smtp, client.User.email, txt.mailPaymentThankSubject, tool.replaceAll(txt.mailPaymentThankBodyTxt, mapMail2), "", mailDatas2); - // + info admin site - await toolMail.sendMail(0, config.adminEmail, txt.mailPaymentAdminNoticeSubject, txt.mailPaymentAdminNoticeBodyTxt.replace("EMAIL", client.User.email), txt.mailPaymentAdminNoticeBodyHTML.replace("EMAIL", client.User.email)); - res.status(200).json(true); } + next(); } - next(); } catch(e) { next(e); } +} + +// Ajoute le nombre de jours nécessaire à un abonnement en vérifiant si il est expiré ou non. +// Si l'abonnement est toujours actif, on se contente d'ajouter le nombre de jours souhaité à celui déjà connu +// Sinon, on complète pour arriver à la date actuelle, puis on ajoute le nombre de jours souhaité +const addDays = (user, nbDays) => +{ + let dateEnd=new Date(user.Subscription.createdAt).getTime()+user.Subscription.numberOfDays*24*3600*1000; + if(dateEnd < Date.now()) + { + let needDays=Math.round((Date.now()-dateEnd)/(24*3600*1000)); + nbDays+=needDays; + } + user.Subscription.numberOfDays+=nbDays; } \ No newline at end of file diff --git a/front/public/img/tirelire.jpg b/front/public/img/tirelire.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0cb17e6586ec13ee92b65b127877df3d03785cc0 GIT binary patch literal 21557 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 P0#gw$>Y__gAV2@vmkXlM literal 0 HcmV?d00001 diff --git a/front/public/merci.html b/front/public/merci.html new file mode 100644 index 0000000..52672fc --- /dev/null +++ b/front/public/merci.html @@ -0,0 +1,61 @@ + + + + + + + WikiLerni : remerciement + + + + + + + + + + + + + +
+ WikiLerni (logo) + +
+ +
+ Logo WikiLerni +

Cultivons notre jardin !

+
+ +
+
+

Merci !

+

Votre paiement vient d'être enregistré. Merci à vous !

+

Normalement, vous avez reçu une facture par e-mail et votre abonnement vient d'être prolongé.

+

Si jamais ce n'est pas le cas et que vous avez une quelconque question, n'hésitez pas à me prévenir.

+

+

+ Tirelire +
User Cornischong on lb.wikipedia / CC BY-SA
+
+

+
+
+ + + \ No newline at end of file diff --git a/lang/fr/payment.js b/lang/fr/payment.js index 25992ad..56fe275 100644 --- a/lang/fr/payment.js +++ b/lang/fr/payment.js @@ -10,9 +10,9 @@ module.exports = mailPaymentThankSubject: "Merci !", mailPaymentLinkTxt: "Mon compte WikiLerni.", mailPaymentThankBodyTxt: "Bonjour USER_NAME,\n\nSuite à votre paiement, votre abonnement à SITE_NAME vient d'être prolongé de NBDAYS jours.\n\nMerci beaucoup et à bientôt !", - mailPaymentThankBodyHTML: "

Bonjour USER_NAME,

Suite à votre paiement, votre abonnement à SITE_NAME vient d'être prolongé de NBDAYS jours.
Merci beaucoup et à bientôt !

", + mailPaymentThankBodyHTML: "

Bonjour USER_NAME,

Suite à votre paiement, votre abonnement à SITE_NAME vient d'être prolongé de NBDAYS jours.

Merci beaucoup et à bientôt sur SITE_NAME !

", mailPaymentAdminNoticeSubject: "Nouvel abonnement prémium !", - mailPaymentAdminNoticeBodyTxt: "Bonjour,\nUn nouvel abonnement prémium vient d'être enregistré pour l'utilisateur EMAIL.", + mailPaymentAdminNoticeBodyTxt: "Bonjour,\nUn nouvel abonnement prémium vient d'être enregistré par l'utilisateur EMAIL.", mailPaymentAdminNoticeBodyHTML: "

Bonjour,

Un nouvel abonnement payant vient d'être enregistré pour l'utilisateur EMAIL.

", mailPaymentThankGodfatherSubject: "Merci !", mailPaymentThankGodfatherBodyTxt: "Bonjour USER_NAME,\n\nUn des utilisateurs que vous avez parrainé vient de souscrire à un abonnement payant.\n\nEn récompense, votre abonnement vient donc d'être prolongé de 30 jours.\n\nMerci à vous et à bientôt !",