FIX Check on Stripe REAL amount currency before validating membership

This commit is contained in:
Laurent Destailleur 2021-11-27 19:04:39 +01:00
parent 309f7da7ba
commit 27ae8f61bd
2 changed files with 27 additions and 26 deletions

View File

@ -768,9 +768,23 @@ if ($action == 'charge' && !empty($conf->stripe->enabled)) {
setEventMessages($paymentintent->status, null, 'errors');
$action = '';
} else {
// TODO We can alse record the payment mode into llx_societe_rib with stripe $paymentintent->payment_method
// TODO We can also record the payment mode into llx_societe_rib with stripe $paymentintent->payment_method
// Note that with other old Stripe architecture (using Charge API), the payment mode was not recorded, so it is not mandatory to do it here.
//dol_syslog("Create payment_method for ".$paymentintent->payment_method, LOG_DEBUG, 0, '_stripe');
// Get here amount and currency used for payment and force value into $amount and $currency so the real amount is saved into session instead
// of the amount and currency retreived from the POST.
if (!empty($paymentintent->currency) && !empty($paymentintent->amount)) {
$currency = strtoupper($paymentintent->currency);
$amount = $paymentintent->amount;
// Correct the amount according to unit of currency
// See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
$arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
if (!in_array($currency, $arrayzerounitcurrency)) {
$amount = $amount / 100;
}
}
}
}

View File

@ -343,6 +343,9 @@ if (empty($FinalPaymentAmt)) {
if (empty($paymentType)) {
$paymentType = $_SESSION["paymentType"];
}
if (empty($currencyCodeType)) {
$currencyCodeType = $_SESSION['currencyCodeType'];
}
$fulltag = $FULLTAG;
$tmptag = dolExplodeIntoArray($fulltag, '.', '=');
@ -403,15 +406,12 @@ if ($ispaymentok) {
$paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS;
}
if (empty($paymentTypeId)) {
$paymentType = $_SESSION["paymentType"];
if (empty($paymentType)) {
$paymentType = 'CB';
}
$paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1);
}
$currencyCodeType = $_SESSION['currencyCodeType'];
dol_syslog("FinalPaymentAmt=".$FinalPaymentAmt." paymentTypeId=".$paymentTypeId." currencyCodeType=".$currencyCodeType, LOG_DEBUG, 0, '_payment');
// Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time)
@ -435,13 +435,19 @@ if ($ispaymentok) {
$errmsg = 'Value of FinalPayment ('.$FinalPaymentAmt.') differs from value expected for membership ('.$amountexpected.'). May be a hack to try to pay a different amount ?';
$postactionmessages[] = $errmsg;
$ispostactionok = -1;
dol_syslog("Failed to validate member: ".$errmsg, LOG_ERR, 0, '_payment');
dol_syslog("Failed to validate member (bad amount check): ".$errmsg, LOG_ERR, 0, '_payment');
}
}
}
// Security protection:
// TODO check that currency is same ?
if ($currencyCodeType && $currencyCodeType != $conf->currency) { // Check that currency is the good one
$error++;
$errmsg = 'Value of currencyCodeType ('.$currencyCodeType.') differs from value expected for membership ('.$conf->currency.'). May be a hack to try to pay a different amount ?';
$postactionmessages[] = $errmsg;
$ispostactionok = -1;
dol_syslog("Failed to validate member (bad currency check): ".$errmsg, LOG_ERR, 0, '_payment');
}
if (! $error) {
// We validate the member (no effect if it is already validated)
@ -766,15 +772,12 @@ if ($ispaymentok) {
$paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS;
}
if (empty($paymentTypeId)) {
$paymentType = $_SESSION["paymentType"];
if (empty($paymentType)) {
$paymentType = 'CB';
}
$paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1);
}
$currencyCodeType = $_SESSION['currencyCodeType'];
// Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time)
if (!empty($FinalPaymentAmt) && $paymentTypeId > 0) {
$db->begin();
@ -866,13 +869,10 @@ if ($ispaymentok) {
if ($paymentmethod == 'paypal') $paymentTypeId = $conf->global->PAYPAL_PAYMENT_MODE_FOR_PAYMENTS;
if ($paymentmethod == 'stripe') $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS;
if (empty($paymentTypeId)) {
$paymentType = $_SESSION["paymentType"];
if (empty($paymentType)) $paymentType = 'CB';
$paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1);
}
$currencyCodeType = $_SESSION['currencyCodeType'];
// Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time)
if (!empty($conf->facture->enabled)) {
if (!empty($FinalPaymentAmt) && $paymentTypeId > 0 ) {
@ -964,8 +964,6 @@ if ($ispaymentok) {
$don = new Don($db);
$result = $don->fetch((int) $tmptag['DON']);
if ($result) {
$FinalPaymentAmt = $_SESSION["FinalPaymentAmt"];
$paymentTypeId = 0;
if ($paymentmethod == 'paybox') {
$paymentTypeId = $conf->global->PAYBOX_PAYMENT_MODE_FOR_PAYMENTS;
@ -977,15 +975,12 @@ if ($ispaymentok) {
$paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS;
}
if (empty($paymentTypeId)) {
$paymentType = $_SESSION["paymentType"];
if (empty($paymentType)) {
$paymentType = 'CB';
}
$paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1);
}
$currencyCodeType = $_SESSION['currencyCodeType'];
// Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time)
if (!empty($FinalPaymentAmt) && $paymentTypeId > 0) {
$db->begin();
@ -1074,8 +1069,6 @@ if ($ispaymentok) {
$object = new Facture($db);
$result = $object->fetch($ref);
if ($result) {
$FinalPaymentAmt = $_SESSION["FinalPaymentAmt"];
$paymentTypeId = 0;
if ($paymentmethod == 'paybox') {
$paymentTypeId = $conf->global->PAYBOX_PAYMENT_MODE_FOR_PAYMENTS;
@ -1087,15 +1080,12 @@ if ($ispaymentok) {
$paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS;
}
if (empty($paymentTypeId)) {
$paymentType = $_SESSION["paymentType"];
if (empty($paymentType)) {
$paymentType = 'CB';
}
$paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1);
}
$currencyCodeType = $_SESSION['currencyCodeType'];
// Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time)
if (!empty($FinalPaymentAmt) && $paymentTypeId > 0) {
$resultvalidate = $object->validate($user);
@ -1271,15 +1261,12 @@ if ($ispaymentok) {
$paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS;
}
if (empty($paymentTypeId)) {
$paymentType = $_SESSION["paymentType"];
if (empty($paymentType)) {
$paymentType = 'CB';
}
$paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1);
}
$currencyCodeType = $_SESSION['currencyCodeType'];
// Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time)
if (!empty($FinalPaymentAmt) && $paymentTypeId > 0) {
$resultvalidate = $object->validate($user);
@ -1687,7 +1674,7 @@ if ($ispaymentok) {
print "\n</div>\n";
print "<!-- Info for payment: FinalPaymentAmt=".dol_escape_htmltag($FinalPaymentAmt)." paymentTypeId=".dol_escape_htmltag($paymentTypeId)." currencyCodeType=".dol_escape_htmltag($currencyCodeType)." -->\n";
print "<!-- Info for payment: FinalPaymentAmt=".dol_escape_htmltag($FinalPaymentAmt)." paymentTypeId=".dol_escape_htmltag($paymentTypeId)." currencyCodeType=".dol_escape_htmltag($currencyCodeType)." -->\n";
htmlPrintOnlinePaymentFooter($mysoc, $langs, 0, $suffix);