| Total Complexity | 178 |
| Total Lines | 1303 |
| Duplicated Lines | 0 % |
| Changes | 3 | ||
| Bugs | 0 | Features | 0 |
Complex classes like Stripe often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Stripe, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 29 | class Stripe extends CommonObject |
||
| 30 | { |
||
| 31 | /** |
||
| 32 | * @var int ID |
||
| 33 | */ |
||
| 34 | public $rowid; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * @var int Thirdparty ID |
||
| 38 | */ |
||
| 39 | public $fk_soc; |
||
| 40 | |||
| 41 | /** |
||
| 42 | * @var int ID |
||
| 43 | */ |
||
| 44 | public $fk_key; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * @var int ID |
||
| 48 | */ |
||
| 49 | public $id; |
||
| 50 | |||
| 51 | public $mode; |
||
| 52 | |||
| 53 | /** |
||
| 54 | * @var int Entity |
||
| 55 | */ |
||
| 56 | public $entity; |
||
| 57 | |||
| 58 | public $statut; |
||
| 59 | |||
| 60 | public $type; |
||
| 61 | |||
| 62 | public $code; |
||
| 63 | public $declinecode; |
||
| 64 | |||
| 65 | /** |
||
| 66 | * @var string Message |
||
| 67 | */ |
||
| 68 | public $message; |
||
| 69 | |||
| 70 | /** |
||
| 71 | * Constructor |
||
| 72 | * |
||
| 73 | * @param DoliDB $db Database handler |
||
| 74 | */ |
||
| 75 | public function __construct($db) |
||
| 78 | } |
||
| 79 | |||
| 80 | |||
| 81 | /** |
||
| 82 | * Return main company OAuth Connect stripe account |
||
| 83 | * |
||
| 84 | * @param string $mode 'StripeTest' or 'StripeLive' |
||
| 85 | * @param int $fk_soc Id of thirdparty |
||
| 86 | * @param int $entity Id of entity (-1 = current environment) |
||
| 87 | * @return string Stripe account 'acc_....' or '' if no OAuth token found |
||
| 88 | */ |
||
| 89 | public function getStripeAccount($mode = 'StripeTest', $fk_soc = 0, $entity = -1) |
||
| 90 | { |
||
| 91 | global $conf; |
||
| 92 | |||
| 93 | $key = ''; |
||
| 94 | if ($entity < 0) { |
||
| 95 | $entity = $conf->entity; |
||
| 96 | } |
||
| 97 | |||
| 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); |
||
| 102 | if ($fk_soc > 0) { |
||
| 103 | $sql .= " AND fk_soc = ".((int) $fk_soc); |
||
| 104 | } else { |
||
| 105 | $sql .= " AND fk_soc IS NULL"; |
||
| 106 | } |
||
| 107 | $sql .= " AND fk_user IS NULL AND fk_adherent IS NULL"; |
||
| 108 | |||
| 109 | dol_syslog(get_class($this)."::getStripeAccount", LOG_DEBUG); |
||
| 110 | |||
| 111 | $result = $this->db->query($sql); |
||
| 112 | if ($result) { |
||
| 113 | if ($this->db->num_rows($result)) { |
||
| 114 | $obj = $this->db->fetch_object($result); |
||
| 115 | $tokenstring = $obj->tokenstring; |
||
| 116 | |||
| 117 | $tmparray = json_decode($tokenstring); |
||
| 118 | $key = empty($tmparray->stripe_user_id) ? '' : $tmparray->stripe_user_id; |
||
| 119 | } else { |
||
| 120 | $tokenstring = ''; |
||
| 121 | } |
||
| 122 | } else { |
||
| 123 | dol_print_error($this->db); |
||
| 124 | } |
||
| 125 | |||
| 126 | dol_syslog("No dedicated Stripe Connect account available for entity ".$conf->entity); |
||
| 127 | return $key; |
||
| 128 | } |
||
| 129 | |||
| 130 | /** |
||
| 131 | * getStripeCustomerAccount |
||
| 132 | * |
||
| 133 | * @param int $id Id of third party |
||
| 134 | * @param int $status Status |
||
| 135 | * @param string $site_account Value to use to identify with account to use on site when site can offer several accounts. For example: 'pk_live_123456' when using Stripe service. |
||
| 136 | * @return string Stripe customer ref 'cu_xxxxxxxxxxxxx' or '' |
||
| 137 | */ |
||
| 138 | public function getStripeCustomerAccount($id, $status = 0, $site_account = '') |
||
| 139 | { |
||
| 140 | include_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php'; |
||
| 141 | $societeaccount = new SocieteAccount($this->db); |
||
| 142 | return $societeaccount->getCustomerAccount($id, 'stripe', $status, $site_account); // Get thirdparty cus_... |
||
| 143 | } |
||
| 144 | |||
| 145 | |||
| 146 | /** |
||
| 147 | * Get the Stripe customer of a thirdparty (with option to create it in Stripe if not linked yet). |
||
| 148 | * Search on site_account = 0 or = $stripearrayofkeysbyenv[$status]['publishable_key'] |
||
| 149 | * |
||
| 150 | * @param Societe $object Object thirdparty to check, or create on stripe (create on stripe also update the stripe_account table for current entity) |
||
| 151 | * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 152 | * @param int $status Status (0=test, 1=live) |
||
| 153 | * @param int $createifnotlinkedtostripe 1=Create the stripe customer and the link if the thirdparty is not yet linked to a stripe customer |
||
| 154 | * @return \Stripe\StripeCustomer|null Stripe Customer or null if not found |
||
|
|
|||
| 155 | */ |
||
| 156 | public function customerStripe(Societe $object, $key = '', $status = 0, $createifnotlinkedtostripe = 0) |
||
| 263 | } |
||
| 264 | |||
| 265 | /** |
||
| 266 | * Get the Stripe payment method Object from its ID |
||
| 267 | * |
||
| 268 | * @param string $paymentmethod Payment Method ID |
||
| 269 | * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 270 | * @param int $status Status (0=test, 1=live) |
||
| 271 | * @return \Stripe\PaymentMethod|null Stripe PaymentMethod or null if not found |
||
| 272 | */ |
||
| 273 | public function getPaymentMethodStripe($paymentmethod, $key = '', $status = 0) |
||
| 291 | } |
||
| 292 | |||
| 293 | /** |
||
| 294 | * Get the Stripe reader Object from its ID |
||
| 295 | * |
||
| 296 | * @param string $reader Reader ID |
||
| 297 | * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 298 | * @param int $status Status (0=test, 1=live) |
||
| 299 | * @return \Stripe\Terminal\Reader|null Stripe Reader or null if not found |
||
| 300 | */ |
||
| 301 | public function getSelectedReader($reader, $key = '', $status = 0) |
||
| 319 | } |
||
| 320 | |||
| 321 | /** |
||
| 322 | * Get the Stripe payment intent. Create it with confirmnow=false |
||
| 323 | * Warning. If a payment was tried and failed, a payment intent was created. |
||
| 324 | * But if we change something on object to pay (amount or other), reusing same payment intent is not allowed by Stripe. |
||
| 325 | * Recommended solution is to recreate a new payment intent each time we need one (old one will be automatically closed after a delay), |
||
| 326 | * that's why i comment the part of code to retrieve a payment intent with object id (never mind if we cumulate payment intent with old ones that will not be used) |
||
| 327 | * Note: This is used when option STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is on when making a payment from the public/payment/newpayment.php page |
||
| 328 | * but not when using the STRIPE_USE_NEW_CHECKOUT. |
||
| 329 | * |
||
| 330 | * @param double $amount Amount |
||
| 331 | * @param string $currency_code Currency code |
||
| 332 | * @param string $tag Tag |
||
| 333 | * @param string $description Description |
||
| 334 | * @param mixed $object Object to pay with Stripe |
||
| 335 | * @param string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() |
||
| 336 | * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 337 | * @param int $status Status (0=test, 1=live) |
||
| 338 | * @param int $usethirdpartyemailforreceiptemail 1=use thirdparty email for receipt |
||
| 339 | * @param int $mode automatic=automatic confirmation/payment when conditions are ok, manual=need to call confirm() on intent |
||
| 340 | * @param boolean $confirmnow false=default, true=try to confirm immediatly after create (if conditions are ok) |
||
| 341 | * @param string $payment_method 'pm_....' (if known) |
||
| 342 | * @param string $off_session If we use an already known payment method to pay when customer is not available during the checkout flow. |
||
| 343 | * @param string $noidempotency_key Do not use the idempotency_key when creating the PaymentIntent |
||
| 344 | * @return \Stripe\PaymentIntent|null Stripe PaymentIntent or null if not found and failed to create |
||
| 345 | */ |
||
| 346 | 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) |
||
| 347 | { |
||
| 348 | global $conf, $user; |
||
| 349 | |||
| 350 | dol_syslog(get_class($this)."::getPaymentIntent", LOG_INFO, 1); |
||
| 351 | |||
| 352 | $error = 0; |
||
| 353 | |||
| 354 | if (empty($status)) { |
||
| 355 | $service = 'StripeTest'; |
||
| 356 | } else { |
||
| 357 | $service = 'StripeLive'; |
||
| 358 | } |
||
| 359 | |||
| 360 | $arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'); |
||
| 361 | if (!in_array($currency_code, $arrayzerounitcurrency)) { |
||
| 362 | $stripeamount = $amount * 100; |
||
| 363 | } else { |
||
| 364 | $stripeamount = $amount; |
||
| 365 | } |
||
| 366 | |||
| 367 | $fee = $amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE; |
||
| 368 | if ($fee >= $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL > $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) { |
||
| 369 | $fee = $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL; |
||
| 370 | } elseif ($fee < $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) { |
||
| 371 | $fee = $conf->global->STRIPE_APPLICATION_FEE_MINIMAL; |
||
| 372 | } |
||
| 373 | if (!in_array($currency_code, $arrayzerounitcurrency)) { |
||
| 374 | $stripefee = round($fee * 100); |
||
| 375 | } else { |
||
| 376 | $stripefee = round($fee); |
||
| 377 | } |
||
| 378 | |||
| 379 | $paymentintent = null; |
||
| 380 | |||
| 381 | if (is_object($object) && getDolGlobalInt('STRIPE_REUSE_EXISTING_INTENT_IF_FOUND') && !getDolGlobalInt('STRIPE_CARD_PRESENT')) { |
||
| 382 | // Warning. If a payment was tried and failed, a payment intent was created. |
||
| 383 | // But if we change something on object to pay (amount or other that does not change the idempotency key), reusing same payment intent is not allowed by Stripe. |
||
| 384 | // Recommended solution is to recreate a new payment intent each time we need one (old one will be automatically closed by Stripe after a delay), Stripe will |
||
| 385 | // automatically return the existing payment intent if idempotency is provided when we try to create the new one. |
||
| 386 | // That's why we can comment the part of code to retrieve a payment intent with object id (never mind if we cumulate payment intent with old ones that will not be used) |
||
| 387 | |||
| 388 | $sql = "SELECT pi.ext_payment_id, pi.entity, pi.fk_facture, pi.sourcetype, pi.ext_payment_site"; |
||
| 389 | $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pi"; |
||
| 390 | $sql .= " WHERE pi.fk_facture = ".((int) $object->id); |
||
| 391 | $sql .= " AND pi.sourcetype = '".$this->db->escape($object->element)."'"; |
||
| 392 | $sql .= " AND pi.entity IN (".getEntity('societe').")"; |
||
| 393 | $sql .= " AND pi.ext_payment_site = '".$this->db->escape($service)."'"; |
||
| 394 | |||
| 395 | dol_syslog(get_class($this)."::getPaymentIntent search stripe payment intent for object id = ".$object->id, LOG_DEBUG); |
||
| 396 | $resql = $this->db->query($sql); |
||
| 397 | if ($resql) { |
||
| 398 | $num = $this->db->num_rows($resql); |
||
| 399 | if ($num) { |
||
| 400 | $obj = $this->db->fetch_object($resql); |
||
| 401 | $intent = $obj->ext_payment_id; |
||
| 402 | |||
| 403 | dol_syslog(get_class($this)."::getPaymentIntent found existing payment intent record"); |
||
| 404 | |||
| 405 | // Force to use the correct API key |
||
| 406 | global $stripearrayofkeysbyenv; |
||
| 407 | \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']); |
||
| 408 | |||
| 409 | try { |
||
| 410 | if (empty($key)) { // If the Stripe connect account not set, we use common API usage |
||
| 411 | $paymentintent = \Stripe\PaymentIntent::retrieve($intent); |
||
| 412 | } else { |
||
| 413 | $paymentintent = \Stripe\PaymentIntent::retrieve($intent, array("stripe_account" => $key)); |
||
| 414 | } |
||
| 415 | } catch (Exception $e) { |
||
| 416 | $error++; |
||
| 417 | $this->error = $e->getMessage(); |
||
| 418 | } |
||
| 419 | } |
||
| 420 | } |
||
| 421 | } |
||
| 422 | |||
| 423 | if (empty($paymentintent)) { |
||
| 424 | // Try to create intent. See https://stripe.com/docs/api/payment_intents/create |
||
| 425 | $ipaddress = getUserRemoteIP(); |
||
| 426 | $metadata = array('dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress); |
||
| 427 | if (is_object($object)) { |
||
| 428 | $metadata['dol_type'] = $object->element; |
||
| 429 | $metadata['dol_id'] = $object->id; |
||
| 430 | if (is_object($object->thirdparty) && $object->thirdparty->id > 0) { |
||
| 431 | $metadata['dol_thirdparty_id'] = $object->thirdparty->id; |
||
| 432 | } |
||
| 433 | } |
||
| 434 | |||
| 435 | // list of payment method types |
||
| 436 | $paymentmethodtypes = array("card"); |
||
| 437 | $descriptor = dol_trunc($tag, 10, 'right', 'UTF-8', 1); |
||
| 438 | if (getDolGlobalInt('STRIPE_SEPA_DIRECT_DEBIT')) { |
||
| 439 | $paymentmethodtypes[] = "sepa_debit"; //&& ($object->thirdparty->isInEEC()) |
||
| 440 | //$descriptor = preg_replace('/ref=[^:=]+/', '', $descriptor); // Clean ref |
||
| 441 | } |
||
| 442 | if (getDolGlobalInt('STRIPE_KLARNA')) { |
||
| 443 | $paymentmethodtypes[] = "klarna"; |
||
| 444 | } |
||
| 445 | if (getDolGlobalInt('STRIPE_BANCONTACT')) { |
||
| 446 | $paymentmethodtypes[] = "bancontact"; |
||
| 447 | } |
||
| 448 | if (getDolGlobalInt('STRIPE_IDEAL')) { |
||
| 449 | $paymentmethodtypes[] = "ideal"; |
||
| 450 | } |
||
| 451 | if (getDolGlobalInt('STRIPE_GIROPAY')) { |
||
| 452 | $paymentmethodtypes[] = "giropay"; |
||
| 453 | } |
||
| 454 | if (getDolGlobalInt('STRIPE_SOFORT')) { |
||
| 455 | $paymentmethodtypes[] = "sofort"; |
||
| 456 | } |
||
| 457 | if (getDolGlobalInt('STRIPE_CARD_PRESENT') && $mode == 'terminal') { |
||
| 458 | $paymentmethodtypes = array("card_present"); |
||
| 459 | } |
||
| 460 | |||
| 461 | $dataforintent = array( |
||
| 462 | "confirm" => $confirmnow, // Do not confirm immediatly during creation of intent |
||
| 463 | "confirmation_method" => $mode, |
||
| 464 | "amount" => $stripeamount, |
||
| 465 | "currency" => $currency_code, |
||
| 466 | "payment_method_types" => $paymentmethodtypes, |
||
| 467 | "description" => $description, |
||
| 468 | "statement_descriptor_suffix" => $descriptor, // For card payment, 22 chars that appears on bank receipt (prefix into stripe setup + this suffix) |
||
| 469 | "statement_descriptor" => $descriptor, // For SEPA, it will take only statement_descriptor, not statement_descriptor_suffix |
||
| 470 | //"save_payment_method" => true, |
||
| 471 | "setup_future_usage" => "on_session", |
||
| 472 | "metadata" => $metadata |
||
| 473 | ); |
||
| 474 | if (!is_null($customer)) { |
||
| 475 | $dataforintent["customer"] = $customer; |
||
| 476 | } |
||
| 477 | // payment_method = |
||
| 478 | // payment_method_types = array('card') |
||
| 479 | //var_dump($dataforintent); |
||
| 480 | if ($off_session) { |
||
| 481 | unset($dataforintent['setup_future_usage']); |
||
| 482 | // We can't use both "setup_future_usage" = "off_session" and "off_session" = true. |
||
| 483 | // Because $off_session parameter is dedicated to create paymentintent off_line (and not future payment), we need to use "off_session" = true. |
||
| 484 | //$dataforintent["setup_future_usage"] = "off_session"; |
||
| 485 | $dataforintent["off_session"] = true; |
||
| 486 | } |
||
| 487 | if (getDolGlobalInt('STRIPE_GIROPAY')) { |
||
| 488 | unset($dataforintent['setup_future_usage']); |
||
| 489 | } |
||
| 490 | if (getDolGlobalInt('STRIPE_KLARNA')) { |
||
| 491 | unset($dataforintent['setup_future_usage']); |
||
| 492 | } |
||
| 493 | if (getDolGlobalInt('STRIPE_CARD_PRESENT') && $mode == 'terminal') { |
||
| 494 | unset($dataforintent['setup_future_usage']); |
||
| 495 | $dataforintent["capture_method"] = "manual"; |
||
| 496 | $dataforintent["confirmation_method"] = "manual"; |
||
| 497 | } |
||
| 498 | if (!is_null($payment_method)) { |
||
| 499 | $dataforintent["payment_method"] = $payment_method; |
||
| 500 | $description .= ' - '.$payment_method; |
||
| 501 | } |
||
| 502 | |||
| 503 | if ($conf->entity != getDolGlobalInt('STRIPECONNECT_PRINCIPAL') && $stripefee > 0) { |
||
| 504 | $dataforintent["application_fee_amount"] = $stripefee; |
||
| 505 | } |
||
| 506 | if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email) { |
||
| 507 | $dataforintent["receipt_email"] = $object->thirdparty->email; |
||
| 508 | } |
||
| 509 | |||
| 510 | try { |
||
| 511 | // Force to use the correct API key |
||
| 512 | global $stripearrayofkeysbyenv; |
||
| 513 | \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']); |
||
| 514 | |||
| 515 | $arrayofoptions = array(); |
||
| 516 | if (empty($noidempotency_key)) { |
||
| 517 | $arrayofoptions["idempotency_key"] = $description; |
||
| 518 | } |
||
| 519 | // 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. |
||
| 520 | if (!empty($key)) { // If the Stripe connect account not set, we use common API usage |
||
| 521 | $arrayofoptions["stripe_account"] = $key; |
||
| 522 | } |
||
| 523 | |||
| 524 | dol_syslog("dataforintent to create paymentintent = ".var_export($dataforintent, true)); |
||
| 525 | |||
| 526 | $paymentintent = \Stripe\PaymentIntent::create($dataforintent, $arrayofoptions); |
||
| 527 | |||
| 528 | // Store the payment intent |
||
| 529 | if (is_object($object)) { |
||
| 530 | $paymentintentalreadyexists = 0; |
||
| 531 | // Check that payment intent $paymentintent->id is not already recorded. |
||
| 532 | $sql = "SELECT pi.rowid"; |
||
| 533 | $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pi"; |
||
| 534 | $sql .= " WHERE pi.entity IN (".getEntity('societe').")"; |
||
| 535 | $sql .= " AND pi.ext_payment_site = '".$this->db->escape($service)."'"; |
||
| 536 | $sql .= " AND pi.ext_payment_id = '".$this->db->escape($paymentintent->id)."'"; |
||
| 537 | |||
| 538 | dol_syslog(get_class($this)."::getPaymentIntent search if payment intent already in prelevement_demande", LOG_DEBUG); |
||
| 539 | $resql = $this->db->query($sql); |
||
| 540 | if ($resql) { |
||
| 541 | $num = $this->db->num_rows($resql); |
||
| 542 | if ($num) { |
||
| 543 | $obj = $this->db->fetch_object($resql); |
||
| 544 | if ($obj) { |
||
| 545 | $paymentintentalreadyexists++; |
||
| 546 | } |
||
| 547 | } |
||
| 548 | } else { |
||
| 549 | dol_print_error($this->db); |
||
| 550 | } |
||
| 551 | |||
| 552 | // If not, we create it. |
||
| 553 | if (!$paymentintentalreadyexists) { |
||
| 554 | $now = dol_now(); |
||
| 555 | $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_demande (date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site, amount)"; |
||
| 556 | $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).")"; |
||
| 557 | $resql = $this->db->query($sql); |
||
| 558 | if (!$resql) { |
||
| 559 | $error++; |
||
| 560 | $this->error = $this->db->lasterror(); |
||
| 561 | dol_syslog(get_class($this)."::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id." into database.", LOG_ERR); |
||
| 562 | } |
||
| 563 | } |
||
| 564 | } else { |
||
| 565 | $_SESSION["stripe_payment_intent"] = $paymentintent; |
||
| 566 | } |
||
| 567 | } catch (Stripe\Error\Card $e) { |
||
| 568 | $error++; |
||
| 569 | $this->error = $e->getMessage(); |
||
| 570 | $this->code = $e->getStripeCode(); |
||
| 571 | $this->declinecode = $e->getDeclineCode(); |
||
| 572 | } catch (Exception $e) { |
||
| 573 | //var_dump($dataforintent); |
||
| 574 | //var_dump($description); |
||
| 575 | //var_dump($key); |
||
| 576 | //var_dump($paymentintent); |
||
| 577 | //var_dump($e->getMessage()); |
||
| 578 | //var_dump($e); |
||
| 579 | $error++; |
||
| 580 | $this->error = $e->getMessage(); |
||
| 581 | $this->code = ''; |
||
| 582 | $this->declinecode = ''; |
||
| 583 | } |
||
| 584 | } |
||
| 585 | |||
| 586 | dol_syslog(get_class($this)."::getPaymentIntent return error=".$error." this->error=".$this->error, LOG_INFO, -1); |
||
| 587 | |||
| 588 | if (!$error) { |
||
| 589 | return $paymentintent; |
||
| 590 | } else { |
||
| 591 | return null; |
||
| 592 | } |
||
| 593 | } |
||
| 594 | |||
| 595 | /** |
||
| 596 | * Get the Stripe payment intent. Create it with confirmnow=false |
||
| 597 | * Warning. If a payment was tried and failed, a payment intent was created. |
||
| 598 | * But if we change something on object to pay (amount or other), reusing same payment intent is not allowed. |
||
| 599 | * Recommanded solution is to recreate a new payment intent each time we need one (old one will be automatically closed after a delay), |
||
| 600 | * that's why i comment the part of code to retrieve a payment intent with object id (never mind if we cumulate payment intent with old ones that will not be used) |
||
| 601 | * Note: This is used when option STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is on when making a payment from the public/payment/newpayment.php page |
||
| 602 | * but not when using the STRIPE_USE_NEW_CHECKOUT. |
||
| 603 | * |
||
| 604 | * @param string $description Description |
||
| 605 | * @param Societe $object Object of company to link the Stripe payment mode with |
||
| 606 | * @param string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() |
||
| 607 | * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 608 | * @param int $status Status (0=test, 1=live) |
||
| 609 | * @param int $usethirdpartyemailforreceiptemail 1=use thirdparty email for receipt |
||
| 610 | * @param boolean $confirmnow false=default, true=try to confirm immediatly after create (if conditions are ok) |
||
| 611 | * @return \Stripe\SetupIntent|null Stripe SetupIntent or null if not found and failed to create |
||
| 612 | */ |
||
| 613 | public function getSetupIntent($description, $object, $customer, $key, $status, $usethirdpartyemailforreceiptemail = 0, $confirmnow = false) |
||
| 752 | } |
||
| 753 | } |
||
| 754 | |||
| 755 | |||
| 756 | /** |
||
| 757 | * Get the Stripe card of a company payment mode (option to create it on Stripe if not linked yet is no more available on new Stripe API) |
||
| 758 | * |
||
| 759 | * @param \Stripe\StripeCustomer $cu Object stripe customer. |
||
| 760 | * @param CompanyPaymentMode $object Object companypaymentmode to check, or create on stripe (create on stripe also update the societe_rib table for current entity) |
||
| 761 | * @param string $stripeacc ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 762 | * @param int $status Status (0=test, 1=live) |
||
| 763 | * @param int $createifnotlinkedtostripe 1=Create the stripe card and the link if the card is not yet linked to a stripe card. Deprecated with new Stripe API and SCA. |
||
| 764 | * @return \Stripe\StripeCard|\Stripe\PaymentMethod|null Stripe Card or null if not found |
||
| 765 | */ |
||
| 766 | public function cardStripe($cu, CompanyPaymentMode $object, $stripeacc = '', $status = 0, $createifnotlinkedtostripe = 0) |
||
| 767 | { |
||
| 768 | global $conf, $user, $langs; |
||
| 769 | |||
| 770 | $card = null; |
||
| 771 | |||
| 772 | $sql = "SELECT sa.stripe_card_ref, sa.proprio, sa.exp_date_month, sa.exp_date_year, sa.number, sa.cvn"; // stripe_card_ref is card_.... |
||
| 773 | $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib as sa"; |
||
| 774 | $sql .= " WHERE sa.rowid = ".((int) $object->id); // We get record from ID, no need for filter on entity |
||
| 775 | $sql .= " AND sa.type = 'card'"; |
||
| 776 | |||
| 777 | dol_syslog(get_class($this)."::cardStripe search stripe card id for paymentmode id=".$object->id.", stripeacc=".$stripeacc.", status=".$status.", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG); |
||
| 778 | $resql = $this->db->query($sql); |
||
| 779 | if ($resql) { |
||
| 780 | $num = $this->db->num_rows($resql); |
||
| 781 | if ($num) { |
||
| 782 | $obj = $this->db->fetch_object($resql); |
||
| 783 | $cardref = $obj->stripe_card_ref; |
||
| 784 | dol_syslog(get_class($this)."::cardStripe cardref=".$cardref); |
||
| 785 | if ($cardref) { |
||
| 786 | try { |
||
| 787 | if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage |
||
| 788 | if (!preg_match('/^pm_/', $cardref) && !empty($cu->sources)) { |
||
| 789 | $card = $cu->sources->retrieve($cardref); |
||
| 790 | } else { |
||
| 791 | $card = \Stripe\PaymentMethod::retrieve($cardref); |
||
| 792 | } |
||
| 793 | } else { |
||
| 794 | if (!preg_match('/^pm_/', $cardref) && !empty($cu->sources)) { |
||
| 795 | //$card = $cu->sources->retrieve($cardref, array("stripe_account" => $stripeacc)); // this API fails when array stripe_account is provided |
||
| 796 | $card = $cu->sources->retrieve($cardref); |
||
| 797 | } else { |
||
| 798 | //$card = \Stripe\PaymentMethod::retrieve($cardref, array("stripe_account" => $stripeacc)); // Don't know if this works |
||
| 799 | $card = \Stripe\PaymentMethod::retrieve($cardref); |
||
| 800 | } |
||
| 801 | } |
||
| 802 | } catch (Exception $e) { |
||
| 803 | $this->error = $e->getMessage(); |
||
| 804 | dol_syslog($this->error, LOG_WARNING); |
||
| 805 | } |
||
| 806 | } elseif ($createifnotlinkedtostripe) { |
||
| 807 | // Deprecated with new Stripe API and SCA. We should not use anymore this part of code now. |
||
| 808 | $exp_date_month = $obj->exp_date_month; |
||
| 809 | $exp_date_year = $obj->exp_date_year; |
||
| 810 | $number = $obj->number; |
||
| 811 | $cvc = $obj->cvn; // cvn in database, cvc for stripe |
||
| 812 | $cardholdername = $obj->proprio; |
||
| 813 | |||
| 814 | $ipaddress = getUserRemoteIP(); |
||
| 815 | |||
| 816 | $dataforcard = array( |
||
| 817 | "source" => array( |
||
| 818 | 'object'=>'card', |
||
| 819 | 'exp_month'=>$exp_date_month, |
||
| 820 | 'exp_year'=>$exp_date_year, |
||
| 821 | 'number'=>$number, |
||
| 822 | 'cvc'=>$cvc, |
||
| 823 | 'name'=>$cardholdername |
||
| 824 | ), |
||
| 825 | "metadata" => array( |
||
| 826 | 'dol_type'=>$object->element, |
||
| 827 | 'dol_id'=>$object->id, |
||
| 828 | 'dol_version'=>DOL_VERSION, |
||
| 829 | 'dol_entity'=>$conf->entity, |
||
| 830 | 'ipaddress'=>$ipaddress |
||
| 831 | ) |
||
| 832 | ); |
||
| 833 | |||
| 834 | //$a = \Stripe\Stripe::getApiKey(); |
||
| 835 | //var_dump($a); |
||
| 836 | //var_dump($stripeacc);exit; |
||
| 837 | try { |
||
| 838 | if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage |
||
| 839 | if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) { |
||
| 840 | dol_syslog("Try to create card with dataforcard = ".json_encode($dataforcard)); |
||
| 841 | $card = $cu->sources->create($dataforcard); |
||
| 842 | if (!$card) { |
||
| 843 | $this->error = 'Creation of card on Stripe has failed'; |
||
| 844 | } |
||
| 845 | } else { |
||
| 846 | $connect = ''; |
||
| 847 | if (!empty($stripeacc)) { |
||
| 848 | $connect = $stripeacc.'/'; |
||
| 849 | } |
||
| 850 | $url = 'https://dashboard.stripe.com/'.$connect.'test/customers/'.$cu->id; |
||
| 851 | if ($status) { |
||
| 852 | $url = 'https://dashboard.stripe.com/'.$connect.'customers/'.$cu->id; |
||
| 853 | } |
||
| 854 | $urtoswitchonstripe = ' <a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe'), 'globe').'</a>'; |
||
| 855 | |||
| 856 | //dol_syslog("Error: This case is not supported", LOG_ERR); |
||
| 857 | $this->error = $langs->trans('CreationOfPaymentModeMustBeDoneFromStripeInterface', $urtoswitchonstripe); |
||
| 858 | } |
||
| 859 | } else { |
||
| 860 | if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) { |
||
| 861 | dol_syslog("Try to create card with dataforcard = ".json_encode($dataforcard)); |
||
| 862 | $card = $cu->sources->create($dataforcard, array("stripe_account" => $stripeacc)); |
||
| 863 | if (!$card) { |
||
| 864 | $this->error = 'Creation of card on Stripe has failed'; |
||
| 865 | } |
||
| 866 | } else { |
||
| 867 | $connect = ''; |
||
| 868 | if (!empty($stripeacc)) { |
||
| 869 | $connect = $stripeacc.'/'; |
||
| 870 | } |
||
| 871 | $url = 'https://dashboard.stripe.com/'.$connect.'test/customers/'.$cu->id; |
||
| 872 | if ($status) { |
||
| 873 | $url = 'https://dashboard.stripe.com/'.$connect.'customers/'.$cu->id; |
||
| 874 | } |
||
| 875 | $urtoswitchonstripe = ' <a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe'), 'globe').'</a>'; |
||
| 876 | |||
| 877 | //dol_syslog("Error: This case is not supported", LOG_ERR); |
||
| 878 | $this->error = $langs->trans('CreationOfPaymentModeMustBeDoneFromStripeInterface', $urtoswitchonstripe); |
||
| 879 | } |
||
| 880 | } |
||
| 881 | |||
| 882 | if ($card) { |
||
| 883 | $sql = "UPDATE ".MAIN_DB_PREFIX."societe_rib"; |
||
| 884 | $sql .= " SET stripe_card_ref = '".$this->db->escape($card->id)."', card_type = '".$this->db->escape($card->brand)."',"; |
||
| 885 | $sql .= " country_code = '".$this->db->escape($card->country)."',"; |
||
| 886 | $sql .= " approved = ".($card->cvc_check == 'pass' ? 1 : 0); |
||
| 887 | $sql .= " WHERE rowid = ".((int) $object->id); |
||
| 888 | $sql .= " AND type = 'card'"; |
||
| 889 | $resql = $this->db->query($sql); |
||
| 890 | if (!$resql) { |
||
| 891 | $this->error = $this->db->lasterror(); |
||
| 892 | } |
||
| 893 | } |
||
| 894 | } catch (Exception $e) { |
||
| 895 | $this->error = $e->getMessage(); |
||
| 896 | dol_syslog($this->error, LOG_WARNING); |
||
| 897 | } |
||
| 898 | } |
||
| 899 | } |
||
| 900 | } else { |
||
| 901 | dol_print_error($this->db); |
||
| 902 | } |
||
| 903 | |||
| 904 | return $card; |
||
| 905 | } |
||
| 906 | |||
| 907 | |||
| 908 | /** |
||
| 909 | * Get the Stripe SEPA of a company payment mode |
||
| 910 | * |
||
| 911 | * @param \Stripe\StripeCustomer $cu Object stripe customer. |
||
| 912 | * @param CompanyPaymentMode $object Object companypaymentmode to check, or create on stripe (create on stripe also update the societe_rib table for current entity) |
||
| 913 | * @param string $stripeacc ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 914 | * @param int $status Status (0=test, 1=live) |
||
| 915 | * @param int $createifnotlinkedtostripe 1=Create the stripe sepa and the link if the sepa is not yet linked to a stripe sepa. Used by the "Create bank to Stripe" feature. |
||
| 916 | * @return \Stripe\PaymentMethod|null Stripe SEPA or null if not found |
||
| 917 | */ |
||
| 918 | public function sepaStripe($cu, CompanyPaymentMode $object, $stripeacc = '', $status = 0, $createifnotlinkedtostripe = 0) |
||
| 1053 | } |
||
| 1054 | |||
| 1055 | |||
| 1056 | /** |
||
| 1057 | * Create charge. |
||
| 1058 | * This is called by page htdocs/stripe/payment.php and may be deprecated. |
||
| 1059 | * |
||
| 1060 | * @param int $amount Amount to pay |
||
| 1061 | * @param string $currency EUR, GPB... |
||
| 1062 | * @param string $origin Object type to pay (order, invoice, contract...) |
||
| 1063 | * @param int $item Object id to pay |
||
| 1064 | * @param string $source src_xxxxx or card_xxxxx or pm_xxxxx |
||
| 1065 | * @param string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() |
||
| 1066 | * @param string $account Stripe account ref 'acc_xxxxxxxxxxxxx' via getStripeAccount() |
||
| 1067 | * @param int $status Status (0=test, 1=live) |
||
| 1068 | * @param int $usethirdpartyemailforreceiptemail Use thirdparty email as receipt email |
||
| 1069 | * @param boolean $capture Set capture flag to true (take payment) or false (wait) |
||
| 1070 | * @return Stripe |
||
| 1071 | */ |
||
| 1072 | public function createPaymentStripe($amount, $currency, $origin, $item, $source, $customer, $account, $status = 0, $usethirdpartyemailforreceiptemail = 0, $capture = true) |
||
| 1332 | } |
||
| 1333 | } |
||
| 1334 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths