From 68c744a631a758177ea2fc8eac0f5fd5fa60c6a9 Mon Sep 17 00:00:00 2001 From: hystepik Date: Fri, 10 Mar 2023 16:17:47 +0100 Subject: [PATCH 1/8] Fix: ipn for stripe --- htdocs/public/stripe/ipn.php | 253 +++++++++++++++++++---------------- 1 file changed, 137 insertions(+), 116 deletions(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index 5d0944e9738..d7322271649 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -315,157 +315,178 @@ if ($event->type == 'payout.created') { $db->commit(); } elseif ($event->type == 'payment_intent.succeeded') { // Called when making payment with PaymentIntent method ($conf->global->STRIPE_USE_NEW_CHECKOUT is on). dol_syslog("object = ".var_export($event->data, true)); - - /* TODO LMR We must retreive the invoice and payment amount from the id = ext_payment_id into llx_prelevement_demande - include_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php'; + include_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php'; //TOTEST + global $stripearrayofkeysbyenv; + $errors = 0; $object = $event->data->object; - $invoice_id = $object->metadata->dol_id; - $ipaddress = $object->metadata->ipaddress; - $invoice_amount = $object->amount / 100; $TRANSACTIONID = $object->id; - $customer_id = $object->customer; - $errorforinvoice = 0; - $paymentmethod = 'stripe'; + $ipaddress = $object->metadata->ipaddress; $now = dol_now(); $currencyCodeType = strtoupper($object->currency); $paymentmethodstripeid = $object->payment_method; + $customer_id = $object->customer; + $invoice_id = ""; + $paymentTypeId = ""; + $payment_amount = 0; + + $sql = "SELECT pi.fk_facture, pi.fk_prelevement_bons, pi.amount, pi.type"; + $sql .= " FROM llx_prelevement_demande as pi"; + $sql .= " WHERE pi.ext_payment_id = '".$db->escape($TRANSACTIONID)."'"; + $sql .= " AND pi.traite = '1'"; + $sql .= " AND pi.ext_payment_site = '".$db->escape($service)."'"; + + $result = $db->query($sql); + if ($result) { + $obj = $db->fetch_object($result); + if ($obj) { + $invoice_id = $obj->fk_facture; + $prelevement_bons_id = $obj->fk_prelevement_bons; + $payment_amount = $obj->amount; + $paymentTypeId = $obj->type; + } + } else { + $error = $this->db->lasterror(); + $postactionmessages[] = $error; + http_response_code(500); + return -1; + } - global $stripearrayofkeysbyenv; $stripeacc = $stripearrayofkeysbyenv[$servicestatus]['secret_key']; - dol_syslog("Try to create payment with data = ".json_encode($dataforcard)); + dol_syslog("Try to find a payment method with id = ".json_encode($paymentmethodstripeid)); $s = new \Stripe\StripeClient($stripeacc); $paymentmethodstripe = $s->paymentMethods->retrieve($paymentmethodstripeid); - $paymentTypeId = $paymentmethodstripe->type; - if ($paymentTypeId == "ban") { - $paymentTypeId = "PRE" - } elseif ($paymentTypeId == "sepa_debit") { // is this used ? how ? - $paymentTypeId = "BANCON"; + if ($paymentTypeId == "ban" || $paymentTypeId == "sepa_debit") { + $paymentTypeId = "PRE"; } elseif ($paymentTypeId == "card") { $paymentTypeId = "CB"; } - // TODO LMR Enable this only if this is a payment of a Dolibarr llx_prelevement_demande only - - $paiement = new Paiement($db); - $paiement->datepaye = $now; - $paiement->date = $now; - if ($currencyCodeType == $conf->currency) { - $paiement->amounts = [$invoice_id => $invoice_amount]; // Array with all payments dispatching with invoice id - } else { - $paiement->multicurrency_amounts = [$invoice_id => $invoice_amount]; // Array with all payments dispatching - - $postactionmessages[] = 'Payment was done in a different currency than currency expected of company'; - $ispostactionok = -1; - // Not yet supported, so error - $error++; - $errorforinvoice++; - } - $paiement->paiementid = $paymentTypeId; - $paiement->num_payment = ''; - $paiement->note_public = ''; - $paiement->note_private = 'StripeSepa payment ' . dol_print_date($now, 'standard') . ' using ' . $paymentmethod . ($ipaddress ? ' from ip ' . $ipaddress : '') . ' - Transaction ID = ' . $TRANSACTIONID; - // TODO LMR Fill the $paiement->ext_payment_id with an ID of payment intent (so 'pi_....'). Like this: - $paiement->ext_payment_id = $TRANSACTIONID.':'.$customer_id.'@'.$stripearrayofkeysbyenv[$servicestatus]['publishable_key']; // May be we should store py_... instead of pi_... but we started with pi_... so we continue. - $paiement->ext_payment_site = $service; // 'StripeLive' or 'Stripe' if test - - - $db->begin(); - - - if (!$errorforinvoice) { - dol_syslog('* Record payment for invoice id ' . $invoice_id . '. It includes closing of invoice and regenerating document'); - - // This include closing invoices to 'paid' (and trigger including unsuspending) and regenerating document - $paiement_id = $paiement->create($user, 1); - if ($paiement_id < 0) { - $postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("
\n", $paiement->errors); - $ispostactionok = -1; - $error++; - $errorforinvoice++; + if ($paymentTypeId == "PRE") { + $paiement = new Paiement($db); + $paiement->datepaye = $now; + $paiement->date = $now; + if ($currencyCodeType == $conf->currency) { + $paiement->amounts = [$invoice_id => $payment_amount]; // Array with all payments dispatching with invoice id } else { - $postactionmessages[] = 'Payment created'; + $paiement->multicurrency_amounts = [$invoice_id => $payment_amount]; // Array with all payments dispatching + + $postactionmessages[] = 'Payment was done in a different currency than currency expected of company'; + $ispostactionok = -1; + // Not yet supported, so error + $errors++; } + $paiement->paiementid = $paymentTypeId; + $paiement->num_payment = ''; + $paiement->note_public = ''; + $paiement->note_private = 'StripeSepa payment ' . dol_print_date($now, 'standard') . ' using ' . $servicestatus . ($ipaddress ? ' from ip ' . $ipaddress : '') . ' - Transaction ID = ' . $TRANSACTIONID; + $paiement->ext_payment_id = $TRANSACTIONID.':'.$customer_id.'@'.$stripearrayofkeysbyenv[$servicestatus]['publishable_key']; // May be we should store py_... instead of pi_... but we started with pi_... so we continue. + $paiement->ext_payment_site = $service; - dol_syslog("The payment has been created for invoice id " . $invoice_id); - } + $db->begin(); + if (!$errors) { + dol_syslog('* Record payment for invoice id ' . $invoice_id . '. It includes closing of invoice and regenerating document'); - if (!$errorforinvoice && isModEnabled('banque')) { - dol_syslog('* Add payment to bank'); - - // The bank used is the one defined into Stripe setup - $bankaccountid = 0; - if ($paymentmethod == 'stripe') { - $bankaccountid = $conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS; - } - - if ($bankaccountid > 0) { - $label = '(CustomerInvoicePayment)'; - $result = $paiement->addPaymentToBank($user, 'payment', $label, $bankaccountid, $customer_id, ''); - if ($result < 0) { + // This include closing invoices to 'paid' (and trigger including unsuspending) and regenerating document + $paiement_id = $paiement->create($user, 1); + if ($paiement_id < 0) { $postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("
\n", $paiement->errors); $ispostactionok = -1; - $error++; - $errorforinvoice++; + $errors++; } else { - $postactionmessages[] = 'Bank transaction of payment created (by makeStripeSepaRequest)'; + $postactionmessages[] = 'Payment created'; } - } else { - $postactionmessages[] = 'Setup of bank account to use in module ' . $paymentmethod . ' was not set. No way to record the payment.'; - $ispostactionok = -1; - $error++; - $errorforinvoice++; - } - } - if (!$errorforinvoice && isModEnabled('prelevement')) { - $bon = new BonPrelevement($db); - $idbon = 0; - $sql = "SELECT dp.fk_prelevement_bons as idbon"; - $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as dp"; - $sql .= " WHERE dp.fk_facture = '".$db->escape($invoice_id)."'"; - $sql .= " AND dp.sourcetype = 'facture'"; - $sql .= " AND dp.traite = 1"; - $result = $db->query($sql); - if ($result) { - if ($db->num_rows($result)) { - $obj = $db->fetch_object($result); - $idbon = $obj->idbon; + dol_syslog("The payment has been created for invoice id " . $invoice_id); + } + if (!$errors && isModEnabled('banque')) { + dol_syslog('* Add payment to bank'); + + // The bank used is the one defined into Stripe setup + $bankaccountid = getDolGlobalInt("STRIPE_BANK_ACCOUNT_FOR_PAYMENTS"); + + if ($bankaccountid > 0) { + $label = '(CustomerInvoicePayment)'; + $result = $paiement->addPaymentToBank($user, 'payment', $label, $bankaccountid, $customer_id, ''); + if ($result < 0) { + $postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("
\n", $paiement->errors); + $ispostactionok = -1; + $errors++; + } else { + $postactionmessages[] = 'Bank transaction of payment created (by makeStripeSepaRequest)'; + } + } else { + $postactionmessages[] = 'Setup of bank account to use in module ' . $paymentmethod . ' was not set. No way to record the payment.'; + $ispostactionok = -1; + $errors++; } - } else { - $postactionmessages[] = $db->lasterror(); - $ispostactionok = -1; - $error++; - $errorforinvoice++; } - if (!empty($idbon)) { - $bon->fetch($idbon); - $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons"; - $sql .= " SET fk_user_credit = ".$user->id; - $sql .= ", statut = '".$db->escape($bon::STATUS_CREDITED)."'"; - $sql .= ", date_credit = '".$db->idate($now)."'"; - $sql .= ", credite = 1"; - $sql .= " WHERE rowid=".((int) $bon->id); - $sql .= " AND statut = '".$db->escape($bon::STATUS_TRANSFERED)."'"; - - $db->begin(); + if (!$errors && isModEnabled('prelevement')) { + dol_syslog('* Set prelevement to credite'); + $bon = new BonPrelevement($db); + $idbon = 0; + $sql = "SELECT dp.fk_prelevement_bons as idbon"; + $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as dp"; + $sql .= " WHERE dp.fk_facture = '".$db->escape($invoice_id)."'"; + $sql .= " AND dp.sourcetype = 'facture'"; + $sql .= " AND dp.ext_payment_id = '".$db->escape($TRANSACTIONID)."'"; + $sql .= " AND dp.traite = 1"; $result = $db->query($sql); - if (!$result) { - $db->rollback(); + if ($result) { + if ($db->num_rows($result)) { + $obj = $db->fetch_object($result); + $idbon = $obj->idbon; + } + } else { $postactionmessages[] = $db->lasterror(); $ispostactionok = -1; - $error++; - $errorforinvoice++; - } else { - $db->commit(); + $errors++; + } + + if (!$errors && !empty($idbon)) { + $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons"; + $sql .= " SET fk_user_credit = ".$user->id; + $sql .= ", statut = '".$db->escape($bon::STATUS_CREDITED)."'"; + $sql .= ", date_credit = '".$db->idate($now)."'"; + $sql .= ", credite = 1"; + $sql .= " WHERE rowid = '".$db->escape($idbon)."'"; + $sql .= " AND statut = '".$db->escape($bon::STATUS_TRANSFERED)."'"; + + $result = $db->query($sql); + if (!$result) { + $postactionmessages[] = $db->lasterror(); + $ispostactionok = -1; + $errors++; + } + } + + if (!$errors && !empty($idbon)) { + $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_lignes"; + $sql .= " SET statut = 2"; + $sql .= " WHERE fk_prelevement_bons = '".$db->escape($idbon)."'"; + $result = $db->query($sql); + if (!$result) { + $postactionmessages[] = $db->lasterror(); + $ispostactionok = -1; + $errors++; + } } } + + if (!$errors) { + $db->commit(); + http_response_code(200); + return 1; + } else { + $db->rollback(); + http_response_code(500); + return -1; + } } - */ } elseif ($event->type == 'payment_intent.payment_failed') { // TODO: Redirect to paymentko.php } elseif ($event->type == 'checkout.session.completed') { // Called when making payment with new Checkout method ($conf->global->STRIPE_USE_NEW_CHECKOUT is on). From 89ea87dcaa941d22a082bc1e9febeba684d2f980 Mon Sep 17 00:00:00 2001 From: hystepik Date: Mon, 13 Mar 2023 11:45:17 +0100 Subject: [PATCH 2/8] fi CI --- htdocs/public/stripe/ipn.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index d7322271649..b1ac43b8af6 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -345,7 +345,7 @@ if ($event->type == 'payout.created') { $paymentTypeId = $obj->type; } } else { - $error = $this->db->lasterror(); + $error = $db->lasterror(); $postactionmessages[] = $error; http_response_code(500); return -1; From 9d460db1ef41afe4e821a75fb009b61cf790045c Mon Sep 17 00:00:00 2001 From: hystepik Date: Tue, 21 Mar 2023 11:12:43 +0100 Subject: [PATCH 3/8] change errors to error --- htdocs/public/stripe/ipn.php | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index b1ac43b8af6..dca67370cd2 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -317,7 +317,7 @@ if ($event->type == 'payout.created') { dol_syslog("object = ".var_export($event->data, true)); include_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php'; //TOTEST global $stripearrayofkeysbyenv; - $errors = 0; + $error = 0; $object = $event->data->object; $TRANSACTIONID = $object->id; $ipaddress = $object->metadata->ipaddress; @@ -345,8 +345,7 @@ if ($event->type == 'payout.created') { $paymentTypeId = $obj->type; } } else { - $error = $db->lasterror(); - $postactionmessages[] = $error; + $postactionmessages[] = $db->lasterror(); http_response_code(500); return -1; } @@ -377,7 +376,7 @@ if ($event->type == 'payout.created') { $postactionmessages[] = 'Payment was done in a different currency than currency expected of company'; $ispostactionok = -1; // Not yet supported, so error - $errors++; + $error++; } $paiement->paiementid = $paymentTypeId; $paiement->num_payment = ''; @@ -387,22 +386,22 @@ if ($event->type == 'payout.created') { $paiement->ext_payment_site = $service; $db->begin(); - if (!$errors) { + if (!$error) { dol_syslog('* Record payment for invoice id ' . $invoice_id . '. It includes closing of invoice and regenerating document'); // This include closing invoices to 'paid' (and trigger including unsuspending) and regenerating document $paiement_id = $paiement->create($user, 1); if ($paiement_id < 0) { - $postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("
\n", $paiement->errors); + $postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("
\n", $paiement->error); $ispostactionok = -1; - $errors++; + $error++; } else { $postactionmessages[] = 'Payment created'; } dol_syslog("The payment has been created for invoice id " . $invoice_id); } - if (!$errors && isModEnabled('banque')) { + if (!$error && isModEnabled('banque')) { dol_syslog('* Add payment to bank'); // The bank used is the one defined into Stripe setup @@ -414,18 +413,18 @@ if ($event->type == 'payout.created') { if ($result < 0) { $postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("
\n", $paiement->errors); $ispostactionok = -1; - $errors++; + $error++; } else { $postactionmessages[] = 'Bank transaction of payment created (by makeStripeSepaRequest)'; } } else { $postactionmessages[] = 'Setup of bank account to use in module ' . $paymentmethod . ' was not set. No way to record the payment.'; $ispostactionok = -1; - $errors++; + $error++; } } - if (!$errors && isModEnabled('prelevement')) { + if (!$error && isModEnabled('prelevement')) { dol_syslog('* Set prelevement to credite'); $bon = new BonPrelevement($db); $idbon = 0; @@ -444,10 +443,10 @@ if ($event->type == 'payout.created') { } else { $postactionmessages[] = $db->lasterror(); $ispostactionok = -1; - $errors++; + $error++; } - if (!$errors && !empty($idbon)) { + if (!$error && !empty($idbon)) { $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons"; $sql .= " SET fk_user_credit = ".$user->id; $sql .= ", statut = '".$db->escape($bon::STATUS_CREDITED)."'"; @@ -460,11 +459,11 @@ if ($event->type == 'payout.created') { if (!$result) { $postactionmessages[] = $db->lasterror(); $ispostactionok = -1; - $errors++; + $error++; } } - if (!$errors && !empty($idbon)) { + if (!$error && !empty($idbon)) { $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_lignes"; $sql .= " SET statut = 2"; $sql .= " WHERE fk_prelevement_bons = '".$db->escape($idbon)."'"; @@ -472,12 +471,12 @@ if ($event->type == 'payout.created') { if (!$result) { $postactionmessages[] = $db->lasterror(); $ispostactionok = -1; - $errors++; + $error++; } } } - if (!$errors) { + if (!$error) { $db->commit(); http_response_code(200); return 1; From b9a6a9771dc390e959490d71566f34d5d27fe3af Mon Sep 17 00:00:00 2001 From: hystepik Date: Tue, 21 Mar 2023 16:13:57 +0100 Subject: [PATCH 4/8] add protection on resend of action --- htdocs/public/stripe/ipn.php | 58 ++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index dca67370cd2..6cb44dba352 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -385,14 +385,25 @@ if ($event->type == 'payout.created') { $paiement->ext_payment_id = $TRANSACTIONID.':'.$customer_id.'@'.$stripearrayofkeysbyenv[$servicestatus]['publishable_key']; // May be we should store py_... instead of pi_... but we started with pi_... so we continue. $paiement->ext_payment_site = $service; + $ispaymentdone = 0; + $sql = "SELECT p.id FROM llx_paiement as p"; + $sql .= " WHERE p.ext_payment_id = '".$paiement->ext_payment_id."'"; + $sql .= " AND p.ext_payment_site = '".$paiement->ext_payment_site."'"; + $result = $db->query($sql); + if ($result) { + if ($db->num_rows($result)) { + $ispaymentdone = 1; + dol_syslog('* Payment for ext_payment_id '.$paiement->ext_payment_id.' already done. We do not recreate the payment'); + } + } $db->begin(); - if (!$error) { + if (!$error && !$ispaymentdone) { dol_syslog('* Record payment for invoice id ' . $invoice_id . '. It includes closing of invoice and regenerating document'); // This include closing invoices to 'paid' (and trigger including unsuspending) and regenerating document $paiement_id = $paiement->create($user, 1); if ($paiement_id < 0) { - $postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("
\n", $paiement->error); + $postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("
\n", $paiement->errors); $ispostactionok = -1; $error++; } else { @@ -402,25 +413,40 @@ if ($event->type == 'payout.created') { dol_syslog("The payment has been created for invoice id " . $invoice_id); } if (!$error && isModEnabled('banque')) { - dol_syslog('* Add payment to bank'); + $ispaymentdone = 0; + $sql = "SELECT p.id, p.fk_bank FROM llx_paiement as p"; + $sql .= " WHERE p.ext_payment_id = '".$paiement->ext_payment_id."'"; + $sql .= " AND p.ext_payment_site = '".$paiement->ext_payment_site."'"; + $sql .= " AND p.fk_bank <> '0'"; + $result = $db->query($sql); + if ($result) { + if ($db->num_rows($result)) { + $ispaymentdone = 1; + $obj = $db->fetch_object($result); + dol_syslog('* Payment already linked to bank record '.$obj->fk_bank.' . We do not recrate the link'); + } + } + if (!$ispaymentdone) { + dol_syslog('* Add payment to bank'); - // The bank used is the one defined into Stripe setup - $bankaccountid = getDolGlobalInt("STRIPE_BANK_ACCOUNT_FOR_PAYMENTS"); + // The bank used is the one defined into Stripe setup + $bankaccountid = getDolGlobalInt("STRIPE_BANK_ACCOUNT_FOR_PAYMENTS"); - if ($bankaccountid > 0) { - $label = '(CustomerInvoicePayment)'; - $result = $paiement->addPaymentToBank($user, 'payment', $label, $bankaccountid, $customer_id, ''); - if ($result < 0) { - $postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("
\n", $paiement->errors); + if ($bankaccountid > 0) { + $label = '(CustomerInvoicePayment)'; + $result = $paiement->addPaymentToBank($user, 'payment', $label, $bankaccountid, $customer_id, ''); + if ($result < 0) { + $postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("
\n", $paiement->errors); + $ispostactionok = -1; + $error++; + } else { + $postactionmessages[] = 'Bank transaction of payment created (by makeStripeSepaRequest)'; + } + } else { + $postactionmessages[] = 'Setup of bank account to use in module ' . $paymentmethod . ' was not set. No way to record the payment.'; $ispostactionok = -1; $error++; - } else { - $postactionmessages[] = 'Bank transaction of payment created (by makeStripeSepaRequest)'; } - } else { - $postactionmessages[] = 'Setup of bank account to use in module ' . $paymentmethod . ' was not set. No way to record the payment.'; - $ispostactionok = -1; - $error++; } } From 8c164db2f9a3b9f784654464fad934048dd34fd3 Mon Sep 17 00:00:00 2001 From: hystepik Date: Wed, 22 Mar 2023 10:31:55 +0100 Subject: [PATCH 5/8] fix CI --- htdocs/public/stripe/ipn.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index 6cb44dba352..3788bfd0585 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -387,8 +387,8 @@ if ($event->type == 'payout.created') { $ispaymentdone = 0; $sql = "SELECT p.id FROM llx_paiement as p"; - $sql .= " WHERE p.ext_payment_id = '".$paiement->ext_payment_id."'"; - $sql .= " AND p.ext_payment_site = '".$paiement->ext_payment_site."'"; + $sql .= " WHERE p.ext_payment_id = '".$db->escape($paiement->ext_payment_id)."'"; + $sql .= " AND p.ext_payment_site = '".$db->escape($paiement->ext_payment_site)."'"; $result = $db->query($sql); if ($result) { if ($db->num_rows($result)) { @@ -415,8 +415,8 @@ if ($event->type == 'payout.created') { if (!$error && isModEnabled('banque')) { $ispaymentdone = 0; $sql = "SELECT p.id, p.fk_bank FROM llx_paiement as p"; - $sql .= " WHERE p.ext_payment_id = '".$paiement->ext_payment_id."'"; - $sql .= " AND p.ext_payment_site = '".$paiement->ext_payment_site."'"; + $sql .= " WHERE p.ext_payment_id = '".$db->escape($paiement->ext_payment_id)."'"; + $sql .= " AND p.ext_payment_site = '".$db->escape($paiement->ext_payment_site)."'"; $sql .= " AND p.fk_bank <> '0'"; $result = $db->query($sql); if ($result) { From 76f221aee000a6fcce8d24f786119aba900b324d Mon Sep 17 00:00:00 2001 From: hystepik Date: Wed, 22 Mar 2023 14:11:59 +0100 Subject: [PATCH 6/8] fix postgre error --- htdocs/public/stripe/ipn.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index 3788bfd0585..fde9dca88fc 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -417,7 +417,7 @@ if ($event->type == 'payout.created') { $sql = "SELECT p.id, p.fk_bank FROM llx_paiement as p"; $sql .= " WHERE p.ext_payment_id = '".$db->escape($paiement->ext_payment_id)."'"; $sql .= " AND p.ext_payment_site = '".$db->escape($paiement->ext_payment_site)."'"; - $sql .= " AND p.fk_bank <> '0'"; + $sql .= " AND p.fk_bank <> 0"; $result = $db->query($sql); if ($result) { if ($db->num_rows($result)) { From 602050ffbceef32e0d4bec67b66b4a2db9f6dbe0 Mon Sep 17 00:00:00 2001 From: hystepik Date: Thu, 23 Mar 2023 10:38:53 +0100 Subject: [PATCH 7/8] add security on prelevement --- htdocs/public/stripe/ipn.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index fde9dca88fc..a7c8e463399 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -451,20 +451,25 @@ if ($event->type == 'payout.created') { } if (!$error && isModEnabled('prelevement')) { - dol_syslog('* Set prelevement to credite'); $bon = new BonPrelevement($db); $idbon = 0; $sql = "SELECT dp.fk_prelevement_bons as idbon"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as dp"; - $sql .= " WHERE dp.fk_facture = '".$db->escape($invoice_id)."'"; + $sql .= " JOIN ".MAIN_DB_PREFIX."prelevement_bons as pb"; // Here we join to prevent modification of a prelevement bon already credited + $sql .= " ON pb.rowid = dp.fk_prelevement_bons"; + $sql .= " WHERE dp.fk_facture = ".$db->escape($invoice_id); $sql .= " AND dp.sourcetype = 'facture'"; $sql .= " AND dp.ext_payment_id = '".$db->escape($TRANSACTIONID)."'"; $sql .= " AND dp.traite = 1"; + $sql .= " AND statut = ".$db->escape($bon::STATUS_TRANSFERED); // To be sure that it's not already credited $result = $db->query($sql); if ($result) { if ($db->num_rows($result)) { $obj = $db->fetch_object($result); $idbon = $obj->idbon; + dol_syslog('* Set prelevement to credite'); + } else { + dol_syslog('* Prelevement not found or already credited'); } } else { $postactionmessages[] = $db->lasterror(); From 8f96412ba2e6c0d9bb88fadbb0b8524404212821 Mon Sep 17 00:00:00 2001 From: hystepik Date: Thu, 23 Mar 2023 11:01:34 +0100 Subject: [PATCH 8/8] add cast for int sql --- htdocs/public/stripe/ipn.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index a7c8e463399..d405a30eb63 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -457,11 +457,11 @@ if ($event->type == 'payout.created') { $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as dp"; $sql .= " JOIN ".MAIN_DB_PREFIX."prelevement_bons as pb"; // Here we join to prevent modification of a prelevement bon already credited $sql .= " ON pb.rowid = dp.fk_prelevement_bons"; - $sql .= " WHERE dp.fk_facture = ".$db->escape($invoice_id); + $sql .= " WHERE dp.fk_facture = ".(int) $db->escape($invoice_id); $sql .= " AND dp.sourcetype = 'facture'"; $sql .= " AND dp.ext_payment_id = '".$db->escape($TRANSACTIONID)."'"; $sql .= " AND dp.traite = 1"; - $sql .= " AND statut = ".$db->escape($bon::STATUS_TRANSFERED); // To be sure that it's not already credited + $sql .= " AND statut = ".(int) $db->escape($bon::STATUS_TRANSFERED); // To be sure that it's not already credited $result = $db->query($sql); if ($result) { if ($db->num_rows($result)) { @@ -479,12 +479,12 @@ if ($event->type == 'payout.created') { if (!$error && !empty($idbon)) { $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons"; - $sql .= " SET fk_user_credit = ".$user->id; - $sql .= ", statut = '".$db->escape($bon::STATUS_CREDITED)."'"; + $sql .= " SET fk_user_credit = ".(int) $db->escape($user->id); + $sql .= ", statut = ".(int) $db->escape($bon::STATUS_CREDITED); $sql .= ", date_credit = '".$db->idate($now)."'"; $sql .= ", credite = 1"; - $sql .= " WHERE rowid = '".$db->escape($idbon)."'"; - $sql .= " AND statut = '".$db->escape($bon::STATUS_TRANSFERED)."'"; + $sql .= " WHERE rowid = ".(int) $db->escape($idbon); + $sql .= " AND statut = ".(int) $db->escape($bon::STATUS_TRANSFERED); $result = $db->query($sql); if (!$result) { @@ -497,7 +497,7 @@ if ($event->type == 'payout.created') { if (!$error && !empty($idbon)) { $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_lignes"; $sql .= " SET statut = 2"; - $sql .= " WHERE fk_prelevement_bons = '".$db->escape($idbon)."'"; + $sql .= " WHERE fk_prelevement_bons = ".(int) $db->escape($idbon); $result = $db->query($sql); if (!$result) { $postactionmessages[] = $db->lasterror();