Work on stripe payment using intent with option

STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION
This commit is contained in:
Laurent Destailleur 2019-05-02 21:54:28 +02:00
parent 8442c86436
commit 10d853cdb3
3 changed files with 375 additions and 128 deletions

View File

@ -1,7 +1,7 @@
# Dolibarr language file - Source file is en_US - paypal
PaypalSetup=PayPal module setup
PaypalDesc=This module allows payment by customers via <a href="http://www.paypal.com" target="_blank">PayPal</a>. This can be used for a ad-hoc payment or for a payment related to a Dolibarr object (invoice, order, ...)
PaypalOrCBDoPayment=Pay with PayPal (Credit Card or PayPal)
PaypalOrCBDoPayment=Pay with PayPal (Card or PayPal)
PaypalDoPayment=Pay with PayPal
PAYPAL_API_SANDBOX=Mode test/sandbox
PAYPAL_API_USER=API username
@ -33,3 +33,4 @@ PaypalImportPayment=Import PayPal payments
PostActionAfterPayment=Post actions after payments
ARollbackWasPerformedOnPostActions=A rollback was performed on all Post actions. You must complete post actions manually if they are necessary.
ValidationOfPaymentFailed=Validation of payment has failed
CardOwner=Card owner

View File

@ -803,6 +803,28 @@ if (! $source)
print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
print '</td></tr>'."\n";
if (! empty($conf->stripe->enabled) && $paymentmethod == 'stripe' && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION))
{
require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
$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;
// for dev only
print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentIntent");
print '</td><td class="CTableRow'.($var?'1':'2').'">';
$paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus);
print '<b>'.$paymentintent->id.'</b>';
print '</td></tr>'."\n";
}
// We do not add fields shipToName, shipToStreet, shipToCity, shipToState, shipToCountryCode, shipToZip, shipToStreet2, phoneNum
// as they don't exists (buyer is unknown, tag is free).
}
@ -896,6 +918,29 @@ if ($source == 'order')
print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
print '</td></tr>'."\n";
if (! empty($conf->stripe->enabled) && $paymentmethod == 'stripe' && empty($order->billed) && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION))
{
require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
$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 = $stripe->customerStripe($order->thirdparty, $stripeacc, $servicestatus, 1);
// for dev only
print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentIntent");
print '</td><td class="CTableRow'.($var?'1':'2').'">';
$paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus);
print '<b>'.$paymentintent->id.'</b>';
print '</td></tr>'."\n";
}
// Shipping address
$shipToName=$order->thirdparty->name;
$shipToStreet=$order->thirdparty->address;
@ -1007,14 +1052,14 @@ if ($source == 'invoice')
print '<input type="hidden" name="amount" value="'.$amount.'">';
print '<input type="hidden" name="newamount" value="'.$amount.'">';
}
// Currency
print ' <b>'.$langs->trans("Currency".$currency).'</b>';
print '<input type="hidden" name="currency" value="'.$currency.'">';
}
else
{
print price($object->total_ttc, 1, $langs);
print '<b>'.price($object->total_ttc, 1, $langs).'</b>';
}
// Currency
print ' <b>'.$langs->trans("Currency".$currency).'</b>';
print '<input type="hidden" name="currency" value="'.$currency.'">';
print '</td></tr>'."\n";
// Tag
@ -1024,6 +1069,28 @@ if ($source == 'invoice')
print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
print '</td></tr>'."\n";
if (! empty($conf->stripe->enabled) && ($paymentmethod == 'stripe') && empty($object->paye) && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION))
{
require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
$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 = $stripe->customerStripe($invoice->thirdparty, $stripeacc, $servicestatus, 1);
// for dev only
print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentIntent");
print '</td><td class="CTableRow'.($var?'1':'2').'">';
$paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus);
print '<b>'.$paymentintent->id.'</b>';
print '</td></tr>'."\n";
}
// Shipping address
$shipToName=$invoice->thirdparty->name;
$shipToStreet=$invoice->thirdparty->address;
@ -1149,6 +1216,7 @@ if ($source == 'contractline')
// Debitor
print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty");
print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$contract->thirdparty->name.'</b>';
print '</td></tr>'."\n";
// Object
$text='<b>'.$langs->trans("PaymentRenewContractId", $contract->ref, $contractline->ref).'</b>';
@ -1234,6 +1302,29 @@ if ($source == 'contractline')
print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
print '</td></tr>'."\n";
if (! empty($conf->stripe->enabled) && $paymentmethod == 'stripe' && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION))
{
require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
$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;
// for dev only
print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentIntent");
print '</td><td class="CTableRow'.($var?'1':'2').'">';
$paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus);
print '<b>'.$paymentintent->id.'</b>';
print '</td></tr>'."\n";
}
// Shipping address
$shipToName=$contract->thirdparty->name;
$shipToStreet=$contract->thirdparty->address;
@ -1400,6 +1491,29 @@ if ($source == 'membersubscription')
print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
print '</td></tr>'."\n";
if (! empty($conf->stripe->enabled) && $paymentmethod == 'stripe' && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION))
{
require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
$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;
// for dev only
print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentIntent");
print '</td><td class="CTableRow'.($var?'1':'2').'">';
$paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus);
print '<b>'.$paymentintent->id.'</b>';
print '</td></tr>'."\n";
}
// Shipping address
$shipToName=$member->getFullName($langs);
$shipToStreet=$member->address;
@ -1541,6 +1655,29 @@ if ($source == 'donation')
print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
print '</td></tr>'."\n";
if (! empty($conf->stripe->enabled) && ($paymentmethod == 'stripe') && empty($object->paid) && ! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION))
{
require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
$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 = $stripe->customerStripe($don->thirdparty, $stripeacc, $servicestatus, 1);
// for dev only
print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentIntent");
print '</td><td class="CTableRow'.($var?'1':'2').'">';
$paymentintent=$stripe->getPaymentIntent($amount, $currency, $tag, $object, $stripecu, $stripeacc, $servicestatus);
print '<b>'.$paymentintent->id.'</b>';
print '</td></tr>'."\n";
}
// Shipping address
$shipToName=$don->getFullName($langs);
$shipToStreet=$don->address;
@ -1724,25 +1861,38 @@ if (preg_match('/^dopayment/', $action))
print '<input type="hidden" name="thirdparty_id" value="'.GETPOST('thirdparty_id', 'int').'" />';
print '
<table id="dolpaymenttable" summary="Payment form" class="center">
<tbody><tr><td class="textpublicpayment">
<table id="dolpaymenttable" summary="Payment form" class="center">
<tbody><tr><td class="textpublicpayment">';
<div class="form-row left">
if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION))
{
print '<div id="payment-request-button"><!-- A Stripe Element will be inserted here. --></div>';
}
<label for="card-element">'.$langs->trans("CreditOrDebitCard").'</label>
<div id="card-element">
print '
<div class="form-row left">
<label for="card-element">'.$langs->trans("CreditOrDebitCard").'</label>';
if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION))
{
print '<br><input id="cardholder-name" class="marginbottomonly" name="cardholder-name" value="" type="text" placeholder="'.$langs->trans("CardOwner").'" autocomplete="off" required>';
}
print '<div id="card-element">
<!-- a Stripe Element will be inserted here. -->
</div>
<!-- Used to display form errors -->
<div id="card-errors" role="alert"></div>
</div>
</div>';
<br>
<button class="butAction" id="buttontopay">'.$langs->trans("ValidatePayment").'</button>
print '<br>
<button class="butAction" id="buttontopay"'.(is_object($paymentintent) ? ' data-secret="'.$paymentintent->client_secret.'"' : ' data-nopaymentintent').'>'.$langs->trans("ValidatePayment").'</button>
<img id="hourglasstopay" class="hidden" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/working.gif'.'">
</td></tr></tbody></table>
</td></tr></tbody>
</table>
</form>'."\n";
@ -1750,8 +1900,94 @@ if (preg_match('/^dopayment/', $action))
// Code to ask the credit card. This use the default "API version". No way to force API version when using JS code.
print '<script type="text/javascript" language="javascript">'."\n";
if (! empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION))
{
?>
// Create a Stripe client.
var stripe = Stripe('<?php echo $stripearrayofkeys['publishable_key']; // Defined into config.php ?>');
// Create an instance of Elements
var elements = stripe.elements();
// Custom styling can be passed to options when creating an Element.
// (Note that this demo uses a wider set of styles than the guide below.)
var style = {
base: {
color: '#32325d',
lineHeight: '24px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
var cardElement = elements.create('card', {style: style});
var cardholderName = document.getElementById('cardholder-name');
// Add an instance of the card Element into the `card-element` <div>
cardElement.mount('#card-element');
// Handle real-time validation errors from the card Element.
cardElement.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
console.log("Show event error");
displayError.textContent = event.error.message;
} else {
console.log("No error");
displayError.textContent = '';
}
});
// Handle form submission
var cardButton = document.getElementById('buttontopay');
var clientSecret = cardButton.dataset.secret;
cardButton.addEventListener('click', function(event) {
stripe.handleCardPayment(
clientSecret, cardElement, {
source_data: {
owner: {
name: cardholderName.value,
}
}
}
).then(function(result) {
jQuery('#buttontopay').hide();
jQuery('#hourglasstopay').show();
if (result.error) {
console.log("Error on result of handleCardPayment");
jQuery('#buttontopay').show();
jQuery('#hourglasstopay').hide();
// Inform the user if there was an error
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
console.log("No error on result of handleCardPayment, so we submit the form");
// Submit the form
jQuery('#buttontopay').hide();
jQuery('#hourglasstopay').show();
}
});
});
<?php
}
else
{
?>
// Create a Stripe client.
var stripe = Stripe('<?php echo $stripearrayofkeys['publishable_key']; // Defined into config.php ?>');
@ -1869,8 +2105,9 @@ if (preg_match('/^dopayment/', $action))
form.submit();
}
<?php
}
print '</script>';
}
}

View File

@ -140,7 +140,7 @@ class Stripe extends CommonObject
if (empty($object->id))
{
dol_syslog("customerStripe is called with param object not loaded");
dol_syslog("customerStripe is called with the parameter object that is not loaded");
return null;
}
@ -240,6 +240,9 @@ class Stripe extends CommonObject
/**
* Get the Stripe payment intent. Create it with confirm=false
*
* @param double $amount Amount
* @param string $currency_code Currency code
* @param string $tag Tag
* @param Societe $object Object to pay with Stripe
* @param string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe()
* @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect
@ -249,127 +252,133 @@ class Stripe extends CommonObject
* @param boolean $confirmnow false=default, true=try to confirm immediatly after create (if conditions are ok)
* @return \Stripe\PaymentIntent|null Stripe PaymentIntent or null if not found
*/
public function getPaymentIntent($object, $customer, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false)
public function getPaymentIntent($amount, $currency_code, $tag, $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false)
{
global $conf, $user, $mysoc;
if (empty($object->id))
{
dol_syslog("object not loaded");
return null;
}
$error = 0;
if (empty($status)) $service = 'StripeTest';
else $service = 'StripeLive';
$arrayzerounitcurrency=array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
if (! in_array($currency_code, $arrayzerounitcurrency)) $stripeamount = $amount * 100;
else $stripeamount = $amount;
$fee = round(($$stripeamount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE) * 100);
if ($fee >= ($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100) && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL>$conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
$fee = round($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100);
} elseif ($fee < ($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100)) {
$fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100);
}
$paymentintent = null;
$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";
$sql.= " WHERE pi.fk_facture = " . $object->id;
$sql.= " AND pi.sourcetype = '" . $object->element . "'";
$sql.= " AND pi.entity IN (".getEntity('societe').")";
$sql.= " AND pi.ext_payment_site = '" . $service . "'";
dol_syslog(get_class($this) . "::getPaymentIntent search stripe customer id for thirdparty id=".$object->id, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
if ($num)
{
$obj = $this->db->fetch_object($resql);
$intent = $obj->ext_payment_id;
dol_syslog(get_class($this) . "::getPaymentIntent found existing payment intent record");
// Force to use the correct API key
global $stripearrayofkeysbyenv;
\Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
try {
if (empty($key)) { // If the Stripe connect account not set, we use common API usage
$paymentintent = \Stripe\PaymentIntent::retrieve($intent);
} else {
$paymentintent = \Stripe\PaymentIntent::retrieve($intent, array("stripe_account" => $key));
}
}
catch(Exception $e)
{
$this->error = $e->getMessage();
}
}
else //if ($createifnotlinkedtostripe)
{
$arrayzerounitcurrency=array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
if (! in_array($object->multicurrency_code, $arrayzerounitcurrency)) $stripeamount=$object->multicurrency_total_ttc * 100;
else $stripeamount = $object->multicurrency_total_ttc;
$fee = round(($object->total_ttc * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE) * 100);
if ($fee >= ($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100) && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL>$conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
$fee = round($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100);
} elseif ($fee < ($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100)) {
$fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100);
}
$ipaddress=getUserRemoteIP();
// Not enough space for a ref so we store id. Also with multicompany we can have same ref for 2 different
// object and we need a unique (this is used later as idempotency_key)
$description=$object->element.$object->id;
$dataforintent = array(
"confirm" => $confirmnow, // Do not confirm immediatly during creation of intent
"confirmation_method" => $mode,
"amount" => $stripeamount,
"currency" => $object->multicurrency_code,
"customer" => $customer,
"allowed_source_types" => ["card"],
"statement_descriptor" => dol_trunc($description, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description)
"metadata" => array('dol_type'=>$object->element, 'dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress)
);
// save_payment_method = true,
// payment_method_types =
// payment_method =
if ($conf->entity!=$conf->global->STRIPECONNECT_PRINCIPAL && $fee>0)
{
$dataforintent["application_fee"] = $fee;
}
if ($usethirdpartyemailforreceiptemail && $object->thirdparty->email)
{
$dataforintent["receipt_email"] = $object->thirdparty->email;
}
try {
// Force to use the correct API key
global $stripearrayofkeysbyenv;
\Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
if (empty($key)) { // If the Stripe connect account not set, we use common API usage
$paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description"));
} else {
$paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description","stripe_account" => $key));
}
$now=dol_now();
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "prelevement_facture_demande (fk_soc, date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site)";
$sql .= " VALUES ('".$object->socid."','".$this->db->idate($now)."', '0', '".$this->db->escape($paymentintent->id)."', ".$object->id.", '".$this->db->escape($object->element)."', " . $conf->entity . ", '" . $service . "')";
$resql = $this->db->query($sql);
if (! $resql)
{
$this->error = $this->db->lasterror();
dol_syslog(get_class($this) . "::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id." into database.");
}
}
catch(Exception $e)
{
$this->error = $e->getMessage();
}
}
}
else
if (is_object($object))
{
dol_print_error($this->db);
$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";
$sql.= " WHERE pi.fk_facture = " . $object->id;
$sql.= " AND pi.sourcetype = '" . $object->element . "'";
$sql.= " AND pi.entity IN (".getEntity('societe').")";
$sql.= " AND pi.ext_payment_site = '" . $service . "'";
dol_syslog(get_class($this) . "::getPaymentIntent search stripe payment intent for object id = ".$object->id, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
if ($num)
{
$obj = $this->db->fetch_object($resql);
$intent = $obj->ext_payment_id;
dol_syslog(get_class($this) . "::getPaymentIntent found existing payment intent record");
// Force to use the correct API key
global $stripearrayofkeysbyenv;
\Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
try {
if (empty($key)) { // If the Stripe connect account not set, we use common API usage
$paymentintent = \Stripe\PaymentIntent::retrieve($intent);
} else {
$paymentintent = \Stripe\PaymentIntent::retrieve($intent, array("stripe_account" => $key));
}
}
catch(Exception $e)
{
$this->error = $e->getMessage();
}
}
}
}
if (empty($paymentintent))
{
$ipaddress=getUserRemoteIP();
// Not enough space for a ref so we store id. Also with multicompany we can have same ref for 2 different
// object and we need a unique (this is used later as idempotency_key)
$description=$tag;
$metadata = array('dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress);
if (is_object($object))
{
$metadata['dol_type'] = $object->element;
$metadata['dol_id'] = $object->id;
}
$dataforintent = array(
"confirm" => $confirmnow, // Do not confirm immediatly during creation of intent
"confirmation_method" => $mode,
"amount" => $stripeamount,
"currency" => $currency_code,
"payment_method_types" => ["card"],
"statement_descriptor" => dol_trunc($description, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description)
"metadata" => $metadata
);
if (! is_null($customer)) $dataforintent["customer"]=$customer;
// save_payment_method = true,
// payment_method =
if ($conf->entity!=$conf->global->STRIPECONNECT_PRINCIPAL && $fee>0)
{
$dataforintent["application_fee"] = $fee;
}
if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email)
{
$dataforintent["receipt_email"] = $object->thirdparty->email;
}
try {
// Force to use the correct API key
global $stripearrayofkeysbyenv;
\Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
if (empty($key)) { // If the Stripe connect account not set, we use common API usage
$paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description"));
} else {
$paymentintent = \Stripe\PaymentIntent::create($dataforintent, array("idempotency_key" => "$description", "stripe_account" => $key));
}
// Store the payment intent
if (is_object($object))
{
$now=dol_now();
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "prelevement_facture_demande (fk_soc, date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site)";
$sql .= " VALUES ('".$object->socid."','".$this->db->idate($now)."', '0', '".$this->db->escape($paymentintent->id)."', ".$object->id.", '".$this->db->escape($object->element)."', " . $conf->entity . ", '" . $service . "')";
$resql = $this->db->query($sql);
if (! $resql)
{
$this->error = $this->db->lasterror();
dol_syslog(get_class($this) . "::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id." into database.");
}
}
else
{
$_SESSION["stripe_payment_intent"] = $paymentintent;
}
}
catch(Exception $e)
{
$this->error = $e->getMessage();
}
}
return $paymentintent;