Payment_Process
[ class tree: Payment_Process ] [ index: Payment_Process ] [ all elements ]

Source for file Process.php

Documentation is available at Process.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available through the world-wide-web at                              |
  11. // | http://www.php.net/license/3_0.txt.                                  |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Ian Eure <ieure@php.net>                                    |
  17. // |          Joe Stump <joe@joestump.net>                                |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Process.php,v 1.30 2004/05/03 16:35:40 jstump Exp $
  21.  
  22. require_once 'PEAR.php';
  23. require_once 'Validate.php';
  24. require_once 'Payment/Process/Type.php';
  25.  
  26. // Error codes
  27. define('PAYMENT_PROCESS_ERROR_NOTIMPLEMENTED'-100);
  28. define('PAYMENT_PROCESS_ERROR_NOFIELD'-101);
  29. define('PAYMENT_PROCESS_ERROR_NOPROCESSOR'-102);
  30. define('PAYMENT_PROCESS_ERROR_INCOMPLETE'-1);
  31. define('PAYMENT_PROCESS_ERROR_INVAILD'-2);
  32. define('PAYMENT_PROCESS_ERROR_AVS',-3);
  33. define('PAYMENT_PROCESS_ERROR_CVV',-4);
  34.  
  35. // Transaction actions
  36. // A normal transaction
  37. define('PAYMENT_PROCESS_ACTION_NORMAL'200);
  38. // Authorize only. No funds are transferred.
  39. define('PAYMENT_PROCESS_ACTION_AUTHONLY'201);
  40. // Credit funds back from a previously-charged transaction.
  41. define('PAYMENT_PROCESS_ACTION_CREDIT'202);
  42. // Post-authorize an AUTHONLY transaction.
  43. define('PAYMENT_PROCESS_ACTION_POSTAUTH'203);
  44.  
  45. // Transaction sources
  46. define('PAYMENT_PROCESS_SOURCE_POS'300);
  47. define('PAYMENT_PROCESS_SOURCE_ONLINE'301);
  48.  
  49. // Results
  50. define('PAYMENT_PROCESS_RESULT_APPROVED'400);
  51. define('PAYMENT_PROCESS_RESULT_DECLINED'401);
  52. define('PAYMENT_PROCESS_RESULT_OTHER'402);
  53. define('PAYMENT_PROCESS_RESULT_FRAUD'403);
  54. define('PAYMENT_PROCESS_RESULT_DUPLICATE',404);
  55.  
  56. define('PAYMENT_PROCESS_AVS_MATCH',500);
  57. define('PAYMENT_PROCESS_AVS_MISMATCH',501);
  58. define('PAYMENT_PROCESS_AVS_ERROR',502);
  59. define('PAYMENT_PROCESS_AVS_NOAPPLY',503);
  60.  
  61. define('PAYMENT_PROCESS_CVV_MATCH',600);
  62. define('PAYMENT_PROCESS_CVV_MISMATCH',601);
  63. define('PAYMENT_PROCESS_CVV_ERROR',602);
  64. define('PAYMENT_PROCESS_CVV_NOAPPLY',603);
  65.  
  66. /**
  67.  * Payment_Process
  68.  *
  69.  * @author Ian Eure <ieure@php.net>
  70.  * @package Payment_Process
  71.  * @category Payment
  72.  * @version @version@
  73.  */
  74. class Payment_Process extends PEAR {
  75.  
  76.     /**
  77.      * Options.
  78.      *
  79.      * @see setOptions()
  80.      * @access private;
  81.      */
  82.     var $_options '';
  83.  
  84.     /**
  85.      * Your login name to use for authentication to the online processor.
  86.      */
  87.     var $login = '';
  88.  
  89.     /**
  90.      * Your password to use for authentication to the online processor.
  91.      */
  92.     var $password = '';
  93.  
  94.     /**
  95.      * Processing action.
  96.      *
  97.      * This should be set to one of the PAYMENT_PROCESS_ACTION_* constants.
  98.      */
  99.     var $action = '';
  100.  
  101.     /**
  102.      * A description of the transaction (used by some processors to send
  103.      * information to the client, normally not a required field).
  104.      */
  105.     var $description = '';
  106.  
  107.     /**
  108.      * The transaction amount.
  109.      */
  110.     var $amount = 0;
  111.  
  112.     /**
  113.      * An invoice number.
  114.      */
  115.     var $invoiceNumber = '';
  116.  
  117.     /**
  118.      * Customer identifier
  119.      */
  120.     var $customerId = '';
  121.  
  122.     /**
  123.      * Transaction source.
  124.      *
  125.      * This should be set to one of the PAYMENT_PROCESS_SOURCE_* constants.
  126.      */
  127.     var $transactionSource;
  128.  
  129.     /**
  130.      * Array of fields which are required.
  131.      *
  132.      * @type array
  133.      * @access private
  134.      * @see _makeRequired()
  135.      */
  136.     var $_required = array();
  137.     
  138.     /**
  139.      * Processor-specific data.
  140.      *
  141.      * @access private
  142.      * @type array
  143.      */
  144.     var $_data = array();
  145.  
  146.     /**
  147.      * $_driver
  148.      *
  149.      * @author Joe Stump <joe@joestump.net>
  150.      * @var string $_driver 
  151.      * @access private
  152.      */
  153.     var $_driver = null;
  154.  
  155.     /**
  156.      * Return an instance of a specific processor.
  157.      *
  158.      * @param  string  $type     Name of the processor
  159.      * @param  array   $options  Options for the processor
  160.      * @return mixed Instance of the processor object, or a PEAR_Error object.
  161.      */
  162.     function &factory($type$options = false)
  163.     {
  164.         $class "Payment_Process_".$type;
  165.         if (include_once "Payment/Process/{$type}.php"{
  166.             if (class_exists($class)) {
  167.                 $object new $class($options);
  168.                 $object->_driver = $type;
  169.                 return $object;
  170.             
  171.         }
  172.  
  173.         return PEAR::raiseError('"'.$type.'" processor does not exist'
  174.                                 PAYMENT_PROCESS_ERROR_NOPROCESSOR);
  175.  
  176.     }
  177.  
  178.     /**
  179.      * Set many fields.
  180.      *
  181.      * @param  array  $where  Associative array of data to set, in the format
  182.      *                        'field' => 'value',
  183.      * @return void 
  184.      */
  185.     function setFrom($where)
  186.     {
  187.         foreach ($this->getFields(as $field{
  188.             if (isset($where[$field])) {
  189.                 $this->$field $where[$field];
  190.             }
  191.         }
  192.     }
  193.  
  194.     /**
  195.      * Set a value.
  196.      *
  197.      * This will set a value, such as the credit card number. If the requested
  198.      * field is not part of the basic set of supported fields, it is set in
  199.      * $_options.
  200.      *
  201.      * @param  string  $field  The field to set
  202.      * @param  string  $value  The value to set
  203.      * @return void 
  204.      */
  205.     function set($field$value)
  206.     {
  207.         if (!$this->fieldExists($field)) {
  208.             return PEAR::raiseError("Field \"$field\" does not exist."PAYMENT_PROCESS_ERROR_INVALID);
  209.         }
  210.         $this->$field $value;
  211.         return true;
  212.     }
  213.     
  214.     /**
  215.      * Mark a field as being required.
  216.      *
  217.      * @param $field Field name
  218.      * @param ... 
  219.      * @return boolean always true.
  220.      */
  221.     function _makeRequired()
  222.     {
  223.         foreach (func_get_args(as $field{
  224.             $this->_required[$field= true;
  225.         }
  226.         return true;
  227.     }
  228.     
  229.     /**
  230.      * Mark a field as being optional.
  231.      *
  232.      * @param $field Field name
  233.      * @param ... 
  234.      * @return boolean always true.
  235.      */
  236.     function _makeOptional()
  237.     {
  238.         foreach (func_get_args(as $field{
  239.             unset($this->_required[$field]);
  240.         }
  241.         return true;
  242.     }
  243.     
  244.     /**
  245.      * Determine if a field is required.
  246.      *
  247.      * @param string $field Field to check
  248.      * @return boolean true if required, false if optional.
  249.      */
  250.     function isRequired($field)
  251.     {
  252.         return (isset($this->_required[$field]));
  253.     }
  254.  
  255.     /**
  256.      * Determines if a field exists.
  257.      *
  258.      * @author Ian Eure <ieure@php.net>
  259.      * @param  string  $field  Field to check
  260.      * @return boolean true if field exists, false otherwise
  261.      */
  262.     function fieldExists($field)
  263.     {
  264.         return @in_array($field$this->getFields());
  265.     }
  266.  
  267.     /**
  268.      * Get a list of fields.
  269.      *
  270.      * This function returns an array containing all the possible fields which
  271.      * may be set.
  272.      *
  273.      * @author Ian Eure <ieure@php.net>
  274.      * @access public
  275.      * @return array Array of valid fields.
  276.      */
  277.     function getFields()
  278.     {
  279.         $vars array_keys(get_class_vars(get_class($this)));
  280.         foreach ($vars as $idx => $field{
  281.             if (ereg('^_+'$field)) {
  282.                 unset($vars[$idx]);
  283.             }
  284.         }
  285.         return $vars;
  286.     }
  287.  
  288.     /**
  289.      * Set class options.
  290.      *
  291.      * @author Ian Eure <ieure@php.net>
  292.      * @param  Array  $options         Options to set
  293.      * @param  Array  $defaultOptions  Default options
  294.      * @return void 
  295.      */
  296.     function setOptions($options = false$defaultOptions = false)
  297.     {
  298.         $defaultOptions $defaultOptions $defaultOptions $this->_defaultOptions;
  299.         $this->_options @array_merge($defaultOptions$options);
  300.     }
  301.  
  302.     /**
  303.      * Get an option value.
  304.      *
  305.      * @author Ian Eure <ieure@php.net>
  306.      * @param  string  $option  Option to get
  307.      * @return mixed Option value
  308.      */
  309.     function getOption($option)
  310.     {
  311.         return @$this->_options[$option];
  312.     }
  313.  
  314.     /**
  315.      * Set an option value
  316.      *
  317.      * @author Joe Stump <joe@joestump.net>
  318.      * @access public
  319.      * @param string $option Option name to set
  320.      * @param mixed $value Value to set
  321.      */
  322.     function setOption($option,$value)
  323.     {
  324.         return ($this->_options[$option$value);
  325.     }
  326.  
  327.     /**
  328.      * See if a value is a defined constant.
  329.      *
  330.      * This function checks to see if $value is defined in one of
  331.      * PAYMENT_PROCESS_{$class}_*. It's used to verify that e.g. $object->action is one of
  332.      * PAYMENT_PROCESS_ACTION_NORMAL, PAYMENT_PROCESS_ACTION_AUTHONLY etc.
  333.      *
  334.      * @access private
  335.      * @param  mixed  $value  Value to check
  336.      * @param  mixed  $class  Constant class to check
  337.      * @return boolean true if it is defined, false otherwise.
  338.      */
  339.     function _isDefinedConst($value$class)
  340.     {
  341.         $re '^PAYMENT_PROCESS_'.strtoupper($class).'_.*';
  342.         $consts get_defined_constants();
  343.         foreach ($consts as $constant => $constVal{
  344.             if (ereg($re$constant)) {
  345.                 $valid[$constVal;
  346.             }
  347.         }
  348.         return @in_array($value$valid);
  349.     }
  350.  
  351.     /**
  352.     * Statically check a Payment_Result class for success
  353.     *
  354.     * @author Joe Stump <joe@joestump.net>
  355.     * @access public
  356.     * @param mixed $obj 
  357.     */
  358.     function isSuccess($obj)
  359.     {
  360.         if (is_a($obj,'Payment_Process_Result')) {
  361.             if ($obj->getCode(== PAYMENT_PROCESS_RESULT_APPROVED{
  362.                 return true;
  363.             }
  364.         }
  365.   
  366.         return false;
  367.     }
  368.  
  369.     /**
  370.     * Statically check a Payment_Result class for error
  371.     *
  372.     * @author Joe Stump <joe@joestump.net>
  373.     * @access public
  374.     * @param mixed $obj 
  375.     */
  376.     function isError($obj)
  377.     {
  378.         if (PEAR::isError($obj)) {
  379.             return true; 
  380.         }
  381.  
  382.         if (is_a($obj,'Payment_Process_Result')) {
  383.             if ($obj->getCode(!= PAYMENT_PROCESS_RESULT_APPROVED{
  384.                 return true;
  385.             }
  386.         }
  387.  
  388.         return false;
  389.     
  390. }
  391.  
  392. /**
  393.  * Payment_Process_Result
  394.  *
  395.  * The core result class that should be returned from each driver's process()
  396.  * function. This should be extended as Payment_Process_Result_DriverName and
  397.  * then have the appropriate fields mapped out accordingly.
  398.  *
  399.  * Take special care to appropriately create a parse() function in your result
  400.  * class. You can then call _mapFields() with a resultArray (ie. exploded
  401.  * result) to map your results from parse() into the member variables.
  402.  *
  403.  * Please note that this class keeps your original codes intact so they can
  404.  * be accessed directly and then uses the function wrappers to return uniform
  405.  * Payment_Process codes.
  406.  *
  407.  * @author Joe Stump <joe@joestump.net>
  408.  * @package Payment_Process
  409.  * @category Payment
  410.  * @version @version@
  411.  */
  412.  
  413.     /**
  414.      * Processor instance which this result was instantiated from.
  415.      *
  416.      * This should contain a reference to the requesting Processor.
  417.      *
  418.      * @author Ian Eure <ieure@php.net>
  419.      * @access private
  420.      * @type Object
  421.      */
  422.     var $_request;
  423.     
  424.     /**
  425.     * The raw response (ie. from cURL)
  426.     *
  427.     * @author Joe Stump <joe@joestump.net>
  428.     * @access protected
  429.     * @var string $_rawResponse 
  430.     */
  431.     var $_rawResponse = null;
  432.  
  433.     /**
  434.     * The approval/decline code
  435.     *
  436.     * The value returned by your gateway as approved/declined should be mapped
  437.     * into this variable. Valid results should then be mapped into the
  438.     * appropriate PAYMENT_PROCESS_RESULT_* code using the $_statusCodeMap
  439.     * array. Values returned into $code should be mapped as keys in the map
  440.     * with PAYMENT_PROCESS_RESULT_* as the values.
  441.     *
  442.     * @author Joe Stump <joe@joestump.net>
  443.     * @access public
  444.     * @var mixed $code 
  445.     * @see PAYMENT_PROCESS_RESULT_APPROVED, PAYMENT_PROCESS_RESULT_DECLINED
  446.     * @see PAYMENT_PROCESS_RESULT_OTHER, $_statusCodeMap
  447.     */
  448.     var $code;
  449.  
  450.     /**
  451.     * Message/Response Code
  452.     *
  453.     * Along with the response (yes/no) you usually get a response/message
  454.     * code that translates into why it was approved/declined. This is where
  455.     * you map that code into. Your $_statusCodeMessages would then be keyed by
  456.     * valid messageCode values.
  457.     *
  458.     * @author Joe Stump <joe@joestump.net>
  459.     * @access public
  460.     * @var mixed $messageCode 
  461.     * @see $_statusCodeMessages
  462.     */
  463.     var $messageCode;
  464.  
  465.     /**
  466.     * Message from gateway
  467.     *
  468.     * Map the textual message from the gateway into this variable. It is not
  469.     * currently returned or used (in favor of the $_statusCodeMessages map, but
  470.     * can be accessed directly for debugging purposes.
  471.     *
  472.     * @author Joe Stump <joe@joestump.net>
  473.     * @access public
  474.     * @var string $message 
  475.     * @see $_statusCodeMessages
  476.     */
  477.     var $message = 'No message from gateway';
  478.  
  479.     /**
  480.     * Authorization/Approval code
  481.     *
  482.     * @author Joe Stump <joe@joestump.net>
  483.     * @access public
  484.     * @var string $approvalCode 
  485.     */
  486.     var $approvalCode;
  487.  
  488.     /**
  489.     * Address verification code
  490.     *
  491.     * The AVS code returned from your gateway. This should then be mapped to
  492.     * the appropriate PAYMENT_PROCESS_AVS_* code using $_avsCodeMap. This value
  493.     * should also be mapped to the appropriate textual message via the
  494.     * $_avsCodeMessages array.
  495.     *
  496.     * @author Joe Stump <joe@joestump.net>
  497.     * @access public
  498.     * @var string $avsCode 
  499.     * @see PAYMENT_PROCESS_AVS_MISMATCH, PAYMENT_PROCESS_AVS_ERROR
  500.     * @see PAYMENT_PROCESS_AVS_MATCH, PAYMENT_PROCESS_AVS_NOAPPLY, $_avsCodeMap
  501.     * @see $_avsCodeMessages
  502.     */
  503.     var $avsCode;
  504.  
  505.     /**
  506.     * Transaction ID
  507.     *
  508.     * This is the unique transaction ID, which is used by gateways to modify
  509.     * transactions (credit, update, etc.). Map the appropriate value into this
  510.     * variable.
  511.     *
  512.     * @author Joe Stump <joe@joestump.net>
  513.     * @access public
  514.     * @var string $transactionId 
  515.     */
  516.     var $transactionId;
  517.  
  518.     /**
  519.     * Invoice Number
  520.     *
  521.     * Unique internal invoiceNumber (ie. your company's order/invoice number
  522.     * that you assign each order as it is processed). It is always a good idea
  523.     * to pass this to the gateway (which is usually then echo'd back).
  524.     *
  525.     * @author Joe Stump <joe@joestump.net>
  526.     * @access public
  527.     * @var string $invoiceNumber 
  528.     */
  529.     var $invoiceNumber;
  530.  
  531.     /**
  532.     * Customer ID
  533.     *
  534.     * Unique internall customer ID (ie. your company's customer ID used to
  535.     * track individual customers).
  536.     *
  537.     * @author Joe Stump <joe@joestump.net>
  538.     * @access public
  539.     * @var string $customerId 
  540.     */
  541.     var $customerId;
  542.  
  543.     /**
  544.     * CVV Code
  545.     *
  546.     * The CVV code is the 3-4 digit number on the back of most credit cards.
  547.     * This value should be mapped via the $_cvvCodeMap variable to the
  548.     * appropriate PAYMENT_PROCESS_CVV_* values.
  549.     *
  550.     * @author Joe Stump <joe@joestump.net>
  551.     * @access public
  552.     * @var string $cvvCode 
  553.     */
  554.     var $cvvCode = PAYMENT_PROCESS_CVV_NOAPPLY;
  555.  
  556.     /**
  557.     * CVV Message
  558.     *
  559.     * Your cvvCode value should be mapped to appropriate messages via the
  560.     * $_cvvCodeMessage array. This value is merely here to hold the value
  561.     * returned from the gateway (if any).
  562.     *
  563.     * @author Joe Stump <joe@joestump.net>
  564.     * @access public
  565.     * @var string $cvvMessage 
  566.     */
  567.     var $cvvMessage = 'No CVV message from gateway';
  568.  
  569.     function Payment_Process_Result($rawResponse
  570.     {
  571.         $this->_rawResponse = $rawResponse;
  572.     }
  573.  
  574.     function &factory($type,$rawResponse)
  575.     {
  576.         $class 'Payment_Process_Result_'.$type;
  577.         if (class_exists($class)) {
  578.             return new $class($rawResponse);
  579.         }
  580.  
  581.         return PEAR::raiseError('Invalid response type: '.$type.'('.$class.')');
  582.     }
  583.  
  584.     // {{{ validate()
  585.     /**
  586.     * validate
  587.     * 
  588.     * @author Joe Stump <joe@joestump.net>
  589.     * @access public
  590.     * @return mixed 
  591.     */
  592.     function validate()
  593.     {
  594.         if ($this->_request->getOption('avsCheck'=== true{
  595.             if ($this->getAVSCode(!= PAYMENT_PROCESS_AVS_MATCH{
  596.                 return PEAR::raiseError('AVS check failed',
  597.                                         PAYMENT_PROCESS_ERROR_AVS);
  598.             }
  599.         }    
  600.  
  601.         $paymentType $this->_request->_payment->_driver;
  602.         if ($this->_request->getOption('cvvCheck'=== true &&
  603.             $paymentType == PAYMENT_PROCESS_TYPE_CREDITCARD{
  604.  
  605.             if ($this->getCvvCode(!= PAYMENT_PROCESS_CVV_MATCH{
  606.                 return PEAR::raiseError('CVV check failed',
  607.                                         PAYMENT_PROCESS_ERROR_CVV);
  608.             }
  609.  
  610.         }
  611.  
  612.         if ($this->getCode(!= PAYMENT_PROCESS_RESULT_APPROVED{
  613.             return PEAR::raiseError($this->getMessage(),
  614.                                     PAYMENT_PROCESS_RESULT_DECLINED)
  615.         
  616.  
  617.         return true;
  618.     }
  619.     // }}}
  620.  
  621.     // {{{ parse()
  622.     /**
  623.     * parse
  624.     *
  625.     * @abstract
  626.     * @author Joe Stump <joe@joestump.net>
  627.     * @access public
  628.     */
  629.     function parse(
  630.     {
  631.         return PEAR::raiseError('parse() not implemented',
  632.                                 PAYMENT_PROCESS_ERROR_NOTIMPLEMENTED);
  633.     }
  634.     // }}}
  635.  
  636.     // {{{ getCode()
  637.     /**
  638.     * getCode
  639.     *  
  640.     * @author Joe Stump <joe@joestump.net>
  641.     * @access public
  642.     */
  643.     function getCode(
  644.     {
  645.         if (isset($this->_statusCodeMap[$this->code])) {
  646.             return $this->_statusCodeMap[$this->code];
  647.         else {
  648.             return PAYMENT_PROCESS_RESULT_DECLINED;
  649.         }
  650.     }
  651.     // }}}
  652.  
  653.     // {{{ getMessage()
  654.     /**
  655.     * getMessage
  656.     *
  657.     * Return the message from the code map, or return the raw message if
  658.     * there is one. Otherwise, return a worthless message.
  659.     *
  660.     * @author Joe Stump <joe@joestump.net>
  661.     * @access public
  662.     * @return string 
  663.     */
  664.     function getMessage(
  665.     {
  666.         if (isset($this->_statusCodeMessages[$this->messageCode])) {
  667.             return $this->_statusCodeMessages[$this->messageCode];
  668.         elseif(strlen($this->message)) {
  669.             return $this->message
  670.         else {
  671.             return 'No message reported';
  672.         }
  673.     }
  674.     // }}} 
  675.  
  676.     function getAVSCode(
  677.     {
  678.         return $this->_avsCodeMap[$this->avsCode];
  679.     }
  680.  
  681.     function getAVSMessage(
  682.     {
  683.         return $this->_avsCodeMessages[$this->avsCode];
  684.     }
  685.  
  686.     function getCvvCode()
  687.     {
  688.         return $this->_cvvCodeMap[$this->cvvCode];
  689.     }
  690.  
  691.     function getCvvMessage()
  692.     {
  693.         return $this->_cvvCodeMessages[$this->cvvCode];
  694.     }
  695.  
  696.     // {{{ _mapFields()
  697.     /**
  698.     * _mapFields
  699.     *
  700.     * @author Joe Stump <joe@joestump.net>
  701.     * @access private
  702.     * @param mixed $responseArray 
  703.     */
  704.     function _mapFields($responseArray{
  705.         foreach($this->_fieldMap as $key => $val{
  706.             $this->$val $responseArray[$key]
  707.         }
  708.     }
  709.     // }}}
  710. }
  711.  
  712. ?>

Documentation generated on Mon, 11 Mar 2019 13:51:27 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.