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;
117 $tmparray = json_decode($tokenstring);
118 $key = empty($tmparray->stripe_user_id) ?
'' : $tmparray->stripe_user_id;
126 dol_syslog(
"No dedicated Stripe Connect account available for entity ".$conf->entity);
140 include_once DOL_DOCUMENT_ROOT.
'/societe/class/societeaccount.class.php';
142 return $societeaccount->getCustomerAccount($id,
'stripe', $status, $site_account);
160 if (empty($object->id)) {
161 dol_syslog(
"customerStripe is called with the parameter object that is not loaded");
168 global $stripearrayofkeysbyenv;
169 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
171 $sql =
"SELECT sa.key_account as key_account, sa.entity";
172 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe_account as sa";
173 $sql .=
" WHERE sa.fk_soc = ".((int) $object->id);
174 $sql .=
" AND sa.entity IN (".getEntity(
'societe').
")";
175 $sql .=
" AND sa.site = 'stripe' AND sa.status = ".((int) $status);
176 $sql .=
" AND (sa.site_account IS NULL OR sa.site_account = '' OR sa.site_account = '".$this->db->escape($stripearrayofkeysbyenv[$status][
'publishable_key']).
"')";
177 $sql .=
" AND sa.key_account IS NOT NULL AND sa.key_account <> ''";
179 dol_syslog(get_class($this).
"::customerStripe search stripe customer id for thirdparty id=".$object->id, LOG_DEBUG);
180 $resql = $this->db->query(
$sql);
182 $num = $this->db->num_rows($resql);
184 $obj = $this->db->fetch_object($resql);
185 $tiers = $obj->key_account;
187 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']);
192 $customer = \Stripe\Customer::retrieve(array(
'id'=>
"$tiers",
'expand[]'=>
'sources'));
195 $customer = \Stripe\Customer::retrieve(array(
'id'=>
"$tiers",
'expand[]'=>
'sources'), array(
"stripe_account" => $key));
199 $this->error = $e->getMessage();
201 } elseif ($createifnotlinkedtostripe) {
204 $dataforcustomer = array(
205 "email" => $object->email,
206 "description" => $object->name,
207 "metadata" => array(
'dol_id'=>$object->id,
'dol_version'=>DOL_VERSION,
'dol_entity'=>$conf->entity,
'ipaddress'=>$ipaddress)
210 $vatcleaned = $object->tva_intra ? $object->tva_intra :
null;
227 global $stripearrayofkeysbyenv;
228 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
231 $customer = \Stripe\Customer::create($dataforcustomer);
233 $customer = \Stripe\Customer::create($dataforcustomer, array(
"stripe_account" => $key));
237 if (!empty($conf->global->STRIPE_SAVE_TAX_IDS)) {
238 if (!empty($vatcleaned)) {
240 if ($object->country_code && $isineec) {
242 $customer->createTaxId($customer->id, array(
'type'=>
'eu_vat',
'value'=>$vatcleaned));
248 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"societe_account (fk_soc, login, key_account, site, site_account, status, entity, date_creation, fk_user_creat)";
249 $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).
")";
250 $resql = $this->db->query(
$sql);
252 $this->error = $this->db->lasterror();
255 $this->error = $e->getMessage();
275 $stripepaymentmethod =
null;
279 global $stripearrayofkeysbyenv;
280 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
282 $stripepaymentmethod = \Stripe\PaymentMethod::retrieve((
string) $paymentmethod->id);
284 $stripepaymentmethod = \Stripe\PaymentMethod::retrieve((
string) $paymentmethod->id, array(
"stripe_account" => $key));
287 $this->error = $e->getMessage();
290 return $stripepaymentmethod;
303 $selectedreader =
null;
307 global $stripearrayofkeysbyenv;
308 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
310 $selectedreader = \Stripe\Terminal\Reader::retrieve((
string) $reader);
312 $stripepaymentmethod = \Stripe\Terminal\Reader::retrieve((
string) $reader, array(
"stripe_account" => $key));
315 $this->error = $e->getMessage();
318 return $selectedreader;
347 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)
351 dol_syslog(get_class($this).
"::getPaymentIntent", LOG_INFO, 1);
355 if (empty($status)) {
356 $service =
'StripeTest';
358 $service =
'StripeLive';
361 $arrayzerounitcurrency = array(
'BIF',
'CLP',
'DJF',
'GNF',
'JPY',
'KMF',
'KRW',
'MGA',
'PYG',
'RWF',
'VND',
'VUV',
'XAF',
'XOF',
'XPF');
362 if (!in_array($currency_code, $arrayzerounitcurrency)) {
363 $stripeamount = $amount * 100;
365 $stripeamount = $amount;
377 if (!in_array($currency_code, $arrayzerounitcurrency)) {
378 $stripefee = round($fee * 100);
380 $stripefee = round($fee);
383 $paymentintent =
null;
392 $sql =
"SELECT pi.ext_payment_id, pi.entity, pi.fk_facture, pi.sourcetype, pi.ext_payment_site";
393 $sql .=
" FROM ".MAIN_DB_PREFIX.
"prelevement_demande as pi";
394 $sql .=
" WHERE pi.fk_facture = ".((int) $object->id);
395 $sql .=
" AND pi.sourcetype = '".$this->db->escape($object->element).
"'";
396 $sql .=
" AND pi.entity IN (".getEntity(
'societe').
")";
397 $sql .=
" AND pi.ext_payment_site = '".$this->db->escape($service).
"'";
399 dol_syslog(get_class($this).
"::getPaymentIntent search stripe payment intent for object id = ".$object->id, LOG_DEBUG);
400 $resql = $this->db->query(
$sql);
402 $num = $this->db->num_rows($resql);
404 $obj = $this->db->fetch_object($resql);
405 $intent = $obj->ext_payment_id;
407 dol_syslog(get_class($this).
"::getPaymentIntent found existing payment intent record");
410 global $stripearrayofkeysbyenv;
411 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
415 $paymentintent = \Stripe\PaymentIntent::retrieve($intent);
417 $paymentintent = \Stripe\PaymentIntent::retrieve($intent, array(
"stripe_account" => $key));
421 $this->error = $e->getMessage();
427 if (empty($paymentintent)) {
430 $metadata = array(
'dol_version'=>DOL_VERSION,
'dol_entity'=>$conf->entity,
'ipaddress'=>$ipaddress);
431 if (is_object($object)) {
432 $metadata[
'dol_type'] = $object->element;
433 $metadata[
'dol_id'] = $object->id;
434 if (is_object($object->thirdparty) && $object->thirdparty->id > 0) {
435 $metadata[
'dol_thirdparty_id'] = $object->thirdparty->id;
440 $paymentmethodtypes = array(
"card");
441 $descriptor =
dol_trunc($tag, 10,
'right',
'UTF-8', 1);
443 $paymentmethodtypes[] =
"sepa_debit";
447 $paymentmethodtypes[] =
"klarna";
450 $paymentmethodtypes[] =
"bancontact";
453 $paymentmethodtypes[] =
"ideal";
456 $paymentmethodtypes[] =
"giropay";
459 $paymentmethodtypes[] =
"sofort";
462 $paymentmethodtypes = array(
"card_present");
465 $dataforintent = array(
466 "confirm" => $confirmnow,
467 "confirmation_method" => $mode,
468 "amount" => $stripeamount,
469 "currency" => $currency_code,
470 "payment_method_types" => $paymentmethodtypes,
471 "description" => $description,
473 "setup_future_usage" =>
"on_session",
474 "metadata" => $metadata
477 $dataforintent[
"statement_descriptor_suffix"] = $descriptor;
478 $dataforintent[
"statement_descriptor"] = $descriptor;
480 if (!is_null($customer)) {
481 $dataforintent[
"customer"] = $customer;
487 unset($dataforintent[
'setup_future_usage']);
491 $dataforintent[
"off_session"] =
true;
494 unset($dataforintent[
'setup_future_usage']);
497 unset($dataforintent[
'setup_future_usage']);
500 unset($dataforintent[
'setup_future_usage']);
501 $dataforintent[
"capture_method"] =
"manual";
502 $dataforintent[
"confirmation_method"] =
"manual";
504 if (!is_null($payment_method)) {
505 $dataforintent[
"payment_method"] = $payment_method;
506 $description .=
' - '.$payment_method;
509 if ($conf->entity !=
getDolGlobalInt(
'STRIPECONNECT_PRINCIPAL') && $stripefee > 0) {
510 $dataforintent[
"application_fee_amount"] = $stripefee;
512 if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email) {
513 $dataforintent[
"receipt_email"] = $object->thirdparty->email;
518 global $stripearrayofkeysbyenv;
519 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
521 $arrayofoptions = array();
522 if (empty($noidempotency_key)) {
523 $arrayofoptions[
"idempotency_key"] = $description;
527 $arrayofoptions[
"stripe_account"] = $key;
530 dol_syslog(
"dataforintent to create paymentintent = ".var_export($dataforintent,
true));
532 $paymentintent = \Stripe\PaymentIntent::create($dataforintent, $arrayofoptions);
535 if (is_object($object)) {
536 $paymentintentalreadyexists = 0;
540 dol_syslog(get_class($this).
"::getPaymentIntent search if payment intent already in prelevement_demande", LOG_DEBUG);
542 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"prelevement_demande SET";
543 $sql .=
" ext_payment_site = '".$this->db->escape($service).
"',";
544 $sql .=
" ext_payment_id = '".$this->db->escape($paymentintent->id).
"'";
545 $sql .=
" WHERE rowid = ".((int) $did);
547 $resql = $this->db->query(
$sql);
549 $paymentintentalreadyexists++;
556 dol_syslog(get_class($this).
"::getPaymentIntent search if payment intent already in prelevement_demande", LOG_DEBUG);
558 $sql =
"SELECT pi.rowid";
559 $sql .=
" FROM ".MAIN_DB_PREFIX.
"prelevement_demande as pi";
560 $sql .=
" WHERE pi.entity IN (".getEntity(
'societe').
")";
561 $sql .=
" AND pi.ext_payment_site = '".$this->db->escape($service).
"'";
562 $sql .=
" AND pi.ext_payment_id = '".$this->db->escape($paymentintent->id).
"'";
564 $resql = $this->db->query(
$sql);
566 $num = $this->db->num_rows($resql);
568 $obj = $this->db->fetch_object($resql);
570 $paymentintentalreadyexists++;
580 if (!$error && !$paymentintentalreadyexists) {
582 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"prelevement_demande (date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site, amount)";
583 $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).
")";
584 $resql = $this->db->query(
$sql);
587 $this->error = $this->db->lasterror();
588 dol_syslog(get_class($this).
"::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id.
" into database.", LOG_ERR);
592 $_SESSION[
"stripe_payment_intent"] = $paymentintent;
594 }
catch (
Stripe\Error\Card $e) {
596 $this->error = $e->getMessage();
597 $this->
code = $e->getStripeCode();
598 $this->declinecode = $e->getDeclineCode();
607 $this->error = $e->getMessage();
609 $this->declinecode =
'';
613 dol_syslog(get_class($this).
"::getPaymentIntent return error=".$error.
" this->error=".$this->error, LOG_INFO, -1);
616 return $paymentintent;
640 public function getSetupIntent($description, $object, $customer, $key, $status, $usethirdpartyemailforreceiptemail = 0, $confirmnow =
false)
644 dol_syslog(
"getSetupIntent description=".$description.
' confirmnow='.$confirmnow, LOG_INFO, 1);
648 if (empty($status)) {
649 $service =
'StripeTest';
651 $service =
'StripeLive';
656 if (empty($setupintent)) {
658 $metadata = array(
'dol_version'=>DOL_VERSION,
'dol_entity'=>$conf->entity,
'ipaddress'=>$ipaddress);
659 if (is_object($object)) {
660 $metadata[
'dol_type'] = $object->element;
661 $metadata[
'dol_id'] = $object->id;
662 if (is_object($object->thirdparty) && $object->thirdparty->id > 0) {
663 $metadata[
'dol_thirdparty_id'] = $object->thirdparty->id;
668 $paymentmethodtypes = array(
"card");
669 if (!empty($conf->global->STRIPE_SEPA_DIRECT_DEBIT)) {
670 $paymentmethodtypes[] =
"sepa_debit";
672 if (!empty($conf->global->STRIPE_BANCONTACT)) {
673 $paymentmethodtypes[] =
"bancontact";
675 if (!empty($conf->global->STRIPE_IDEAL)) {
676 $paymentmethodtypes[] =
"ideal";
679 if (!empty($conf->global->STRIPE_SOFORT)) {
680 $paymentmethodtypes[] =
"sofort";
683 $dataforintent = array(
684 "confirm" => $confirmnow,
685 "payment_method_types" => $paymentmethodtypes,
686 "usage" =>
"off_session",
687 "metadata" => $metadata
689 if (!is_null($customer)) {
690 $dataforintent[
"customer"] = $customer;
692 if (!is_null($description)) {
693 $dataforintent[
"description"] = $description;
699 if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email) {
700 $dataforintent[
"receipt_email"] = $object->thirdparty->email;
705 global $stripearrayofkeysbyenv;
706 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
708 dol_syslog(
"getSetupIntent ".$stripearrayofkeysbyenv[$status][
'publishable_key'], LOG_DEBUG);
713 $setupintent = \Stripe\SetupIntent::create($dataforintent, array());
716 $setupintent = \Stripe\SetupIntent::create($dataforintent, array(
"stripe_account" => $key));
769 $this->error = $e->getMessage();
774 dol_syslog(
"getSetupIntent ".(is_object($setupintent) ? $setupintent->id :
''), LOG_INFO, -1);
777 dol_syslog(
"getSetupIntent return error=".$error, LOG_INFO, -1);
795 global $conf, $user, $langs;
799 $sql =
"SELECT sa.stripe_card_ref, sa.proprio, sa.exp_date_month, sa.exp_date_year, sa.number, sa.cvn";
800 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe_rib as sa";
801 $sql .=
" WHERE sa.rowid = ".((int) $object->id);
802 $sql .=
" AND sa.type = 'card'";
804 dol_syslog(get_class($this).
"::cardStripe search stripe card id for paymentmode id=".$object->id.
", stripeacc=".$stripeacc.
", status=".$status.
", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
805 $resql = $this->db->query(
$sql);
807 $num = $this->db->num_rows($resql);
809 $obj = $this->db->fetch_object($resql);
810 $cardref = $obj->stripe_card_ref;
811 dol_syslog(get_class($this).
"::cardStripe cardref=".$cardref);
814 if (empty($stripeacc)) {
815 if (!preg_match(
'/^pm_/', $cardref) && !empty($cu->sources)) {
816 $card = $cu->sources->retrieve($cardref);
818 $card = \Stripe\PaymentMethod::retrieve($cardref);
821 if (!preg_match(
'/^pm_/', $cardref) && !empty($cu->sources)) {
823 $card = $cu->sources->retrieve($cardref);
826 $card = \Stripe\PaymentMethod::retrieve($cardref);
830 $this->error = $e->getMessage();
833 } elseif ($createifnotlinkedtostripe) {
835 $exp_date_month = $obj->exp_date_month;
836 $exp_date_year = $obj->exp_date_year;
837 $number = $obj->number;
839 $cardholdername = $obj->proprio;
843 $dataforcard = array(
846 'exp_month'=>$exp_date_month,
847 'exp_year'=>$exp_date_year,
850 'name'=>$cardholdername
853 'dol_type'=>$object->element,
854 'dol_id'=>$object->id,
855 'dol_version'=>DOL_VERSION,
856 'dol_entity'=>$conf->entity,
857 'ipaddress'=>$ipaddress
865 if (empty($stripeacc)) {
866 if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) {
867 dol_syslog(
"Try to create card with dataforcard = ".json_encode($dataforcard));
868 $card = $cu->sources->create($dataforcard);
870 $this->error =
'Creation of card on Stripe has failed';
874 if (!empty($stripeacc)) {
875 $connect = $stripeacc.
'/';
877 $url =
'https://dashboard.stripe.com/'.$connect.
'test/customers/'.$cu->id;
879 $url =
'https://dashboard.stripe.com/'.$connect.
'customers/'.$cu->id;
881 $urtoswitchonstripe =
' <a href="'.$url.
'" target="_stripe">'.
img_picto($langs->trans(
'ShowInStripe'),
'globe').
'</a>';
884 $this->error = $langs->trans(
'CreationOfPaymentModeMustBeDoneFromStripeInterface', $urtoswitchonstripe);
887 if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) {
888 dol_syslog(
"Try to create card with dataforcard = ".json_encode($dataforcard));
889 $card = $cu->sources->create($dataforcard, array(
"stripe_account" => $stripeacc));
891 $this->error =
'Creation of card on Stripe has failed';
895 if (!empty($stripeacc)) {
896 $connect = $stripeacc.
'/';
898 $url =
'https://dashboard.stripe.com/'.$connect.
'test/customers/'.$cu->id;
900 $url =
'https://dashboard.stripe.com/'.$connect.
'customers/'.$cu->id;
902 $urtoswitchonstripe =
' <a href="'.$url.
'" target="_stripe">'.
img_picto($langs->trans(
'ShowInStripe'),
'globe').
'</a>';
905 $this->error = $langs->trans(
'CreationOfPaymentModeMustBeDoneFromStripeInterface', $urtoswitchonstripe);
910 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"societe_rib";
911 $sql .=
" SET stripe_card_ref = '".$this->db->escape($card->id).
"', card_type = '".$this->db->escape($card->brand).
"',";
912 $sql .=
" country_code = '".$this->db->escape($card->country).
"',";
913 $sql .=
" approved = ".($card->cvc_check ==
'pass' ? 1 : 0);
914 $sql .=
" WHERE rowid = ".((int) $object->id);
915 $sql .=
" AND type = 'card'";
916 $resql = $this->db->query(
$sql);
918 $this->error = $this->db->lasterror();
922 $this->error = $e->getMessage();
947 global $conf, $user, $langs;
950 $sql =
"SELECT sa.stripe_card_ref, sa.proprio, sa.iban_prefix as iban, sa.rum";
951 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe_rib as sa";
952 $sql .=
" WHERE sa.rowid = ".((int) $object->id);
953 $sql .=
" AND sa.type = 'ban'";
956 $soc->fetch($object->fk_soc);
958 dol_syslog(get_class($this).
"::sepaStripe search stripe ban id for paymentmode id=".$object->id.
", stripeacc=".$stripeacc.
", status=".$status.
", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
959 $resql = $this->db->query(
$sql);
961 $num = $this->db->num_rows($resql);
963 $obj = $this->db->fetch_object($resql);
964 $cardref = $obj->stripe_card_ref;
965 dol_syslog(get_class($this).
"::sepaStripe cardref=".$cardref);
968 if (empty($stripeacc)) {
969 if (!preg_match(
'/^pm_/', $cardref) && !empty($cu->sources)) {
970 $sepa = $cu->sources->retrieve($cardref);
972 $sepa = \Stripe\PaymentMethod::retrieve($cardref);
975 if (!preg_match(
'/^pm_/', $cardref) && !empty($cu->sources)) {
977 $sepa = $cu->sources->retrieve($cardref);
980 $sepa = \Stripe\PaymentMethod::retrieve($cardref);
984 $this->error = $e->getMessage();
987 } elseif ($createifnotlinkedtostripe) {
990 $metadata = array(
'dol_version'=>DOL_VERSION,
'dol_entity'=>$conf->entity,
'ipaddress'=>$ipaddress);
991 if (is_object($object)) {
992 $metadata[
'dol_type'] = $object->element;
993 $metadata[
'dol_id'] = $object->id;
994 $metadata[
'dol_thirdparty_id'] = $soc->id;
997 $description =
'SEPA for IBAN '.$iban;
999 $dataforcard = array(
1000 'type'=>
'sepa_debit',
1001 "sepa_debit" => array(
'iban' => $iban),
1002 'billing_details' => array(
1003 'name' => $soc->name,
1004 'email' => !empty($soc->email) ? $soc->email :
"",
1006 "metadata" => $metadata
1009 if (!empty($soc->town)) {
1010 $dataforcard[
'billing_details'][
'address'][
'city']=$soc->town;
1012 if (!empty($soc->country_code)) {
1013 $dataforcard[
'billing_details'][
'address'][
'country']=$soc->country_code;
1015 if (!empty($soc->address)) {
1016 $dataforcard[
'billing_details'][
'address'][
'line1']=$soc->address;
1018 if (!empty($soc->zip)) {
1019 $dataforcard[
'billing_details'][
'address'][
'postal_code']=$soc->zip;
1021 if (!empty($soc->state)) {
1022 $dataforcard[
'billing_details'][
'address'][
'state']=$soc->state;
1030 $service =
'StripeTest';
1032 if (!empty($conf->global->STRIPE_LIVE) && !
GETPOST(
'forcesandbox',
'alpha')) {
1033 $service =
'StripeLive';
1037 global $stripearrayofkeysbyenv;
1038 $stripeacc = $stripearrayofkeysbyenv[$servicestatus][
'secret_key'];
1040 dol_syslog(
"Try to create sepa_debit with data = ".json_encode($dataforcard));
1042 $s = new \Stripe\StripeClient($stripeacc);
1046 $sepa = $s->paymentMethods->create($dataforcard);
1048 $this->error =
'Creation of payment method sepa_debit on Stripe has failed';
1052 $dataforintent = array([
'description'=> $description,
'payment_method_types' => [
'sepa_debit'],
'customer' => $cu->id,
'payment_method' => $sepa->id],
'metadata'=>$metadata);
1053 $cs = $s->setupIntents->create($dataforintent);
1055 $cs = $s->setupIntents->confirm($cs->id, [
'mandate_data' => [
'customer_acceptance' => [
'type' =>
'offline']]]);
1057 $this->error =
'Link SEPA <-> Customer failed';
1059 dol_syslog(
"Update the payment mode of the customer");
1063 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"societe_rib";
1064 $sql .=
" SET stripe_card_ref = '".$this->db->escape($sepa->id).
"', card_type = 'sepa_debit',";
1065 $sql .=
" stripe_account= '" . $this->db->escape($cu->id .
"@" . $stripeacc) .
"'";
1066 $sql .=
" WHERE rowid = ".((int) $object->id);
1067 $sql .=
" AND type = 'ban'";
1068 $resql = $this->db->query(
$sql);
1070 $this->error = $this->db->lasterror();
1076 $this->error = $e->getMessage();
1105 public function createPaymentStripe($amount, $currency, $origin, $item, $source, $customer, $account, $status = 0, $usethirdpartyemailforreceiptemail = 0, $capture =
true)
1111 if (empty($status)) {
1112 $service =
'StripeTest';
1114 $service =
'StripeLive';
1117 $sql =
"SELECT sa.key_account as key_account, sa.fk_soc, sa.entity";
1118 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe_account as sa";
1119 $sql .=
" WHERE sa.key_account = '".$this->db->escape($customer).
"'";
1121 $sql .=
" AND sa.site = 'stripe' AND sa.status = ".((int) $status);
1123 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1124 $result = $this->db->query(
$sql);
1126 if ($this->db->num_rows($result)) {
1127 $obj = $this->db->fetch_object($result);
1128 $key = $obj->fk_soc;
1136 $arrayzerounitcurrency = array(
'BIF',
'CLP',
'DJF',
'GNF',
'JPY',
'KMF',
'KRW',
'MGA',
'PYG',
'RWF',
'VND',
'VUV',
'XAF',
'XOF',
'XPF');
1137 if (!in_array($currency, $arrayzerounitcurrency)) {
1138 $stripeamount = $amount * 100;
1140 $stripeamount = $amount;
1143 $societe =
new Societe($this->db);
1145 $societe->fetch($key);
1150 if ($origin ==
'order') {
1152 $order->fetch($item);
1154 $description =
"ORD=".$ref.
".CUS=".$societe->id.
".PM=stripe";
1155 } elseif ($origin ==
'invoice') {
1156 $invoice =
new Facture($this->db);
1157 $invoice->fetch($item);
1158 $ref = $invoice->ref;
1159 $description =
"INV=".$ref.
".CUS=".$societe->id.
".PM=stripe";
1165 "dol_id" => (
string) $item,
1166 "dol_type" => (
string) $origin,
1167 "dol_thirdparty_id" => (
string) $societe->id,
1168 'dol_thirdparty_name' => $societe->name,
1169 'dol_version' => DOL_VERSION,
1170 'dol_entity' => $conf->entity,
1171 'ipaddress' => $ipaddress
1173 $return =
new Stripe($this->db);
1176 global $stripearrayofkeysbyenv;
1177 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status][
'secret_key']);
1179 if (empty($conf->stripeconnect->enabled)) {
1180 if (preg_match(
'/pm_/i', $source)) {
1181 $stripecard = $source;
1182 $amountstripe = $stripeamount;
1185 $amounttopay = $amount;
1186 $servicestatus = $status;
1188 dol_syslog(
"* createPaymentStripe get stripeacc", LOG_DEBUG);
1189 $stripeacc = $stripe->getStripeAccount($service);
1191 dol_syslog(
"* createPaymentStripe Create payment for customer ".$customer->id.
" on source card ".$stripecard->id.
", amounttopay=".$amounttopay.
", amountstripe=".$amountstripe.
", FULLTAG=".$FULLTAG, LOG_DEBUG);
1194 $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $invoice, $customer->id, $stripeacc, $servicestatus, 0,
'automatic',
true, $stripecard->id, 1);
1196 $charge =
new stdClass();
1197 if ($paymentintent->status ==
'succeeded') {
1198 $charge->status =
'ok';
1200 $charge->status =
'failed';
1201 $charge->failure_code = $stripe->code;
1202 $charge->failure_message = $stripe->error;
1203 $charge->failure_declinecode = $stripe->declinecode;
1204 $stripefailurecode = $stripe->code;
1205 $stripefailuremessage = $stripe->error;
1206 $stripefailuredeclinecode = $stripe->declinecode;
1208 } elseif (preg_match(
'/acct_/i', $source)) {
1209 $charge = \Stripe\Charge::create(array(
1210 "amount" =>
"$stripeamount",
1211 "currency" =>
"$currency",
1212 "statement_descriptor_suffix" =>
dol_trunc($description, 10,
'right',
'UTF-8', 1),
1213 "description" =>
"Stripe payment: ".$description,
1214 "capture" => $capture,
1215 "metadata" => $metadata,
1216 "source" =>
"$source"
1219 $paymentarray = array(
1220 "amount" =>
"$stripeamount",
1221 "currency" =>
"$currency",
1222 "statement_descriptor_suffix" =>
dol_trunc($description, 10,
'right',
'UTF-8', 1),
1223 "description" =>
"Stripe payment: ".$description,
1224 "capture" => $capture,
1225 "metadata" => $metadata,
1226 "source" =>
"$source",
1227 "customer" =>
"$customer"
1230 if ($societe->email && $usethirdpartyemailforreceiptemail) {
1231 $paymentarray[
"receipt_email"] = $societe->email;
1234 $charge = \Stripe\Charge::create($paymentarray, array(
"idempotency_key" =>
"$description"));
1238 $fee = $amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE;
1239 if ($fee >= $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL > $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
1240 $fee = $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL;
1241 } elseif ($fee < $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
1242 $fee = $conf->global->STRIPE_APPLICATION_FEE_MINIMAL;
1245 if (!in_array($currency, $arrayzerounitcurrency)) {
1246 $stripefee = round($fee * 100);
1248 $stripefee = round($fee);
1251 $paymentarray = array(
1252 "amount" =>
"$stripeamount",
1253 "currency" =>
"$currency",
1254 "statement_descriptor_suffix" =>
dol_trunc($description, 10,
'right',
'UTF-8', 1),
1255 "description" =>
"Stripe payment: ".$description,
1256 "capture" => $capture,
1257 "metadata" => $metadata,
1258 "source" =>
"$source",
1259 "customer" =>
"$customer"
1261 if ($conf->entity != $conf->global->STRIPECONNECT_PRINCIPAL && $stripefee > 0) {
1262 $paymentarray[
"application_fee_amount"] = $stripefee;
1264 if ($societe->email && $usethirdpartyemailforreceiptemail) {
1265 $paymentarray[
"receipt_email"] = $societe->email;
1268 if (preg_match(
'/pm_/i', $source)) {
1269 $stripecard = $source;
1270 $amountstripe = $stripeamount;
1273 $amounttopay = $amount;
1274 $servicestatus = $status;
1276 dol_syslog(
"* createPaymentStripe get stripeacc", LOG_DEBUG);
1277 $stripeacc = $stripe->getStripeAccount($service);
1279 dol_syslog(
"* createPaymentStripe Create payment on card ".$stripecard->id.
", amounttopay=".$amounttopay.
", amountstripe=".$amountstripe.
", FULLTAG=".$FULLTAG, LOG_DEBUG);
1282 $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $invoice, $customer->id, $stripeacc, $servicestatus, 0,
'automatic',
true, $stripecard->id, 1);
1284 $charge =
new stdClass();
1285 if ($paymentintent->status ==
'succeeded') {
1286 $charge->status =
'ok';
1287 $charge->id = $paymentintent->id;
1289 $charge->status =
'failed';
1290 $charge->failure_code = $stripe->code;
1291 $charge->failure_message = $stripe->error;
1292 $charge->failure_declinecode = $stripe->declinecode;
1295 $charge = \Stripe\Charge::create($paymentarray, array(
"idempotency_key" =>
"$description",
"stripe_account" =>
"$account"));
1298 if (isset($charge->id)) {
1301 $return->statut =
'success';
1302 $return->id = $charge->id;
1304 if (preg_match(
'/pm_/i', $source)) {
1305 $return->message =
'Payment retrieved by card status = '.$charge->status;
1307 if ($charge->source->type ==
'card') {
1308 $return->message = $charge->source->card->brand.
" ....".$charge->source->card->last4;
1309 } elseif ($charge->source->type ==
'three_d_secure') {
1310 $stripe =
new Stripe($this->db);
1311 $src = \Stripe\Source::retrieve(
"".$charge->source->three_d_secure->card, array(
1312 "stripe_account" => $stripe->getStripeAccount($service)
1314 $return->message = $src->card->brand.
" ....".$src->card->last4;
1316 $return->message = $charge->id;
1319 }
catch (\
Stripe\Error\Card $e) {
1320 include DOL_DOCUMENT_ROOT.
'/core/class/CMailFile.class.php';
1322 $body = $e->getJsonBody();
1323 $err = $body[
'error'];
1325 $return->statut =
'error';
1326 $return->id = $err[
'charge'];
1327 $return->type = $err[
'type'];
1328 $return->code = $err[
'code'];
1329 $return->message = $err[
'message'];
1330 $body =
"Error: <br>".$return->id.
" ".$return->message.
" ";
1331 $subject =
'[Alert] Payment error using Stripe';
1332 $cmailfile =
new CMailFile($subject, $conf->global->ONLINE_PAYMENT_SENDEMAIL, $conf->global->MAIN_INFO_SOCIETE_MAIL, $body);
1333 $cmailfile->sendfile();
1336 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1337 }
catch (\
Stripe\Error\RateLimit $e) {
1340 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1341 }
catch (\
Stripe\Error\InvalidRequest $e) {
1344 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1345 }
catch (\
Stripe\Error\Authentication $e) {
1349 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1350 }
catch (\
Stripe\Error\ApiConnection $e) {
1353 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1354 }
catch (\
Stripe\Error\Base $e) {
1358 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');
1362 dol_syslog($e->getMessage(), LOG_WARNING, 0,
'_stripe');