/** * Validate the input to the constructor. * @param $values * @throws InvalidArgumentException */ private function validateInput($values) { if (!array_key_exists("name", $values)) { throw new InvalidArgumentException("You must supply a name."); } if (!array_key_exists("number", $values)) { throw new InvalidArgumentException("You must supply a credit card number."); } if (!array_key_exists("expiration_month", $values)) { throw new InvalidArgumentException("You must supply an expiration month"); } if (!array_key_exists("expiration_year", $values)) { throw new InvalidArgumentException("You must supply an expiration year."); } $card = CreditCardValidator::validCreditCard($values['number']); if ($card['valid'] !== true) { throw new InvalidArgumentException("The credit card number is not valid."); } $month = sprintf("%02d", $values['expiration_month']); if (strlen($values['expiration_year']) !== 4) { throw new InvalidArgumentException("You must input a 4 digit year."); } if (!CreditCardValidator::validDate($values['expiration_year'], $month)) { throw new InvalidArgumentException("Expiration date is not valid."); } }
/** * before a new card is saved, store it in the remote card processor * if adding the card fails, then do not save to server * * (non-PHPdoc) * * @see \PhalconRest\API\Entity::afterSave() */ function beforeSave($object, $id) { $processor = $this->getDI()->get('paymentProcessor'); $account = \PhalconRest\Models\Accounts::findFirst($object->account_id); if (!$account->external_id or $account->external_id == null) { $accountExternalId = $processor->createCustomer($account); } else { $accountExternalId = $account->external_id; } // run credit card through a series of validation tests $result = CreditCard::validCreditCard($object->number, $object->vendor); if ($result['valid'] == false) { throw new ValidationException("Bad Credit Card Supplied", ['dev' => "Bad card number supplied: {$object->number}", 'code' => '5846846848644984'], ['number' => 'The supplied credit card number is invalid.']); } else { $object->number = $result['number']; } $result = CreditCard::validDate($object->expiration_year, $object->expiration_month); if ($result == false) { throw new ValidationException("Bad Expiration Date Supplied", ['dev' => "Bad expiration month or year: {$object->expiration_month} | {$object->expiration_year}", 'code' => '81618161684684'], ['expiration_month' => 'The supplied expiration month is invalid.', 'expiration_year' => 'The supplied expiration year is invalid.']); } // put this in until we better populate the credit card form // TODO fix CVC in app // $object->cvc = '123'; $object->external_id = $processor->createCard($accountExternalId, $object); // clear out data we do NOT want to store $object->number = substr($object->number, strlen($object->number) - 4, 4); unset($object->cvc); return $object; }
/** * Bootstrap the application services. * * @return void */ public function boot() { \Validator::extend('ccn', function ($attribute, $value, $parameters, $validator) { return CreditCard::validCreditCard($value)['valid']; }); \Validator::extend('ccd', function ($attribute, $value, $parameters, $validator) { try { $value = explode('/', $value); return CreditCard::validDate(strlen($value[1]) == 2 ? 2000 + $value[1] : $value[1], $value[0]); } catch (\Exception $e) { return false; } }); \Validator::extend('cvc', function ($attribute, $value, $parameters, $validator) { return ctype_digit($value) && (strlen($value) == 3 || strlen($value) == 4); }); }
public function testDate() { // Invalid month $this->assertEquals(false, CreditCard::validDate(date('Y'), '13')); // Invalid year $this->assertEquals(false, CreditCard::validDate(date('Y'), '15')); // Integer values $this->assertEquals(true, CreditCard::validDate(intval(date('Y')), intval(date('m')))); // Not numbers $this->assertEquals(false, CreditCard::validDate('j201', 'd4')); // Past year, future month $timestamp = strtotime('-1 month'); $this->assertEquals(false, CreditCard::validDate(date('Y', $timestamp) - 1, date('m', $timestamp))); // Current year, past month $timestamp = strtotime('-1 month'); $this->assertEquals(false, CreditCard::validDate(date('Y', $timestamp), date('m', $timestamp))); // Current year, current month $this->assertEquals(true, CreditCard::validDate(date('Y'), date('m'))); // Next year $timestamp = strtotime('+1 year'); $this->assertEquals(true, CreditCard::validDate(date('Y', $timestamp), date('m', $timestamp))); }
/** * Create a credit card object from a request containing cc-number, name, and expirationDate * @param $request * @return CreditCard */ private function createCreditCardObjectFromRequest($request) { $card = CreditCardValidator::validCreditCard(trim(str_replace(" ", "", $request->input('cc-number')))); if ($card['valid'] !== true) { throw new InvalidArgumentException(trans("errors.invalidCreditCardNumber")); } $expiration = $request->input('expirationDate'); $boom = explode(" / ", $expiration); $month = ltrim(trim($boom[0]), 0); $year = trim($boom[1]); if (strlen($year) == 2) { $now = Carbon::now(Config::get("app.timezone")); $year = substr($now->year, 0, 2) . $year; } if (CreditCardValidator::validDate($year, $month) !== true) { throw new InvalidArgumentException(trans("errors.invalidExpirationDate")); } $creditCard = new CreditCard(['name' => $request->input('name'), 'number' => $card['number'], 'expiration_month' => intval($month), 'expiration_year' => $year]); return $creditCard; }
/** * Get a list of unexpired credit cards on the account (see https://sonar.software/apidoc/index.html#api-Account_Payment_Methods-GetAccountPaymentMethods). This does not return CreditCard objects, but just the raw API return. This is because the credit card objects * don't really match up - we can't access the credit card number, for example. * @param $accountID * @return array * @throws ApiException */ public function getValidCreditCards($accountID) { $return = []; $result = $this->httpHelper->get("accounts/" . intval($accountID) . "/payment_methods"); foreach ($result as $datum) { if ($datum->type != "credit card") { continue; } try { if (\Inacho\CreditCard::validDate($datum->expiration_year, sprintf("%02d", $datum->expiration_month)) !== true) { continue; } } catch (Exception $e) { continue; } array_push($return, $datum); } return $return; }