19 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
20 require_once DOL_DOCUMENT_ROOT.
'/societe/class/societe.class.php';
21 require_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
22 require_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture.class.php';
23 require_once DOL_DOCUMENT_ROOT.
'/stripe/config.php';
95 $entity = $conf->entity;
98 $sql =
"SELECT tokenstring";
99 $sql .=
" FROM ".MAIN_DB_PREFIX.
"oauth_token";
100 $sql .=
" WHERE service = '".$this->db->escape($mode).
"'";
101 $sql .=
" AND entity = ".((int) $entity);
103 $sql .=
" AND fk_soc = ".((int) $fk_soc);
105 $sql .=
" AND fk_soc IS NULL";
107 $sql .=
" AND fk_user IS NULL AND fk_adherent IS NULL";
109 dol_syslog(get_class($this).
"::getStripeAccount", LOG_DEBUG);
111 $result = $this->db->query(
$sql);
113 if ($this->db->num_rows($result)) {
114 $obj = $this->db->fetch_object($result);
115 $tokenstring = $obj->tokenstring;
118 $tmparray = json_decode($tokenstring);
119 $key = empty($tmparray->stripe_user_id) ?
'' : $tmparray->stripe_user_id;
128 dol_syslog(
"No dedicated Stripe Connect account available for entity ".$conf->entity);
143 include_once DOL_DOCUMENT_ROOT.
'/societe/class/societeaccount.class.php';
145 return $societeaccount->getCustomerAccount($id,
'stripe', $status, $site_account);
163 if (empty($object->id)) {
164 dol_syslog(
"customerStripe is called with the parameter object that is not loaded");
171 global $stripearrayofkeysbyenv;
172 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
174 $sql =
"SELECT sa.key_account as key_account, sa.entity";
175 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe_account as sa";
176 $sql .=
" WHERE sa.fk_soc = ".((int) $object->id);
177 $sql .=
" AND sa.entity IN (".getEntity(
'societe').
")";
178 $sql .=
" AND sa.site = 'stripe' AND sa.status = ".((int) $status);
179 $sql .=
" AND (sa.site_account IS NULL OR sa.site_account = '' OR sa.site_account = '".$this->db->escape($stripearrayofkeysbyenv[$status][
'publishable_key']).
"')";
180 $sql .=
" AND sa.key_account IS NOT NULL AND sa.key_account <> ''";
182 dol_syslog(get_class($this).
"::customerStripe search stripe customer id for thirdparty id=".$object->id, LOG_DEBUG);
183 $resql = $this->db->query(
$sql);
185 $num = $this->db->num_rows($resql);
187 $obj = $this->db->fetch_object($resql);
188 $tiers = $obj->key_account;
190 dol_syslog(get_class($this).
"::customerStripe found stripe customer key_account = ".$tiers.
". We will try to read it on Stripe with publishable_key = ".$stripearrayofkeysbyenv[$status][
'publishable_key']);
195 $customer = \Stripe\Customer::retrieve(array(
'id'=>
"$tiers",
'expand[]'=>
'sources'));
198 $customer = \Stripe\Customer::retrieve(array(
'id'=>
"$tiers",
'expand[]'=>
'sources'), array(
"stripe_account" => $key));
202 $this->error = $e->getMessage();
204 } elseif ($createifnotlinkedtostripe) {
207 $dataforcustomer = array(
208 "email" => $object->email,
209 "description" => $object->name,
210 "metadata" => array(
'dol_id'=>$object->id,
'dol_version'=>DOL_VERSION,
'dol_entity'=>$conf->entity,
'ipaddress'=>$ipaddress)
213 $vatcleaned = $object->tva_intra ? $object->tva_intra :
null;
230 global $stripearrayofkeysbyenv;
231 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
234 $customer = \Stripe\Customer::create($dataforcustomer);
236 $customer = \Stripe\Customer::create($dataforcustomer, array(
"stripe_account" => $key));
240 if (!empty($conf->global->STRIPE_SAVE_TAX_IDS)) {
241 if (!empty($vatcleaned)) {
243 if ($object->country_code && $isineec) {
245 $customer->createTaxId($customer->id, array(
'type'=>
'eu_vat',
'value'=>$vatcleaned));
251 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"societe_account (fk_soc, login, key_account, site, site_account, status, entity, date_creation, fk_user_creat)";
252 $sql .=
" VALUES (".((int) $object->id).
", '', '".$this->db->escape($customer->id).
"', 'stripe', '".$this->db->escape($stripearrayofkeysbyenv[$status][
'publishable_key']).
"', ".((int) $status).
", ".((int) $conf->entity).
", '".$this->db->idate(
dol_now()).
"', ".((
int) $user->id).
")";
253 $resql = $this->db->query(
$sql);
255 $this->error = $this->db->lasterror();
258 $this->error = $e->getMessage();
278 $stripepaymentmethod =
null;
282 global $stripearrayofkeysbyenv;
283 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
285 $stripepaymentmethod = \Stripe\PaymentMethod::retrieve((
string) $paymentmethod->id);
287 $stripepaymentmethod = \Stripe\PaymentMethod::retrieve((
string) $paymentmethod->id, array(
"stripe_account" => $key));
290 $this->error = $e->getMessage();
293 return $stripepaymentmethod;
306 $selectedreader =
null;
310 global $stripearrayofkeysbyenv;
311 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
313 $selectedreader = \Stripe\Terminal\Reader::retrieve((
string) $reader);
315 $stripepaymentmethod = \Stripe\Terminal\Reader::retrieve((
string) $reader, array(
"stripe_account" => $key));
318 $this->error = $e->getMessage();
321 return $selectedreader;
350 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 = 1, $did = 0)
354 dol_syslog(get_class($this).
"::getPaymentIntent", LOG_INFO, 1);
358 if (empty($status)) {
359 $service =
'StripeTest';
361 $service =
'StripeLive';
364 $arrayzerounitcurrency = array(
'BIF',
'CLP',
'DJF',
'GNF',
'JPY',
'KMF',
'KRW',
'MGA',
'PYG',
'RWF',
'VND',
'VUV',
'XAF',
'XOF',
'XPF');
365 if (!in_array($currency_code, $arrayzerounitcurrency)) {
366 $stripeamount = $amount * 100;
368 $stripeamount = $amount;
380 if (!in_array($currency_code, $arrayzerounitcurrency)) {
381 $stripefee = round($fee * 100);
383 $stripefee = round($fee);
386 $paymentintent =
null;
395 $sql =
"SELECT pi.ext_payment_id, pi.entity, pi.fk_facture, pi.sourcetype, pi.ext_payment_site";
396 $sql .=
" FROM ".MAIN_DB_PREFIX.
"prelevement_demande as pi";
397 $sql .=
" WHERE pi.fk_facture = ".((int) $object->id);
398 $sql .=
" AND pi.sourcetype = '".$this->db->escape($object->element).
"'";
399 $sql .=
" AND pi.entity IN (".getEntity(
'societe').
")";
400 $sql .=
" AND pi.ext_payment_site = '".$this->db->escape($service).
"'";
402 dol_syslog(get_class($this).
"::getPaymentIntent search stripe payment intent for object id = ".$object->id, LOG_DEBUG);
403 $resql = $this->db->query(
$sql);
405 $num = $this->db->num_rows($resql);
407 $obj = $this->db->fetch_object($resql);
408 $intent = $obj->ext_payment_id;
410 dol_syslog(get_class($this).
"::getPaymentIntent found existing payment intent record");
413 global $stripearrayofkeysbyenv;
414 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
418 $paymentintent = \Stripe\PaymentIntent::retrieve($intent);
420 $paymentintent = \Stripe\PaymentIntent::retrieve($intent, array(
"stripe_account" => $key));
424 $this->error = $e->getMessage();
430 if (empty($paymentintent)) {
433 $metadata = array(
'dol_version'=>DOL_VERSION,
'dol_entity'=>$conf->entity,
'ipaddress'=>$ipaddress);
434 if (is_object($object)) {
435 $metadata[
'dol_type'] = $object->element;
436 $metadata[
'dol_id'] = $object->id;
437 if (is_object($object->thirdparty) && $object->thirdparty->id > 0) {
438 $metadata[
'dol_thirdparty_id'] = $object->thirdparty->id;
443 $paymentmethodtypes = array(
"card");
444 $descriptor =
dol_trunc($tag, 10,
'right',
'UTF-8', 1);
446 $paymentmethodtypes[] =
"sepa_debit";
450 $paymentmethodtypes[] =
"klarna";
453 $paymentmethodtypes[] =
"bancontact";
456 $paymentmethodtypes[] =
"ideal";
459 $paymentmethodtypes[] =
"giropay";
462 $paymentmethodtypes[] =
"sofort";
465 $paymentmethodtypes = array(
"card_present");
468 $dataforintent = array(
469 "confirm" => $confirmnow,
470 "confirmation_method" => $mode,
471 "amount" => $stripeamount,
472 "currency" => $currency_code,
473 "payment_method_types" => $paymentmethodtypes,
474 "description" => $description,
476 "setup_future_usage" =>
"on_session",
477 "metadata" => $metadata
480 $dataforintent[
"statement_descriptor_suffix"] = $descriptor;
481 $dataforintent[
"statement_descriptor"] = $descriptor;
483 if (!is_null($customer)) {
484 $dataforintent[
"customer"] = $customer;
490 unset($dataforintent[
'setup_future_usage']);
494 $dataforintent[
"off_session"] =
true;
497 unset($dataforintent[
'setup_future_usage']);
500 unset($dataforintent[
'setup_future_usage']);
503 unset($dataforintent[
'setup_future_usage']);
504 $dataforintent[
"capture_method"] =
"manual";
505 $dataforintent[
"confirmation_method"] =
"manual";
507 if (!is_null($payment_method)) {
508 $dataforintent[
"payment_method"] = $payment_method;
509 $description .=
' - '.$payment_method;
512 if ($conf->entity !=
getDolGlobalInt(
'STRIPECONNECT_PRINCIPAL') && $stripefee > 0) {
513 $dataforintent[
"application_fee_amount"] = $stripefee;
515 if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email) {
516 $dataforintent[
"receipt_email"] = $object->thirdparty->email;
521 global $stripearrayofkeysbyenv;
522 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
524 $arrayofoptions = array();
525 if (empty($noidempotency_key)) {
526 $arrayofoptions[
"idempotency_key"] = $description;
530 $arrayofoptions[
"stripe_account"] = $key;
533 dol_syslog(
"dataforintent to create paymentintent = ".var_export($dataforintent,
true));
535 $paymentintent = \Stripe\PaymentIntent::create($dataforintent, $arrayofoptions);
538 if (is_object($object)) {
539 $paymentintentalreadyexists = 0;
543 dol_syslog(get_class($this).
"::getPaymentIntent search if payment intent already in prelevement_demande", LOG_DEBUG);
545 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"prelevement_demande SET";
546 $sql .=
" ext_payment_site = '".$this->db->escape($service).
"',";
547 $sql .=
" ext_payment_id = '".$this->db->escape($paymentintent->id).
"'";
548 $sql .=
" WHERE rowid = ".((int) $did);
550 $resql = $this->db->query(
$sql);
552 $paymentintentalreadyexists++;
559 dol_syslog(get_class($this).
"::getPaymentIntent search if payment intent already in prelevement_demande", LOG_DEBUG);
561 $sql =
"SELECT pi.rowid";
562 $sql .=
" FROM ".MAIN_DB_PREFIX.
"prelevement_demande as pi";
563 $sql .=
" WHERE pi.entity IN (".getEntity(
'societe').
")";
564 $sql .=
" AND pi.ext_payment_site = '".$this->db->escape($service).
"'";
565 $sql .=
" AND pi.ext_payment_id = '".$this->db->escape($paymentintent->id).
"'";
567 $resql = $this->db->query(
$sql);
569 $num = $this->db->num_rows($resql);
571 $obj = $this->db->fetch_object($resql);
573 $paymentintentalreadyexists++;
583 if (!$error && !$paymentintentalreadyexists) {
585 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"prelevement_demande (date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site, amount)";
586 $sql .=
" VALUES ('".$this->db->idate($now).
"', ".((int) $user->id).
", '".$this->db->escape($paymentintent->id).
"', ".((int) $object->id).
", '".$this->db->escape($object->element).
"', ".((int) $conf->entity).
", '".$this->db->escape($service).
"', ".((
float) $amount).
")";
587 $resql = $this->db->query(
$sql);
590 $this->error = $this->db->lasterror();
591 dol_syslog(get_class($this).
"::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id.
" into database.", LOG_ERR);
595 $_SESSION[
"stripe_payment_intent"] = $paymentintent;
597 }
catch (
Stripe\Error\Card $e) {
599 $this->error = $e->getMessage();
600 $this->
code = $e->getStripeCode();
601 $this->declinecode = $e->getDeclineCode();
610 $this->error = $e->getMessage();
612 $this->declinecode =
'';
616 dol_syslog(get_class($this).
"::getPaymentIntent return error=".$error.
" this->error=".$this->error, LOG_INFO, -1);
619 return $paymentintent;
643 public function getSetupIntent($description, $object, $customer, $key, $status, $usethirdpartyemailforreceiptemail = 0, $confirmnow =
false)
647 dol_syslog(
"getSetupIntent description=".$description.
' confirmnow='.$confirmnow, LOG_INFO, 1);
651 if (empty($status)) {
652 $service =
'StripeTest';
654 $service =
'StripeLive';
659 if (empty($setupintent)) {
661 $metadata = array(
'dol_version'=>DOL_VERSION,
'dol_entity'=>$conf->entity,
'ipaddress'=>$ipaddress);
662 if (is_object($object)) {
663 $metadata[
'dol_type'] = $object->element;
664 $metadata[
'dol_id'] = $object->id;
665 if (is_object($object->thirdparty) && $object->thirdparty->id > 0) {
666 $metadata[
'dol_thirdparty_id'] = $object->thirdparty->id;
671 $paymentmethodtypes = array(
"card");
672 if (!empty($conf->global->STRIPE_SEPA_DIRECT_DEBIT)) {
673 $paymentmethodtypes[] =
"sepa_debit";
675 if (!empty($conf->global->STRIPE_BANCONTACT)) {
676 $paymentmethodtypes[] =
"bancontact";
678 if (!empty($conf->global->STRIPE_IDEAL)) {
679 $paymentmethodtypes[] =
"ideal";
682 if (!empty($conf->global->STRIPE_SOFORT)) {
683 $paymentmethodtypes[] =
"sofort";
686 $dataforintent = array(
687 "confirm" => $confirmnow,
688 "payment_method_types" => $paymentmethodtypes,
689 "usage" =>
"off_session",
690 "metadata" => $metadata
692 if (!is_null($customer)) {
693 $dataforintent[
"customer"] = $customer;
695 if (!is_null($description)) {
696 $dataforintent[
"description"] = $description;
702 if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email) {
703 $dataforintent[
"receipt_email"] = $object->thirdparty->email;
708 global $stripearrayofkeysbyenv;
709 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
711 dol_syslog(
"getSetupIntent ".$stripearrayofkeysbyenv[$status][
'publishable_key'], LOG_DEBUG);
716 $setupintent = \Stripe\SetupIntent::create($dataforintent, array());
719 $setupintent = \Stripe\SetupIntent::create($dataforintent, array(
"stripe_account" => $key));
772 $this->error = $e->getMessage();
777 dol_syslog(
"getSetupIntent ".(is_object($setupintent) ? $setupintent->id :
''), LOG_INFO, -1);
780 dol_syslog(
"getSetupIntent return error=".$error, LOG_INFO, -1);
798 global $conf, $user, $langs;
802 $sql =
"SELECT sa.stripe_card_ref, sa.proprio, sa.exp_date_month, sa.exp_date_year, sa.number, sa.cvn";
803 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe_rib as sa";
804 $sql .=
" WHERE sa.rowid = ".((int) $object->id);
805 $sql .=
" AND sa.type = 'card'";
807 dol_syslog(get_class($this).
"::cardStripe search stripe card id for paymentmode id=".$object->id.
", stripeacc=".$stripeacc.
", status=".$status.
", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
808 $resql = $this->db->query(
$sql);
810 $num = $this->db->num_rows($resql);
812 $obj = $this->db->fetch_object($resql);
813 $cardref = $obj->stripe_card_ref;
814 dol_syslog(get_class($this).
"::cardStripe cardref=".$cardref);
817 if (empty($stripeacc)) {
818 if (!preg_match(
'/^pm_/', $cardref) && !empty($cu->sources)) {
819 $card = $cu->sources->retrieve($cardref);
821 $card = \Stripe\PaymentMethod::retrieve($cardref);
824 if (!preg_match(
'/^pm_/', $cardref) && !empty($cu->sources)) {
826 $card = $cu->sources->retrieve($cardref);
829 $card = \Stripe\PaymentMethod::retrieve($cardref);
833 $this->error = $e->getMessage();
836 } elseif ($createifnotlinkedtostripe) {
838 $exp_date_month = $obj->exp_date_month;
839 $exp_date_year = $obj->exp_date_year;
840 $number = $obj->number;
842 $cardholdername = $obj->proprio;
846 $dataforcard = array(
849 'exp_month'=>$exp_date_month,
850 'exp_year'=>$exp_date_year,
853 'name'=>$cardholdername
856 'dol_type'=>$object->element,
857 'dol_id'=>$object->id,
858 'dol_version'=>DOL_VERSION,
859 'dol_entity'=>$conf->entity,
860 'ipaddress'=>$ipaddress
868 if (empty($stripeacc)) {
869 if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) {
870 dol_syslog(
"Try to create card with dataforcard = ".json_encode($dataforcard));
871 $card = $cu->sources->create($dataforcard);
873 $this->error =
'Creation of card on Stripe has failed';
877 if (!empty($stripeacc)) {
878 $connect = $stripeacc.
'/';
880 $url =
'https://dashboard.stripe.com/'.$connect.
'test/customers/'.$cu->id;
882 $url =
'https://dashboard.stripe.com/'.$connect.
'customers/'.$cu->id;
884 $urtoswitchonstripe =
' <a href="'.$url.
'" target="_stripe">'.
img_picto($langs->trans(
'ShowInStripe'),
'globe').
'</a>';
887 $this->error = $langs->trans(
'CreationOfPaymentModeMustBeDoneFromStripeInterface', $urtoswitchonstripe);
890 if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) {
891 dol_syslog(
"Try to create card with dataforcard = ".json_encode($dataforcard));
892 $card = $cu->sources->create($dataforcard, array(
"stripe_account" => $stripeacc));
894 $this->error =
'Creation of card on Stripe has failed';
898 if (!empty($stripeacc)) {
899 $connect = $stripeacc.
'/';
901 $url =
'https://dashboard.stripe.com/'.$connect.
'test/customers/'.$cu->id;
903 $url =
'https://dashboard.stripe.com/'.$connect.
'customers/'.$cu->id;
905 $urtoswitchonstripe =
' <a href="'.$url.
'" target="_stripe">'.
img_picto($langs->trans(
'ShowInStripe'),
'globe').
'</a>';
908 $this->error = $langs->trans(
'CreationOfPaymentModeMustBeDoneFromStripeInterface', $urtoswitchonstripe);
913 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"societe_rib";
914 $sql .=
" SET stripe_card_ref = '".$this->db->escape($card->id).
"', card_type = '".$this->db->escape($card->brand).
"',";
915 $sql .=
" country_code = '".$this->db->escape($card->country).
"',";
916 $sql .=
" approved = ".($card->cvc_check ==
'pass' ? 1 : 0);
917 $sql .=
" WHERE rowid = ".((int) $object->id);
918 $sql .=
" AND type = 'card'";
919 $resql = $this->db->query(
$sql);
921 $this->error = $this->db->lasterror();
925 $this->error = $e->getMessage();
950 global $conf, $user, $langs;
953 $sql =
"SELECT sa.stripe_card_ref, sa.proprio, sa.iban_prefix as iban, sa.rum";
954 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe_rib as sa";
955 $sql .=
" WHERE sa.rowid = ".((int) $object->id);
956 $sql .=
" AND sa.type = 'ban'";
959 $soc->fetch($object->fk_soc);
961 dol_syslog(get_class($this).
"::sepaStripe search stripe ban id for paymentmode id=".$object->id.
", stripeacc=".$stripeacc.
", status=".$status.
", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
962 $resql = $this->db->query(
$sql);
964 $num = $this->db->num_rows($resql);
966 $obj = $this->db->fetch_object($resql);
967 $cardref = $obj->stripe_card_ref;
968 dol_syslog(get_class($this).
"::sepaStripe paymentmode=".$cardref);
971 if (empty($stripeacc)) {
972 if (!preg_match(
'/^pm_/', $cardref) && !empty($cu->sources)) {
973 $sepa = $cu->sources->retrieve($cardref);
975 $sepa = \Stripe\PaymentMethod::retrieve($cardref);
978 if (!preg_match(
'/^pm_/', $cardref) && !empty($cu->sources)) {
980 $sepa = $cu->sources->retrieve($cardref);
983 $sepa = \Stripe\PaymentMethod::retrieve($cardref);
987 $this->error = $e->getMessage();
990 } elseif ($createifnotlinkedtostripe) {
993 $metadata = array(
'dol_version'=>DOL_VERSION,
'dol_entity'=>$conf->entity,
'ipaddress'=>$ipaddress);
994 if (is_object($object)) {
995 $metadata[
'dol_type'] = $object->element;
996 $metadata[
'dol_id'] = $object->id;
997 $metadata[
'dol_thirdparty_id'] = $soc->id;
1000 $description =
'SEPA for IBAN '.$iban;
1002 $dataforcard = array(
1003 'type'=>
'sepa_debit',
1004 "sepa_debit" => array(
'iban' => $iban),
1005 'billing_details' => array(
1006 'name' => $soc->name,
1007 'email' => !empty($soc->email) ? $soc->email :
"",
1009 "metadata" => $metadata
1012 if (!empty($soc->town)) {
1013 $dataforcard[
'billing_details'][
'address'][
'city']=$soc->town;
1015 if (!empty($soc->country_code)) {
1016 $dataforcard[
'billing_details'][
'address'][
'country']=$soc->country_code;
1018 if (!empty($soc->address)) {
1019 $dataforcard[
'billing_details'][
'address'][
'line1']=$soc->address;
1021 if (!empty($soc->zip)) {
1022 $dataforcard[
'billing_details'][
'address'][
'postal_code']=$soc->zip;
1024 if (!empty($soc->state)) {
1025 $dataforcard[
'billing_details'][
'address'][
'state']=$soc->state;
1033 $service =
'StripeTest';
1035 if (!empty($conf->global->STRIPE_LIVE) && !
GETPOST(
'forcesandbox',
'alpha')) {
1036 $service =
'StripeLive';
1040 global $stripearrayofkeysbyenv;
1041 $stripeacc = $stripearrayofkeysbyenv[$servicestatus][
'secret_key'];
1043 dol_syslog(
"Try to create sepa_debit with data = ".json_encode($dataforcard));
1045 $s = new \Stripe\StripeClient($stripeacc);
1049 $sepa = $s->paymentMethods->create($dataforcard);
1051 $this->error =
'Creation of payment method sepa_debit on Stripe has failed';
1055 $dataforintent = array([
'description'=> $description,
'payment_method_types' => [
'sepa_debit'],
'customer' => $cu->id,
'payment_method' => $sepa->id],
'metadata'=>$metadata);
1056 $cs = $s->setupIntents->create($dataforintent);
1058 $cs = $s->setupIntents->confirm($cs->id, [
'mandate_data' => [
'customer_acceptance' => [
'type' =>
'offline']]]);
1060 $this->error =
'Link SEPA <-> Customer failed';
1062 dol_syslog(
"Update the payment mode of the customer");
1066 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"societe_rib";
1067 $sql .=
" SET stripe_card_ref = '".$this->db->escape($sepa->id).
"', card_type = 'sepa_debit',";
1068 $sql .=
" stripe_account= '" . $this->db->escape($cu->id .
"@" . $stripeacc) .
"'";
1069 $sql .=
" WHERE rowid = ".((int) $object->id);
1070 $sql .=
" AND type = 'ban'";
1071 $resql = $this->db->query(
$sql);
1073 $this->error = $this->db->lasterror();
1079 $this->error = $e->getMessage();
1108 public function createPaymentStripe($amount, $currency, $origin, $item, $source, $customer, $account, $status = 0, $usethirdpartyemailforreceiptemail = 0, $capture =
true)
1114 if (empty($status)) {
1115 $service =
'StripeTest';
1117 $service =
'StripeLive';
1120 $sql =
"SELECT sa.key_account as key_account, sa.fk_soc, sa.entity";
1121 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe_account as sa";
1122 $sql .=
" WHERE sa.key_account = '".$this->db->escape($customer).
"'";
1124 $sql .=
" AND sa.site = 'stripe' AND sa.status = ".((int) $status);
1126 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1127 $result = $this->db->query(
$sql);
1129 if ($this->db->num_rows($result)) {
1130 $obj = $this->db->fetch_object($result);
1131 $key = $obj->fk_soc;
1139 $arrayzerounitcurrency = array(
'BIF',
'CLP',
'DJF',
'GNF',
'JPY',
'KMF',
'KRW',
'MGA',
'PYG',
'RWF',
'VND',
'VUV',
'XAF',
'XOF',
'XPF');
1140 if (!in_array($currency, $arrayzerounitcurrency)) {
1141 $stripeamount = $amount * 100;
1143 $stripeamount = $amount;
1146 $societe =
new Societe($this->db);
1148 $societe->fetch($key);
1153 if ($origin ==
'order') {
1155 $order->fetch($item);
1157 $description =
"ORD=".$ref.
".CUS=".$societe->id.
".PM=stripe";
1158 } elseif ($origin ==
'invoice') {
1159 $invoice =
new Facture($this->db);
1160 $invoice->fetch($item);
1161 $ref = $invoice->ref;
1162 $description =
"INV=".$ref.
".CUS=".$societe->id.
".PM=stripe";
1168 "dol_id" => (
string) $item,
1169 "dol_type" => (
string) $origin,
1170 "dol_thirdparty_id" => (
string) $societe->id,
1171 'dol_thirdparty_name' => $societe->name,
1172 'dol_version' => DOL_VERSION,
1173 'dol_entity' => $conf->entity,
1174 'ipaddress' => $ipaddress
1176 $return =
new Stripe($this->db);
1179 global $stripearrayofkeysbyenv;
1180 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
1182 if (empty($conf->stripeconnect->enabled)) {
1183 if (preg_match(
'/pm_/i', $source)) {
1184 $stripecard = $source;
1185 $amountstripe = $stripeamount;
1188 $amounttopay = $amount;
1189 $servicestatus = $status;
1191 dol_syslog(
"* createPaymentStripe get stripeacc", LOG_DEBUG);
1192 $stripeacc = $stripe->getStripeAccount($service);
1194 dol_syslog(
"* createPaymentStripe Create payment for customer ".$customer->id.
" on source card ".$stripecard->id.
", amounttopay=".$amounttopay.
", amountstripe=".$amountstripe.
", FULLTAG=".$FULLTAG, LOG_DEBUG);
1197 $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $invoice, $customer->id, $stripeacc, $servicestatus, 0,
'automatic',
true, $stripecard->id, 1);
1199 $charge =
new stdClass();
1200 if ($paymentintent->status ==
'succeeded') {
1201 $charge->status =
'ok';
1203 $charge->status =
'failed';
1204 $charge->failure_code = $stripe->code;
1205 $charge->failure_message = $stripe->error;
1206 $charge->failure_declinecode = $stripe->declinecode;
1207 $stripefailurecode = $stripe->code;
1208 $stripefailuremessage = $stripe->error;
1209 $stripefailuredeclinecode = $stripe->declinecode;
1211 } elseif (preg_match(
'/acct_/i', $source)) {
1212 $charge = \Stripe\Charge::create(array(
1213 "amount" =>
"$stripeamount",
1214 "currency" =>
"$currency",
1215 "statement_descriptor_suffix" =>
dol_trunc($description, 10,
'right',
'UTF-8', 1),
1216 "description" =>
"Stripe payment: ".$description,
1217 "capture" => $capture,
1218 "metadata" => $metadata,
1219 "source" =>
"$source"
1222 $paymentarray = array(
1223 "amount" =>
"$stripeamount",
1224 "currency" =>
"$currency",
1225 "statement_descriptor_suffix" =>
dol_trunc($description, 10,
'right',
'UTF-8', 1),
1226 "description" =>
"Stripe payment: ".$description,
1227 "capture" => $capture,
1228 "metadata" => $metadata,
1229 "source" =>
"$source",
1230 "customer" =>
"$customer"
1233 if ($societe->email && $usethirdpartyemailforreceiptemail) {
1234 $paymentarray[
"receipt_email"] = $societe->email;
1237 $charge = \Stripe\Charge::create($paymentarray, array(
"idempotency_key" =>
"$description"));
1241 $fee = $amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE;
1242 if ($fee >= $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL > $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
1243 $fee = $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL;
1244 } elseif ($fee < $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
1245 $fee = $conf->global->STRIPE_APPLICATION_FEE_MINIMAL;
1248 if (!in_array($currency, $arrayzerounitcurrency)) {
1249 $stripefee = round($fee * 100);
1251 $stripefee = round($fee);
1254 $paymentarray = array(
1255 "amount" =>
"$stripeamount",
1256 "currency" =>
"$currency",
1257 "statement_descriptor_suffix" =>
dol_trunc($description, 10,
'right',
'UTF-8', 1),
1258 "description" =>
"Stripe payment: ".$description,
1259 "capture" => $capture,
1260 "metadata" => $metadata,
1261 "source" =>
"$source",
1262 "customer" =>
"$customer"
1264 if ($conf->entity != $conf->global->STRIPECONNECT_PRINCIPAL && $stripefee > 0) {
1265 $paymentarray[
"application_fee_amount"] = $stripefee;
1267 if ($societe->email && $usethirdpartyemailforreceiptemail) {
1268 $paymentarray[
"receipt_email"] = $societe->email;
1271 if (preg_match(
'/pm_/i', $source)) {
1272 $stripecard = $source;
1273 $amountstripe = $stripeamount;
1276 $amounttopay = $amount;
1277 $servicestatus = $status;
1279 dol_syslog(
"* createPaymentStripe get stripeacc", LOG_DEBUG);
1280 $stripeacc = $stripe->getStripeAccount($service);
1282 dol_syslog(
"* createPaymentStripe Create payment on card ".$stripecard->id.
", amounttopay=".$amounttopay.
", amountstripe=".$amountstripe.
", FULLTAG=".$FULLTAG, LOG_DEBUG);
1285 $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $invoice, $customer->id, $stripeacc, $servicestatus, 0,
'automatic',
true, $stripecard->id, 1);
1287 $charge =
new stdClass();
1288 if ($paymentintent->status ==
'succeeded') {
1289 $charge->status =
'ok';
1290 $charge->id = $paymentintent->id;
1292 $charge->status =
'failed';
1293 $charge->failure_code = $stripe->code;
1294 $charge->failure_message = $stripe->error;
1295 $charge->failure_declinecode = $stripe->declinecode;
1298 $charge = \Stripe\Charge::create($paymentarray, array(
"idempotency_key" =>
"$description",
"stripe_account" =>
"$account"));
1301 if (isset($charge->id)) {
1304 $return->statut =
'success';
1305 $return->id = $charge->id;
1307 if (preg_match(
'/pm_/i', $source)) {
1308 $return->message =
'Payment retrieved by card status = '.$charge->status;
1310 if ($charge->source->type ==
'card') {
1311 $return->message = $charge->source->card->brand.
" ....".$charge->source->card->last4;
1312 } elseif ($charge->source->type ==
'three_d_secure') {
1313 $stripe =
new Stripe($this->db);
1314 $src = \Stripe\Source::retrieve(
"".$charge->source->three_d_secure->card, array(
1315 "stripe_account" => $stripe->getStripeAccount($service)
1317 $return->message = $src->card->brand.
" ....".$src->card->last4;
1319 $return->message = $charge->id;
1322 }
catch (\
Stripe\Error\Card $e) {
1323 include DOL_DOCUMENT_ROOT.
'/core/class/CMailFile.class.php';
1325 $body = $e->getJsonBody();
1326 $err = $body[
'error'];
1328 $return->statut =
'error';
1329 $return->id = $err[
'charge'];
1330 $return->type = $err[
'type'];
1331 $return->code = $err[
'code'];
1332 $return->message = $err[
'message'];
1333 $body =
"Error: <br>".$return->id.
" ".$return->message.
" ";
1334 $subject =
'[Alert] Payment error using Stripe';
1335 $cmailfile =
new CMailFile($subject, $conf->global->ONLINE_PAYMENT_SENDEMAIL, $conf->global->MAIN_INFO_SOCIETE_MAIL, $body);
1336 $cmailfile->sendfile();
1339 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1340 }
catch (\
Stripe\Error\RateLimit $e) {
1343 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1344 }
catch (\
Stripe\Error\InvalidRequest $e) {
1347 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1348 }
catch (\
Stripe\Error\Authentication $e) {
1352 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1353 }
catch (\
Stripe\Error\ApiConnection $e) {
1356 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1357 }
catch (\
Stripe\Error\Base $e) {
1361 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1365 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Class to manage customers orders.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
Class for CompanyPaymentMode.
Class to manage invoices.
Class for SocieteAccount.
Class to manage third parties objects (customers, suppliers, prospects...)
getSetupIntent($description, $object, $customer, $key, $status, $usethirdpartyemailforreceiptemail=0, $confirmnow=false)
Get the Stripe payment intent.
getPaymentMethodStripe($paymentmethod, $key='', $status=0)
Get the Stripe payment method Object from its ID.
sepaStripe($cu, CompanyPaymentMode $object, $stripeacc='', $status=0, $createifnotlinkedtostripe=0)
Get the Stripe SEPA of a company payment mode.
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=1, $did=0)
Get the Stripe payment intent.
getStripeCustomerAccount($id, $status=0, $site_account='')
getStripeCustomerAccount
cardStripe($cu, CompanyPaymentMode $object, $stripeacc='', $status=0, $createifnotlinkedtostripe=0)
Get the Stripe card of a company payment mode (option to create it on Stripe if not linked yet is no ...
createPaymentStripe($amount, $currency, $origin, $item, $source, $customer, $account, $status=0, $usethirdpartyemailforreceiptemail=0, $capture=true)
Create charge.
__construct($db)
Constructor.
getStripeAccount($mode='StripeTest', $fk_soc=0, $entity=-1)
Return main company OAuth Connect stripe account.
customerStripe(Societe $object, $key='', $status=0, $createifnotlinkedtostripe=0)
Get the Stripe customer of a thirdparty (with option to create it in Stripe if not linked yet).
getSelectedReader($reader, $key='', $status=0)
Get the Stripe reader Object from its ID.
isInEEC($object)
Return if a country of an object is inside the EEC (European Economic Community)
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
getUserRemoteIP()
Return the IP of remote user.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
div float
Buy price without taxes.
print *****$script_file(".$version.") pid code
! Closing after partial payment: discount_vat, badcustomer or badsupplier, bankcharge,...