diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php
index 067c371bf67..4a3d08f6602 100644
--- a/htdocs/public/payment/newpayment.php
+++ b/htdocs/public/payment/newpayment.php
@@ -1725,6 +1725,7 @@ if ($action != 'dopayment')
{
// If STRIPE_PICTO_FOR_PAYMENT is 'cb' we show a picto of a crdit card instead of stripe
print '
';
@@ -1858,12 +1859,12 @@ if (preg_match('/^dopayment/', $action)) // If we choosed/click on the payment
$service = 'StripeLive';
$servicestatus = 1;
-
if (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha'))
{
$service = 'StripeTest';
$servicestatus = 0;
}
+
$stripe = new Stripe($db);
$stripeacc = $stripe->getStripeAccount($service);
$stripecu = null;
@@ -1871,7 +1872,10 @@ if (preg_match('/^dopayment/', $action)) // If we choosed/click on the payment
if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION))
{
- $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, 'Stripe payment: '.$fulltag.(is_object($object)?' ref='.$object->ref:''), $object, $stripecu, $stripeacc, $servicestatus);
+ $noidempotency_key = (GETPOSTISSET('noidempotency') ? GETPOST('noidempotency', 'int') : 0); // By default noidempotency is unset, so we must use a different tag/ref for each payment. If set, we can pay several times the same tag/ref.
+ $paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, 'Stripe payment: '.$fulltag.(is_object($object)?' ref='.$object->ref:''), $object, $stripecu, $stripeacc, $servicestatus, 0, 'automatic', false, null, 0, $noidempotency_key);
+ // The paymentintnent has status 'requires_payment_method' (even if paymentintent was already payed)
+ //var_dump($paymentintent);
if ($stripe->error) setEventMessages($stripe->error, null, 'errors');
}
}
diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php
index 021a9fac1f9..c30e3169ee5 100644
--- a/htdocs/stripe/class/stripe.class.php
+++ b/htdocs/stripe/class/stripe.class.php
@@ -318,9 +318,10 @@ class Stripe extends CommonObject
* @param boolean $confirmnow false=default, true=try to confirm immediatly after create (if conditions are ok)
* @param string $payment_method 'pm_....' (if known)
* @param string $off_session If we use an already known payment method to pay off line.
+ * @param string $noidempotency_key Do not use the idempotency_key when creating the PaymentIntent
* @return \Stripe\PaymentIntent|null Stripe PaymentIntent or null if not found and failed to create
*/
- public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false, $payment_method = null, $off_session = 0)
+ public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false, $payment_method = null, $off_session = 0, $noidempotency_key = 0)
{
global $conf;
@@ -352,9 +353,10 @@ class Stripe extends CommonObject
if (is_object($object))
{
// Warning. If a payment was tried and failed, a payment intent was created.
- // But if we change someting on object to pay (amount or other), reusing same payment intent is not allowed.
- // Recommanded solution is to recreate a new payment intent each time we need one (old one will be automatically closed after a delay),
- // that's why i comment the part of code to retreive a payment intent with object id (never mind if we cumulate payment intent with old that will not be used)
+ // But if we change someting on object to pay (amount or other that does not change the idempotency key), reusing same payment intent is not allowed.
+ // Recommanded solution is to recreate a new payment intent each time we need one (old one will be automatically closed after a delay), Stripe will
+ // automatically return the existing payment intent if idempotency is provided when we try to create the new one.
+ // That's why we can comment the part of code to retreive a payment intent with object id (never mind if we cumulate payment intent with old ones that will not be used)
/*
$sql = "SELECT pi.ext_payment_id, pi.entity, pi.fk_facture, pi.sourcetype, pi.ext_payment_site";
$sql.= " FROM " . MAIN_DB_PREFIX . "prelevement_facture_demande as pi";
@@ -445,14 +447,15 @@ class Stripe extends CommonObject
global $stripearrayofkeysbyenv;
\Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
- // Note: If all data for payment intent are same than a previous on, even if we use 'create', Stripe will return ID of the old existing payment intent.
- if (empty($key)) { // If the Stripe connect account not set, we use common API usage
- $paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description"));
- //$paymentintent = \Stripe\PaymentIntent::create($dataforintent, array());
- } else {
- $paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description", "stripe_account" => $key));
- //$paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("stripe_account" => $key));
+ $arrayofoptions = array();
+ if (empty($noidempotency_key)) {
+ $arrayofoptions["idempotency_key"] = $description;
}
+ // Note: If all data for payment intent are same than a previous on, even if we use 'create', Stripe will return ID of the old existing payment intent.
+ if (! empty($key)) { // If the Stripe connect account not set, we use common API usage
+ $arrayofoptions["stripe_account"] = $key;
+ }
+ $paymentintent = \Stripe\PaymentIntent::create($dataforintent, $arrayofoptions);
// Store the payment intent
if (is_object($object))
diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php
index 0030bdb5535..1070f605eb8 100644
--- a/htdocs/stripe/config.php
+++ b/htdocs/stripe/config.php
@@ -28,7 +28,7 @@
require_once DOL_DOCUMENT_ROOT.'/includes/stripe/init.php';
require_once DOL_DOCUMENT_ROOT.'/includes/stripe/lib/Stripe.php';
-global $stripe;
+//global $stripe;
global $conf;
global $stripearrayofkeysbyenv;