| Total Complexity | 108 |
| Total Lines | 928 |
| Duplicated Lines | 0 % |
| Changes | 5 | ||
| 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 | |||
| 64 | public $message; |
||
| 65 | |||
| 66 | /** |
||
| 67 | * Constructor |
||
| 68 | * |
||
| 69 | * @param DoliDB $db Database handler |
||
| 70 | */ |
||
| 71 | public function __construct($db) |
||
| 72 | { |
||
| 73 | $this->db = $db; |
||
| 74 | } |
||
| 75 | |||
| 76 | |||
| 77 | /** |
||
| 78 | * Return main company OAuth Connect stripe account |
||
| 79 | * |
||
| 80 | * @param string $mode 'StripeTest' or 'StripeLive' |
||
| 81 | * @param int $fk_soc Id of thirdparty |
||
| 82 | * @return string Stripe account 'acc_....' or '' if no OAuth token found |
||
| 83 | */ |
||
| 84 | public function getStripeAccount($mode = 'StripeTest', $fk_soc = 0) |
||
| 85 | { |
||
| 86 | global $conf; |
||
| 87 | |||
| 88 | $sql = "SELECT tokenstring"; |
||
| 89 | $sql.= " FROM ".MAIN_DB_PREFIX."oauth_token"; |
||
| 90 | $sql.= " WHERE entity = ".$conf->entity; |
||
| 91 | $sql.= " AND service = '".$mode."'"; |
||
| 92 | if ($fk_soc > 0) { |
||
| 93 | $sql.= " AND fk_soc = ".$fk_soc; |
||
| 94 | } |
||
| 95 | else { |
||
| 96 | $sql.= " AND fk_soc IS NULL"; |
||
| 97 | } |
||
| 98 | $sql.= " AND fk_user IS NULL AND fk_adherent IS NULL"; |
||
| 99 | |||
| 100 | dol_syslog(get_class($this) . "::fetch", LOG_DEBUG); |
||
| 101 | $result = $this->db->query($sql); |
||
| 102 | if ($result) { |
||
| 103 | if ($this->db->num_rows($result)) { |
||
| 104 | $obj = $this->db->fetch_object($result); |
||
| 105 | $tokenstring=$obj->tokenstring; |
||
| 106 | |||
| 107 | $tmparray = dol_json_decode($tokenstring); |
||
| 108 | $key = $tmparray->stripe_user_id; |
||
| 109 | } else { |
||
| 110 | $tokenstring=''; |
||
| 111 | } |
||
| 112 | } |
||
| 113 | else { |
||
| 114 | dol_print_error($this->db); |
||
| 115 | } |
||
| 116 | |||
| 117 | dol_syslog("No dedicated Stripe Connect account available for entity ".$conf->entity); |
||
| 118 | return $key; |
||
|
|
|||
| 119 | } |
||
| 120 | |||
| 121 | /** |
||
| 122 | * getStripeCustomerAccount |
||
| 123 | * |
||
| 124 | * @param int $id Id of third party |
||
| 125 | * @param int $status Status |
||
| 126 | * @return string Stripe customer ref 'cu_xxxxxxxxxxxxx' or '' |
||
| 127 | */ |
||
| 128 | public function getStripeCustomerAccount($id, $status = 0) |
||
| 129 | { |
||
| 130 | include_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php'; |
||
| 131 | $societeaccount = new SocieteAccount($this->db); |
||
| 132 | return $societeaccount->getCustomerAccount($id, 'stripe', $status); // Get thirdparty cus_... |
||
| 133 | } |
||
| 134 | |||
| 135 | |||
| 136 | /** |
||
| 137 | * Get the Stripe customer of a thirdparty (with option to create it if not linked yet) |
||
| 138 | * |
||
| 139 | * @param Societe $object Object thirdparty to check, or create on stripe (create on stripe also update the stripe_account table for current entity) |
||
| 140 | * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 141 | * @param int $status Status (0=test, 1=live) |
||
| 142 | * @param int $createifnotlinkedtostripe 1=Create the stripe customer and the link if the thirdparty is not yet linked to a stripe customer |
||
| 143 | * @return \Stripe\StripeCustomer|null Stripe Customer or null if not found |
||
| 144 | */ |
||
| 145 | public function customerStripe(Societe $object, $key = '', $status = 0, $createifnotlinkedtostripe = 0) |
||
| 146 | { |
||
| 147 | global $conf, $user; |
||
| 148 | |||
| 149 | if (empty($object->id)) |
||
| 150 | { |
||
| 151 | dol_syslog("customerStripe is called with the parameter object that is not loaded"); |
||
| 152 | return null; |
||
| 153 | } |
||
| 154 | |||
| 155 | $customer = null; |
||
| 156 | |||
| 157 | $sql = "SELECT sa.key_account as key_account, sa.entity"; // key_account is cus_.... |
||
| 158 | $sql.= " FROM " . MAIN_DB_PREFIX . "societe_account as sa"; |
||
| 159 | $sql.= " WHERE sa.fk_soc = " . $object->id; |
||
| 160 | $sql.= " AND sa.entity IN (".getEntity('societe').")"; |
||
| 161 | $sql.= " AND sa.site = 'stripe' AND sa.status = ".((int) $status); |
||
| 162 | $sql.= " AND key_account IS NOT NULL AND key_account <> ''"; |
||
| 163 | |||
| 164 | dol_syslog(get_class($this) . "::customerStripe search stripe customer id for thirdparty id=".$object->id, LOG_DEBUG); |
||
| 165 | $resql = $this->db->query($sql); |
||
| 166 | if ($resql) { |
||
| 167 | $num = $this->db->num_rows($resql); |
||
| 168 | if ($num) |
||
| 169 | { |
||
| 170 | $obj = $this->db->fetch_object($resql); |
||
| 171 | $tiers = $obj->key_account; |
||
| 172 | |||
| 173 | dol_syslog(get_class($this) . "::customerStripe found stripe customer key_account = ".$tiers); |
||
| 174 | |||
| 175 | // Force to use the correct API key |
||
| 176 | global $stripearrayofkeysbyenv; |
||
| 177 | \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']); |
||
| 178 | |||
| 179 | try { |
||
| 180 | if (empty($key)) { // If the Stripe connect account not set, we use common API usage |
||
| 181 | $customer = \Stripe\Customer::retrieve("$tiers"); |
||
| 182 | } else { |
||
| 183 | $customer = \Stripe\Customer::retrieve("$tiers", array("stripe_account" => $key)); |
||
| 184 | } |
||
| 185 | } |
||
| 186 | catch(Exception $e) |
||
| 187 | { |
||
| 188 | // For exemple, we may have error: 'No such customer: cus_XXXXX; a similar object exists in live mode, but a test mode key was used to make this request.' |
||
| 189 | $this->error = $e->getMessage(); |
||
| 190 | } |
||
| 191 | } |
||
| 192 | elseif ($createifnotlinkedtostripe) |
||
| 193 | { |
||
| 194 | $ipaddress = getUserRemoteIP(); |
||
| 195 | |||
| 196 | $dataforcustomer = array( |
||
| 197 | "email" => $object->email, |
||
| 198 | "description" => $object->name, |
||
| 199 | "metadata" => array('dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress) |
||
| 200 | ); |
||
| 201 | |||
| 202 | $vatcleaned = $object->tva_intra ? $object->tva_intra : null; |
||
| 203 | |||
| 204 | /* |
||
| 205 | $taxinfo = array('type'=>'vat'); |
||
| 206 | if ($vatcleaned) |
||
| 207 | { |
||
| 208 | $taxinfo["tax_id"] = $vatcleaned; |
||
| 209 | } |
||
| 210 | // We force data to "null" if not defined as expected by Stripe |
||
| 211 | if (empty($vatcleaned)) $taxinfo=null; |
||
| 212 | $dataforcustomer["tax_info"] = $taxinfo; |
||
| 213 | */ |
||
| 214 | |||
| 215 | //$a = \Stripe\Stripe::getApiKey(); |
||
| 216 | //var_dump($a);var_dump($key);exit; |
||
| 217 | try { |
||
| 218 | // Force to use the correct API key |
||
| 219 | global $stripearrayofkeysbyenv; |
||
| 220 | \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']); |
||
| 221 | |||
| 222 | if (empty($key)) { // If the Stripe connect account not set, we use common API usage |
||
| 223 | $customer = \Stripe\Customer::create($dataforcustomer); |
||
| 224 | } else { |
||
| 225 | $customer = \Stripe\Customer::create($dataforcustomer, array("stripe_account" => $key)); |
||
| 226 | } |
||
| 227 | |||
| 228 | // Create the VAT record in Stripe |
||
| 229 | if (! empty($conf->global->STRIPE_SAVE_TAX_IDS)) // We setup to save Tax info on Stripe side. Warning: This may result in error when saving customer |
||
| 230 | { |
||
| 231 | if (! empty($vatcleaned)) |
||
| 232 | { |
||
| 233 | $isineec=isInEEC($object); |
||
| 234 | if ($object->country_code && $isineec) |
||
| 235 | { |
||
| 236 | //$taxids = $customer->allTaxIds($customer->id); |
||
| 237 | $customer->createTaxId($customer->id, array('type'=>'eu_vat', 'value'=>$vatcleaned)); |
||
| 238 | } |
||
| 239 | } |
||
| 240 | } |
||
| 241 | |||
| 242 | // Create customer in Dolibarr |
||
| 243 | $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_account (fk_soc, login, key_account, site, status, entity, date_creation, fk_user_creat)"; |
||
| 244 | $sql .= " VALUES (".$object->id.", '', '".$this->db->escape($customer->id)."', 'stripe', " . $status . ", " . $conf->entity . ", '".$this->db->idate(dol_now())."', ".$user->id.")"; |
||
| 245 | $resql = $this->db->query($sql); |
||
| 246 | if (! $resql) |
||
| 247 | { |
||
| 248 | $this->error = $this->db->lasterror(); |
||
| 249 | } |
||
| 250 | } |
||
| 251 | catch(Exception $e) |
||
| 252 | { |
||
| 253 | $this->error = $e->getMessage(); |
||
| 254 | } |
||
| 255 | } |
||
| 256 | } |
||
| 257 | else |
||
| 258 | { |
||
| 259 | dol_print_error($this->db); |
||
| 260 | } |
||
| 261 | |||
| 262 | return $customer; |
||
| 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) |
||
| 293 | } |
||
| 294 | |||
| 295 | /** |
||
| 296 | * Get the Stripe payment intent. Create it with confirmnow=false |
||
| 297 | * Warning. If a payment was tried and failed, a payment intent was created. |
||
| 298 | * But if we change something on object to pay (amount or other), reusing same payment intent is not allowed. |
||
| 299 | * Recommanded solution is to recreate a new payment intent each time we need one (old one will be automatically closed after a delay), |
||
| 300 | * that's why i comment the part of code to retreive a payment intent with object id (never mind if we cumulate payment intent with old ones that will not be used) |
||
| 301 | * 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 |
||
| 302 | * but not when using the STRIPE_USE_NEW_CHECKOUT. |
||
| 303 | * |
||
| 304 | * @param double $amount Amount |
||
| 305 | * @param string $currency_code Currency code |
||
| 306 | * @param string $tag Tag |
||
| 307 | * @param string $description Description |
||
| 308 | * @param Societe $object Object to pay with Stripe |
||
| 309 | * @param string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() |
||
| 310 | * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 311 | * @param int $status Status (0=test, 1=live) |
||
| 312 | * @param int $usethirdpartyemailforreceiptemail 1=use thirdparty email for receipt |
||
| 313 | * @param int $mode automatic=automatic confirmation/payment when conditions are ok, manual=need to call confirm() on intent |
||
| 314 | * @param boolean $confirmnow false=default, true=try to confirm immediatly after create (if conditions are ok) |
||
| 315 | * @return \Stripe\PaymentIntent|null Stripe PaymentIntent or null if not found and failed to create |
||
| 316 | */ |
||
| 317 | public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false) |
||
| 503 | } |
||
| 504 | } |
||
| 505 | |||
| 506 | |||
| 507 | /** |
||
| 508 | * Get the Stripe payment intent. Create it with confirmnow=false |
||
| 509 | * Warning. If a payment was tried and failed, a payment intent was created. |
||
| 510 | * But if we change something on object to pay (amount or other), reusing same payment intent is not allowed. |
||
| 511 | * Recommanded solution is to recreate a new payment intent each time we need one (old one will be automatically closed after a delay), |
||
| 512 | * that's why i comment the part of code to retreive a payment intent with object id (never mind if we cumulate payment intent with old ones that will not be used) |
||
| 513 | * 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 |
||
| 514 | * but not when using the STRIPE_USE_NEW_CHECKOUT. |
||
| 515 | * |
||
| 516 | * @param string $description Description |
||
| 517 | * @param Societe $object Object to pay with Stripe |
||
| 518 | * @param string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() |
||
| 519 | * @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 520 | * @param int $status Status (0=test, 1=live) |
||
| 521 | * @param int $usethirdpartyemailforreceiptemail 1=use thirdparty email for receipt |
||
| 522 | * @param boolean $confirmnow false=default, true=try to confirm immediatly after create (if conditions are ok) |
||
| 523 | * @return \Stripe\SetupIntent|null Stripe SetupIntent or null if not found and failed to create |
||
| 524 | */ |
||
| 525 | public function getSetupIntent($description, $object, $customer, $key, $status, $usethirdpartyemailforreceiptemail = 0, $confirmnow = false) |
||
| 645 | } |
||
| 646 | } |
||
| 647 | |||
| 648 | |||
| 649 | /** |
||
| 650 | * Get the Stripe card of a company payment mode (with option to create it on Stripe if not linked yet) |
||
| 651 | * |
||
| 652 | * @param \Stripe\StripeCustomer $cu Object stripe customer |
||
| 653 | * @param CompanyPaymentMode $object Object companypaymentmode to check, or create on stripe (create on stripe also update the societe_rib table for current entity) |
||
| 654 | * @param string $stripeacc ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect |
||
| 655 | * @param int $status Status (0=test, 1=live) |
||
| 656 | * @param int $createifnotlinkedtostripe 1=Create the stripe card and the link if the card is not yet linked to a stripe card |
||
| 657 | * @return \Stripe\StripeCard|null Stripe Card or null if not found |
||
| 658 | */ |
||
| 659 | public function cardStripe($cu, CompanyPaymentMode $object, $stripeacc = '', $status = 0, $createifnotlinkedtostripe = 0) |
||
| 660 | { |
||
| 661 | global $conf, $user; |
||
| 662 | |||
| 663 | $card = null; |
||
| 664 | |||
| 665 | $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_.... |
||
| 666 | $sql.= " FROM " . MAIN_DB_PREFIX . "societe_rib as sa"; |
||
| 667 | $sql.= " WHERE sa.rowid = " . $object->id; // We get record from ID, no need for filter on entity |
||
| 668 | $sql.= " AND sa.type = 'card'"; |
||
| 669 | |||
| 670 | dol_syslog(get_class($this) . "::fetch search stripe card id for paymentmode id=".$object->id.", stripeacc=".$stripeacc.", status=".$status.", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG); |
||
| 671 | $resql = $this->db->query($sql); |
||
| 672 | if ($resql) { |
||
| 673 | $num = $this->db->num_rows($resql); |
||
| 674 | if ($num) |
||
| 675 | { |
||
| 676 | $obj = $this->db->fetch_object($resql); |
||
| 677 | $cardref = $obj->stripe_card_ref; |
||
| 678 | dol_syslog(get_class($this) . "::cardStripe cardref=".$cardref); |
||
| 679 | if ($cardref) |
||
| 680 | { |
||
| 681 | try { |
||
| 682 | if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage |
||
| 683 | $card = $cu->sources->retrieve($cardref); |
||
| 684 | } else { |
||
| 685 | //$card = $cu->sources->retrieve($cardref, array("stripe_account" => $stripeacc)); // this API fails when array stripe_account is provided |
||
| 686 | $card = $cu->sources->retrieve($cardref); |
||
| 687 | } |
||
| 688 | } |
||
| 689 | catch(Exception $e) |
||
| 690 | { |
||
| 691 | $this->error = $e->getMessage(); |
||
| 692 | dol_syslog($this->error, LOG_WARNING); |
||
| 693 | } |
||
| 694 | } |
||
| 695 | elseif ($createifnotlinkedtostripe) |
||
| 696 | { |
||
| 697 | $exp_date_month=$obj->exp_date_month; |
||
| 698 | $exp_date_year=$obj->exp_date_year; |
||
| 699 | $number=$obj->number; |
||
| 700 | $cvc=$obj->cvn; // cvn in database, cvc for stripe |
||
| 701 | $cardholdername=$obj->proprio; |
||
| 702 | |||
| 703 | $dataforcard = array( |
||
| 704 | "source" => array('object'=>'card', 'exp_month'=>$exp_date_month, 'exp_year'=>$exp_date_year, 'number'=>$number, 'cvc'=>$cvc, 'name'=>$cardholdername), |
||
| 705 | "metadata" => array('dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>(empty($_SERVER['REMOTE_ADDR'])?'':$_SERVER['REMOTE_ADDR'])) |
||
| 706 | ); |
||
| 707 | |||
| 708 | //$a = \Stripe\Stripe::getApiKey(); |
||
| 709 | //var_dump($a);var_dump($stripeacc);exit; |
||
| 710 | dol_syslog("Try to create card dataforcard = ".json_encode($dataforcard)); |
||
| 711 | try { |
||
| 712 | if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage |
||
| 713 | $card = $cu->sources->create($dataforcard); |
||
| 714 | } else { |
||
| 715 | $card = $cu->sources->create($dataforcard, array("stripe_account" => $stripeacc)); |
||
| 716 | } |
||
| 717 | |||
| 718 | if ($card) |
||
| 719 | { |
||
| 720 | $sql = "UPDATE " . MAIN_DB_PREFIX . "societe_rib"; |
||
| 721 | $sql.= " SET stripe_card_ref = '".$this->db->escape($card->id)."', card_type = '".$this->db->escape($card->brand)."',"; |
||
| 722 | $sql.= " country_code = '".$this->db->escape($card->country)."',"; |
||
| 723 | $sql.= " approved = ".($card->cvc_check == 'pass' ? 1 : 0); |
||
| 724 | $sql.= " WHERE rowid = " . $object->id; |
||
| 725 | $sql.= " AND type = 'card'"; |
||
| 726 | $resql = $this->db->query($sql); |
||
| 727 | if (! $resql) |
||
| 728 | { |
||
| 729 | $this->error = $this->db->lasterror(); |
||
| 730 | } |
||
| 731 | } |
||
| 732 | else |
||
| 733 | { |
||
| 734 | $this->error = 'Call to cu->source->create return empty card'; |
||
| 735 | } |
||
| 736 | } |
||
| 737 | catch(Exception $e) |
||
| 738 | { |
||
| 739 | $this->error = $e->getMessage(); |
||
| 740 | dol_syslog($this->error, LOG_WARNING); |
||
| 741 | } |
||
| 742 | } |
||
| 743 | } |
||
| 744 | } |
||
| 745 | else |
||
| 746 | { |
||
| 747 | dol_print_error($this->db); |
||
| 748 | } |
||
| 749 | |||
| 750 | return $card; |
||
| 751 | } |
||
| 752 | |||
| 753 | /** |
||
| 754 | * Create charge with public/payment/newpayment.php, stripe/card.php, cronjobs or REST API |
||
| 755 | * This is using old Stripe API charge. |
||
| 756 | * |
||
| 757 | * @param int $amount Amount to pay |
||
| 758 | * @param string $currency EUR, GPB... |
||
| 759 | * @param string $origin Object type to pay (order, invoice, contract...) |
||
| 760 | * @param int $item Object id to pay |
||
| 761 | * @param string $source src_xxxxx or card_xxxxx |
||
| 762 | * @param string $customer Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe() |
||
| 763 | * @param string $account Stripe account ref 'acc_xxxxxxxxxxxxx' via getStripeAccount() |
||
| 764 | * @param int $status Status (0=test, 1=live) |
||
| 765 | * @param int $usethirdpartyemailforreceiptemail Use thirdparty email as receipt email |
||
| 766 | * @param boolean $capture Set capture flag to true (take payment) or false (wait) |
||
| 767 | * @return Stripe |
||
| 768 | */ |
||
| 769 | public function createPaymentStripe($amount, $currency, $origin, $item, $source, $customer, $account, $status = 0, $usethirdpartyemailforreceiptemail = 0, $capture = true) |
||
| 957 | } |
||
| 958 | } |
||
| 959 |