Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Cc.php
Go to the documentation of this file.
1 <?php
7 
11 
18 {
22  protected $_formBlockType = \Magento\Payment\Block\Form\Cc::class;
23 
27  protected $_infoBlockType = \Magento\Payment\Block\Info\Cc::class;
28 
32  protected $_canSaveCc = false;
33 
37  protected $_moduleList;
38 
42  protected $_localeDate;
43 
59  public function __construct(
60  \Magento\Framework\Model\Context $context,
61  \Magento\Framework\Registry $registry,
62  \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
63  \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
64  \Magento\Payment\Helper\Data $paymentData,
65  \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
66  \Magento\Payment\Model\Method\Logger $logger,
67  \Magento\Framework\Module\ModuleListInterface $moduleList,
68  \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
69  \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
70  \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
71  array $data = []
72  ) {
73  parent::__construct(
74  $context,
75  $registry,
76  $extensionFactory,
77  $customAttributeFactory,
78  $paymentData,
79  $scopeConfig,
80  $logger,
81  $resource,
82  $resourceCollection,
83  $data
84  );
85  $this->_moduleList = $moduleList;
86  $this->_localeDate = $localeDate;
87  }
88 
97  public function validate()
98  {
99  /*
100  * calling parent validate function
101  */
102  parent::validate();
103 
104  $info = $this->getInfoInstance();
105  $errorMsg = false;
106  $availableTypes = explode(',', $this->getConfigData('cctypes'));
107 
108  $ccNumber = $info->getCcNumber();
109 
110  // remove credit card number delimiters such as "-" and space
111  $ccNumber = preg_replace('/[\-\s]+/', '', $ccNumber);
112  $info->setCcNumber($ccNumber);
113 
114  $ccType = '';
115 
116  if (in_array($info->getCcType(), $availableTypes)) {
117  if ($this->validateCcNum(
118  $ccNumber
119  ) || $this->otherCcType(
120  $info->getCcType()
121  ) && $this->validateCcNumOther(
122  // Other credit card type number validation
123  $ccNumber
124  )
125  ) {
126  $ccTypeRegExpList = [
127  //Solo, Switch or Maestro. International safe
128  'SO' => '/(^(6334)[5-9](\d{11}$|\d{13,14}$))|(^(6767)(\d{12}$|\d{14,15}$))/',
129  'SM' => '/(^(5[0678])\d{11,18}$)|(^(6[^05])\d{11,18}$)|(^(601)[^1]\d{9,16}$)|(^(6011)\d{9,11}$)' .
130  '|(^(6011)\d{13,16}$)|(^(65)\d{11,13}$)|(^(65)\d{15,18}$)' .
131  '|(^(49030)[2-9](\d{10}$|\d{12,13}$))|(^(49033)[5-9](\d{10}$|\d{12,13}$))' .
132  '|(^(49110)[1-2](\d{10}$|\d{12,13}$))|(^(49117)[4-9](\d{10}$|\d{12,13}$))' .
133  '|(^(49118)[0-2](\d{10}$|\d{12,13}$))|(^(4936)(\d{12}$|\d{14,15}$))/',
134  // Visa
135  'VI' => '/^4[0-9]{12}([0-9]{3})?$/',
136  // Master Card
137  'MC' => '/^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/',
138  // American Express
139  'AE' => '/^3[47][0-9]{13}$/',
140  // Discover
141  'DI' => '/^(6011((0|9|[2-4])[0-9]{11,14}|(74|7[7-9]|8[6-9])[0-9]{10,13})|6(4[4-9][0-9]{13,16}|' .
142  '5[0-9]{14,17}))/',
143  'DN' => '/^3(0[0-5][0-9]{13,16}|095[0-9]{12,15}|(6|[8-9])[0-9]{14,17})/',
144  // UnionPay
145  'UN' => '/^622(1(2[6-9][0-9]{10,13}|[3-9][0-9]{11,14})|[3-8][0-9]{12,15}|9([[0-1][0-9]{11,14}|' .
146  '2[0-5][0-9]{10,13}))|62[4-6][0-9]{13,16}|628[2-8][0-9]{12,15}/',
147  // JCB
148  'JCB' => '/^35(2[8-9][0-9]{12,15}|[3-8][0-9]{13,16})/',
149  'MI' => '/^(5(0|[6-9])|63|67(?!59|6770|6774))\d*$/',
150  'MD' => '/^(6759(?!24|38|40|6[3-9]|70|76)|676770|676774)\d*$/',
151  ];
152 
153  $ccNumAndTypeMatches = isset(
154  $ccTypeRegExpList[$info->getCcType()]
155  ) && preg_match(
156  $ccTypeRegExpList[$info->getCcType()],
157  $ccNumber
158  );
159  $ccType = $ccNumAndTypeMatches ? $info->getCcType() : 'OT';
160 
161  if (!$ccNumAndTypeMatches && !$this->otherCcType($info->getCcType())) {
162  $errorMsg = __('The credit card number doesn\'t match the credit card type.');
163  }
164  } else {
165  $errorMsg = __('Invalid Credit Card Number');
166  }
167  } else {
168  $errorMsg = __('This credit card type is not allowed for this payment method.');
169  }
170 
171  //validate credit card verification number
172  if ($errorMsg === false && $this->hasVerification()) {
173  $verifcationRegEx = $this->getVerificationRegEx();
174  $regExp = isset($verifcationRegEx[$info->getCcType()]) ? $verifcationRegEx[$info->getCcType()] : '';
175  if (!$info->getCcCid() || !$regExp || !preg_match($regExp, $info->getCcCid())) {
176  $errorMsg = __('Please enter a valid credit card verification number.');
177  }
178  }
179 
180  if ($ccType != 'SS' && !$this->_validateExpDate($info->getCcExpYear(), $info->getCcExpMonth())) {
181  $errorMsg = __('Please enter a valid credit card expiration date.');
182  }
183 
184  if ($errorMsg) {
185  throw new \Magento\Framework\Exception\LocalizedException($errorMsg);
186  }
187 
188  return $this;
189  }
190 
195  public function hasVerification()
196  {
197  $configData = $this->getConfigData('useccv');
198  if ($configData === null) {
199  return true;
200  }
201  return (bool)$configData;
202  }
203 
208  public function getVerificationRegEx()
209  {
210  $verificationExpList = [
211  'VI' => '/^[0-9]{3}$/',
212  'MC' => '/^[0-9]{3}$/',
213  'AE' => '/^[0-9]{4}$/',
214  'DI' => '/^[0-9]{3}$/',
215  'DN' => '/^[0-9]{3}$/',
216  'UN' => '/^[0-9]{3}$/',
217  'SS' => '/^[0-9]{3,4}$/',
218  'SM' => '/^[0-9]{3,4}$/',
219  'SO' => '/^[0-9]{3,4}$/',
220  'OT' => '/^[0-9]{3,4}$/',
221  'JCB' => '/^[0-9]{3,4}$/',
222  'MI' => '/^[0-9]{3}$/',
223  'MD' => '/^[0-9]{3}$/',
224  ];
225  return $verificationExpList;
226  }
227 
233  protected function _validateExpDate($expYear, $expMonth)
234  {
235  $date = new \DateTime();
236  if (!$expYear || !$expMonth || (int)$date->format('Y') > $expYear
237  || (int)$date->format('Y') == $expYear && (int)$date->format('m') > $expMonth
238  ) {
239  return false;
240  }
241  return true;
242  }
243 
251  public function assignData(\Magento\Framework\DataObject $data)
252  {
253  $additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA);
254  if (!is_object($additionalData)) {
255  $additionalData = new DataObject($additionalData ?: []);
256  }
257 
259  $info = $this->getInfoInstance();
260  $info->addData(
261  [
262  'cc_type' => $additionalData->getCcType(),
263  'cc_owner' => $additionalData->getCcOwner(),
264  'cc_last_4' => substr($additionalData->getCcNumber(), -4),
265  'cc_number' => $additionalData->getCcNumber(),
266  'cc_cid' => $additionalData->getCcCid(),
267  'cc_exp_month' => $additionalData->getCcExpMonth(),
268  'cc_exp_year' => $additionalData->getCcExpYear(),
269  'cc_ss_issue' => $additionalData->getCcSsIssue(),
270  'cc_ss_start_month' => $additionalData->getCcSsStartMonth(),
271  'cc_ss_start_year' => $additionalData->getCcSsStartYear()
272  ]
273  );
274 
275  return $this;
276  }
277 
283  public function otherCcType($type)
284  {
285  return $type == 'OT';
286  }
287 
295  public function validateCcNum($ccNumber)
296  {
297  $cardNumber = strrev($ccNumber);
298  $numSum = 0;
299 
300  for ($i = 0; $i < strlen($cardNumber); $i++) {
301  $currentNum = substr($cardNumber, $i, 1);
302 
306  if ($i % 2 == 1) {
307  $currentNum *= 2;
308  }
309 
313  if ($currentNum > 9) {
314  $firstNum = $currentNum % 10;
315  $secondNum = ($currentNum - $firstNum) / 10;
316  $currentNum = $firstNum + $secondNum;
317  }
318 
319  $numSum += $currentNum;
320  }
321 
325  return $numSum % 10 == 0;
326  }
327 
335  public function validateCcNumOther($ccNumber)
336  {
337  return preg_match('/^\\d+$/', $ccNumber);
338  }
339 
346  public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null)
347  {
348  return $this->getConfigData('cctypes', $quote ? $quote->getStoreId() : null) && parent::isAvailable($quote);
349  }
350 }
$quote
__()
Definition: __.php:13
$resource
Definition: bulk.php:12
$logger
$type
Definition: item.phtml:13
$ccType
Definition: info.phtml:16
foreach( $_productCollection as $_product)() ?>" class $info
Definition: listing.phtml:52
$i
Definition: gallery.phtml:31