Revue script API retour paiement WebPortage avec prise en compte des abonnements renouvelés après un délai.

This commit is contained in:
Fabrice PENHOËT 2020-08-28 12:18:22 +02:00
parent b8a652d1cd
commit 30c98c972e
4 changed files with 166 additions and 80 deletions

View File

@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

61
front/public/merci.html Normal file
View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex">
<title>WikiLerni : remerciement</title>
<!-- Version lisible des scripts : https://gitlab.com/lefablab/wikilerni/-/tree/master/front/src -->
<script src="/JS/polyfill.app.js" defer></script>
<script src="/JS/index.app.js" defer></script>
<link rel="shortcut icon" href="/img/favicon.ico">
<link rel="stylesheet" href="/themes/wikilerni/css/common.css" media="screen and (min-width: 970px)">
<link rel="stylesheet" href="/themes/wikilerni/css/common-mobile.css" media="screen and (max-width: 969px)">
<link rel="stylesheet" href="/themes/wikilerni/css/pages.css" media="screen and (min-width: 970px)">
<link rel="stylesheet" href="/themes/wikilerni/css/pages-mobile.css" media="screen and (max-width: 969px)">
<!-- <link rel="stylesheet" href="/themes/wikilerni/css/style.css"> -->
</head>
<body class="cardboard">
<!-- En tête -->
<header class="cardboard">
<a href="/" title="Page d'accueil WikLerni"><img src="/themes/wikilerni/img/wikilerni-purple-2-128.png" alt="WikiLerni (logo)" title="Accéder à la page d'accueil de WikiLerni" /></a>
<ul id="headLinks">
<li><a href="/contact.html" rel="nofollow">Contact</a></li>
<li><a href="/quizs/" id="indexHeadLink" title="Les derniers quizs">Parcourir</a></li>
<li><a href="/connexion.html" id="accountHeadLink">Mon compte</a></li>
<li><a href="/a-propos.html">À propos</a></li>
<li><a href="/" title="Page d'accueil de WikiLerni">Accueil</a></li>
</ul>
</header>
<div id="prompt" class="cardboard">
<a href="/" title="Page d'accueil WikLerni"><img src="/themes/wikilerni/img/wikilerni-purple-2-512.png" alt="Logo WikiLerni" title="W I K I L E R N I" /></a>
<p class="cardboard">Cultivons notre jardin !</p>
</div>
<div id="page" class="cardboard">
<div class="framed">
<h2>Merci !</h2>
<p>Votre paiement vient d'être enregistré. Merci à vous !</p>
<p>Normalement, vous avez reçu une facture par e-mail et votre abonnement vient d'être prolongé.</p>
<p>Si jamais ce n'est pas le cas et que vous avez une quelconque question, n'hésitez pas <a href="/contact.html">à me prévenir</a>.</p>
<p class="engraved">
<figure>
<img alt="Tirelire" src="/img/tirelire.jpg">
<figCaption>User Cornischong on lb.wikipedia / CC BY-SA</figCaption>
</figure>
</p>
</div>
</div>
<footer class="cardboard">
<ul id="footLinks">
<li><a href="https://framasphere.org/people/7e54b7a0b53201389eef2a0000053625" title="Blog WikiLerni sur diaspora*">Blog</a></li>
<li><a href="/credits.html">Crédits</a></li>
<li><a href="/mentions-legales.html" rel="nofollow">Mentions légales</a></li>
<li><a href="/donnees.html">Données personnelles</a></li>
<li><a href="/CGV-CGU.html" rel="nofollow">CGV &amp; CGU</a></li>
</ul>
</footer>
</body>
</html>

View File

@ -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: "<h3>Bonjour USER_NAME,</h3><p>Suite à votre paiement, votre abonnement à SITE_NAME vient d'être prolongé de NBDAYS jours.<br>Merci beaucoup et à bientôt !</p>",
mailPaymentThankBodyHTML: "<h3>Bonjour USER_NAME,</h3><p>Suite à votre paiement, votre abonnement à SITE_NAME vient d'être prolongé de NBDAYS jours.<br><br>Merci beaucoup et à bientôt sur SITE_NAME !</p>",
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: "<h3>Bonjour,</h3><p>Un nouvel abonnement payant vient d'être enregistré pour l'utilisateur EMAIL.</p>",
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 !",