Open-Source PHP Framework - Designed for rapid development of performance-oriented scalable applications

/mvc/components/cc

[return to app]
1
<?php
/**
 * Credit Card functions
 */
class ccComponent {
    /**
     * These properties store the response from AuthorizeNet after a charge
     *
     * @var string
     */
    public $authnetResponse, $authnetResponseText, $authnetApprovalCode, $authnetTransactionId;

    /**
     * Every second digit in the Mod 10 (Luhn) algorithm gets doubled and then the resulting digit(s) are added
 
together * This array maps the orignal number to the digit after the Mod 10 equation */ protected $_mod10digits = array(0 => 0, 1 => 2, 2 => 4, 3 => 6, 4 => 8, 5 => 1, 6 => 3, 7 => 5, 8 => 7, 9 =>
 
9); /** * Standard credit card test numbers; these will validate Mod 10 but are never valid credit card accounts * * @var array */ public $ccTestNumbers = array(5105105105105100, 5555555555554444, 4222222222222, 4111111111111111, 4012888888881881, 378282246310005, 371449635398431, 378734493671000, 38520000023237, 30569309025904, 6011111111111117, 6011000990139424, 3530111333300000, 3566002020360505); /** * Credit card types; keys mapped to the AuthorizeNet card type response * * @var array */ public $cardTypes = array(4 => 'Visa', 5 => 'MasterCard', 3 => 'American Express', 6 => 'Discover Card', 8 => 'Diners Club', 1 => 'JCB (Japanese Credit Bureau)', 7 => 'Australian
 BankCard'
, 2 => 'enRoute'); /** * Validates the length of credit card number is correct for the card type * * @param int $cc * @param int $cardType This must match the key from the $this->cardTypes array * @return boolean */ public function isValidCcLength($cc, $cardType) { $length[16] = array(1, 4, 5, 6, 7); //JCB, Visa, MasterCard, Discover Card, Australian BankCard $length[15] = array(1, 2, 3); //JCB, enRoute, American Express $length[14] = array(8); //Diners Club $length[13] = array(4); //Visa $ccLength = strlen($cc); return (isset($length[$ccLength]) && in_array($cardType, $length[$ccLength])); } /** * Flag set by $this->getCardType() if a Diners Club card is a CarteBlanch card * * @var boolean */ public $isCarteBlanch; /** * Determines credit card type by the credit card number * * @param int $cc Can be the first four digits of the credit card number, the entire number or anything in
 
between * @return int Matches the keys in $this->cardTypes */ public function getCardType($cc, $returnHumanReadable = true) { $cardType = 0; $prefix = substr($cc, 0, 4); if ($prefix >= 4000 && $prefix <= 4999) { $cardType = 4; //Visa } else if ($prefix >= 5100 && $prefix <= 5599) { $cardType = 5; //MasterCard } else if (($prefix >= 3400 && $prefix <= 3499) || ($prefix >= 3700 && $prefix <= 3799)) { $cardType = 3; //American Express } else if (($prefix >= 3000 && $prefix <= 3059) || ($prefix >= 3600 && $prefix <= 3699) || ($prefix >= 3800 && $prefix <= 3899)) { $cardType = 8; //Diners Club $this->isCarteBlanch = ($prefix >= 3890 && $prefix <= 3899); } else if ($prefix >= 3528 && $prefix <= 3589) { $cardType = 1; //JCB } else { switch ($prefix) { case 6011: $cardType = 6; //Discover Card break; case 1800: case 2131: $cardType = 1; //JCB break; case 2014: case 2149: $cardType = 2; //enRoute break; case 5610: $cardType = 7; //Australian BankCard break; } } if ($cardType && $returnHumanReadable && isset($this->cardTypes[$cardType])) { $cardType = $this->cardTypes[$cardType]; } return $cardType; } /** * Verifies if a credit card number passes the Mod 10 specification * * @param int $cc * @return boolean */ public function isMod10Valid($cc) { $cclen = strlen($cc); if ($cclen > 16 || $cclen < 13 || !is_numeric($cc)) { return false; } $digitsum = 0; $currentbit = 1; $startbit = ($cclen % 2); for ($x = 0; $x < $cclen; $x++) { $currentbit =! $currentbit; if ($currentbit == $startbit) { $cc[$x] = $this->_mod10digits[$cc[$x]]; } $digitsum += $cc[$x]; } return (boolean) !($digitsum % 10); } /** * Charges a credit card through AuthorizeNet and records meta data in properties: * $this->authnetResponse, $this->authnetResponseText, $this->authnetApprovalCode and
 
$this->authnetTransactionId * * Requires AUTHNET_LOGIN and AUTHNET_PASSWORD to be set in the .config * * @param float $amount * @param int $cc * @param string $exp * @return int 1=approved, 2=declined, 3=error */ public function chargeAuthNet($amount, $cc, $exp) { $postfields = array('x_login' => get::$config->AUTHNET_LOGIN, 'x_password' => get::$config->AUTHNET_PASSWORD, 'x_version' => '3.1', 'x_delim_data' => 'TRUE', 'x_method' => 'CC', 'x_type' => 'AUTH_CAPTURE', 'x_customer_ip' => $_SERVER['REMOTE_ADDR'], 'x_amount' => $amount, 'x_card_num' => $cc, 'x_exp_date' => $exp); $postdata = http_build_query($postfields); $sockheader = 'POST /gateway/transact.dll HTTP/1.0' . PHP_EOL . 'Host: secure.authorize.net' . PHP_EOL . 'Content-type: application/x-www-form-urlencoded' . PHP_EOL . 'Content-length: ' . strlen($postdata) . PHP_EOL . 'Accept: */*'; $fp = stream_socket_client('ssl://secure.authorize.net:443', $errno, $errstr, 30); fwrite($fp, $sockheader . PHP_EOL . PHP_EOL . $postdata . PHP_EOL . PHP_EOL); while(trim(fgets($fp, 128))); //error-suppression is needed for connecting to older IIS servers that do not close the connection
 properly
$responsestring = @fgets($fp); fclose($fp); $this->authnetResponse = explode(',', $responsestring); $this->authnetResponseText = $this->authnetResponse[3]; $this->authnetApprovalCode = $this->authnetResponse[4]; $this->authnetTransactionId = $this->authnetResponse[6]; return $this->authnetResponse[0]; } /** * Redirect a user to a Google Payment checkout prepopulated with their order (& directing payment to your
 
account) * * @param array $items */ public function redirectToGoogleCheckout(array $items) { $data = '<?xml version="1.0" encoding="UTF-8"?> <checkout-shopping-cart xmlns="http://checkout.google.com/schema/2"> <shopping-cart> <items>'; foreach ($items as $item) { $currency = (!isset($item['currency']) ? 'USD' : $item['currency']); $data .= ' <item> <item-name>' . $item['name'] . '</item-name> <item-description>' . $item['description'] . '</item-description> <unit-price currency="' . $currency . '">' . $item['price'] . '</unit-price> <quantity>' . (!isset($item['quantity']) ? 1 : $item['quantity']) . '</quantity> </item>'; } $data .= ' </items> </shopping-cart> <checkout-flow-support> <merchant-checkout-flow-support/> </checkout-flow-support> </checkout-shopping-cart> '; if (!get::$config->GOOGLE_CHECKOUT['useSandbox']) { $credentials = get::$config->GOOGLE_CHECKOUT['live']; $url = 'checkout.google.com/api/checkout/v2/request/Merchant/'; } else { $credentials = get::$config->GOOGLE_CHECKOUT['sandbox']; $url = 'sandbox.google.com/checkout/api/checkout/v2/request/Merchant/'; } $url = 'https://' . $credentials['id'] . ':' . $credentials['key'] . '@' . $url . $credentials['id']; $errorLevel = error_reporting(E_ERROR); $xml = get::component('post')->postRequest($url, $data); error_reporting($errorLevel); if ($xml) { $url = trim(html_entity_decode(strip_tags($xml))); load::redirect($url); } else { error_log('No Google Payment URL returned from: ' . $data); } } }