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

Source for file Bibit.php

Documentation is available at Bibit.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 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: Robin Ericsson <lobbin@localhost.nu>                        |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Bibit.php,v 1.6 2005/07/28 02:52:58 jstump Exp $
  20.  
  21. require_once('Payment/Process.php');
  22. require_once('Payment/Process/Common.php');
  23. require_once('Net/Curl.php');
  24. require_once('XML/Util.php');
  25. require_once('XML/XPath.php');
  26.  
  27. define('PAYMENT_PROCESS_ACTION_BIBIT_AUTH'300);
  28. define('PAYMENT_PROCESS_ACTION_BIBIT_REDIRECT'400);
  29. define('PAYMENT_PROCESS_ACTION_BIBIT_REFUND'500);
  30. define('PAYMENT_PROCESS_ACTION_BIBIT_CAPTURE'600);
  31.  
  32. // Map actions
  33. $GLOBALS['_Payment_Process_Bibit'= array(
  34.     PAYMENT_PROCESS_ACTION_SETTLE   => PAYMENT_PROCESS_ACTION_BIBIT_CAPTURE,
  35. );
  36.  
  37. /**
  38.  * Payment_Process_Bibit
  39.  *
  40.  * This is a process for Bibit's merchant payment gateway.
  41.  * (http://www.bibit.com)
  42.  *
  43.  * *** WARNING ***
  44.  * This is BETA code, and hos not been fully tested. It is not recommended
  45.  * that you use it in a production environment without further testing.
  46.  *
  47.  * @package Payment_Process
  48.  * @author Robin Ericsson <lobbin@localhost.nu>
  49.  * @version @version@
  50.  */
  51. class Payment_Process_Bibit extends Payment_Process_Common {
  52.     /**
  53.      * Front-end -> back-end field map.
  54.      *
  55.      * This array contains the mapping from front-end fields (defined in
  56.      * the Payment_Process class) to the field names Bibit requires.
  57.      *
  58.      * @see _prepare()
  59.      * @access private
  60.      */
  61.     var $_fieldMap = array(
  62.         // Required
  63.         'login' => 'x_login',
  64.         'password' => 'x_password',
  65.         'ordercode' => 'x_ordercode',
  66.         'description' => 'x_descr',
  67.         'amount' => 'x_amount',
  68.         'currency' => 'x_currency',
  69.         'exponent' => 'x_exponent',
  70.         'action' => 'x_action',
  71.         // Optional
  72.         'ordercontent' => 'x_ordercontent',
  73.         'shopper_ip_address' => 'shopperIPAddress',
  74.         'shopper_email_address' => 'shopperEmailAddress',
  75.         'session_id' => 'sessionId',
  76.         'authenticated_shopper_id' => 'authenticatedShopperID',
  77.         'shipping_address' => 'shippingAddress',
  78.         'payment_method_mask' => 'paymentMethodMask',
  79.     );
  80.  
  81.     /**
  82.      * Default options for this processor.
  83.      *
  84.      * @see Payment_Process::setOptions()
  85.      * @access private
  86.      */
  87.     var $_defaultOptions = array(
  88.         'authorizeUri' => 'https://secure.bibit.com/jsp/merchant/xml/paymentService.jsp',
  89.         'authorizeTestUri' => 'https://secure-test.bibit.com/jsp/merchant/xml/paymentService.jsp',
  90.         'x_version' => '1.4'
  91.     );
  92.  
  93.     /**
  94.      * The reponse body sent back from the gateway.
  95.      *
  96.      * @access private
  97.      */
  98.     var $_responseBody '';
  99.  
  100.     /**
  101.      * The orders unique code
  102.      *
  103.      * @access private
  104.      */
  105.     var $ordercode '';
  106.  
  107.     /**
  108.      * The order amounts currency
  109.      *
  110.      * @access private
  111.      */
  112.     var $currency '';
  113.  
  114.     /**
  115.      * The order amounts exponent
  116.      * 
  117.      * @access private
  118.      */
  119.     var $exponent = 0;
  120.  
  121.     /**
  122.      * The orders content as displayed at bibit
  123.      *
  124.      * @access private
  125.      */
  126.     var $ordercontent '';
  127.  
  128.     /**
  129.      * The ip-address the order comes from
  130.      *
  131.      * @access private
  132.      */
  133.     var $shopper_ip_address;
  134.  
  135.     /**
  136.      * The shoppers email-address
  137.      *
  138.      * @access private
  139.      */
  140.     var $shopper_email_address;
  141.     
  142.     /**
  143.      * The unique id of the users session
  144.      *
  145.      * @access private
  146.      */
  147.     var $session_id;
  148.     
  149.     /**
  150.      * Unique id of the authenticed shopper
  151.      *
  152.      * @access private
  153.      */
  154.     var $authenticated_shopper_id;
  155.     
  156.     /**
  157.      * Shipping address
  158.      *
  159.      * @access private
  160.      */
  161.     var $shipping_address = array();
  162.    
  163.     /**
  164.      * Payment method mask
  165.      *
  166.      * @access private
  167.      */
  168.     var $payment_method_mask = array();
  169.    
  170.     /**
  171.      * $_typeFieldMap
  172.      *
  173.      * @access protected
  174.      */
  175.     var $_typeFieldMap = array(
  176.         'CreditCard' => array(
  177.             'cvv' => 'x_card_code',
  178.             'expDate' => 'x_exp_date',
  179.             'cardNumber' => 'x_card_num',
  180.         )
  181.     );
  182.  
  183.     /**
  184.      * Constructor.
  185.      *
  186.      * @param array $options Class options to set.
  187.      * @see Payment_Process::setOptions()
  188.      * @return void 
  189.      */
  190.     function __construct($options = false)
  191.     {
  192.         parent::__construct();
  193.         $this->_driver 'Bibit';
  194.         $this->_makeRequired('login''password''ordercode''description''amount''currency''exponent''cardNumber''expDate''action');
  195.  
  196.     }
  197.  
  198.     function Payment_Process_Bibit($options = false)
  199.     {
  200.         $this->__construct($options);
  201.     }
  202.  
  203.     /**
  204.      * Process the transaction.
  205.      *
  206.      * @return mixed Payment_Process_Result on success, PEAR_Error on failure
  207.      */
  208.     function &process()
  209.     {
  210.         // Sanity check
  211.         $result $this->validate();
  212.         if(PEAR::isError($result)) {
  213.             return $result;
  214.         }
  215.  
  216.         // Prepare the data
  217.         $result $this->_prepare();
  218.         if (PEAR::isError($result)) {
  219.             return $result;
  220.         }
  221.  
  222.         // Don't die partway through
  223.         PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
  224.  
  225.         $fields $this->_prepareQueryString();
  226.         $curl new Net_Curl(isset($this->_options['live']$this->_options['authorizeUri'$this->_options['authorizeTestUri']);
  227.         if (PEAR::isError($curl)) {
  228.             PEAR::popErrorHandling();
  229.             return $curl;
  230.         }
  231.  
  232.         $curl->type = 'PUT';
  233.         $curl->fields = $fields;
  234.         $curl->userAgent = 'PEAR Payment_Process_Bibit 0.1';
  235.         $curl->username = $this->_data['x_login'];
  236.         $curl->password = $this->_data['x_password'];
  237.  
  238.         $result &$curl->execute();
  239.         if (PEAR::isError($result)) {
  240.             PEAR::popErrorHandling();
  241.             return $result;
  242.         else {
  243.             $curl->close();
  244.         }
  245.  
  246.         $this->_responseBody trim($result);
  247.         $this->_processed = true;
  248.  
  249.         // Restore error handling
  250.         PEAR::popErrorHandling();
  251.  
  252.         $response &Payment_Process_Result::factory($this->_driver
  253.                                                      $this->_responseBody,
  254.                                                      &$this);
  255.         if (!PEAR::isError($response)) {
  256.             $response->parse();
  257.         }
  258.  
  259.         return $response;
  260.     }
  261.  
  262.     /**
  263.      * Prepare the PUT query xml.
  264.      *
  265.      * @access private
  266.      * @return string The query xml
  267.      */
  268.     function _prepareQueryString()
  269.     {  
  270.         $data array_merge($this->_options,$this->_data);
  271.  
  272.         $doc = XML_Util::getXMLDeclaration();
  273.         $doc .= '<!DOCTYPE paymentService PUBLIC "-//Bibit//DTD Bibit PaymentService v1//EN" "http://dtd.bibit.com/paymentService_v1.dtd">';
  274.  
  275.         $doc .= XML_Util::createStartElement('paymentService'array('version' =>  $data['x_version']'merchantCode' => $data['x_login']));
  276.         if ($data['x_action'== PAYMENT_PROCESS_ACTION_BIBIT_CAPTURE || $data['x_action'== PAYMENT_PROCESS_ACTION_BIBIT_REFUND{
  277.             $doc .= XML_Util::createStartElement('modify');
  278.             $doc .= XML_Util::createStartElement('orderModification'array('orderCode' => $data['x_ordercode']));
  279.             if ($data['x_action'== PAYMENT_PROCESS_ACTION_BIBIT_CAPTURE{
  280.                 $doc .= XML_Util::createStartElement('capture');
  281.                 
  282.                 $d = array();
  283.                 $t time(- 86400;
  284.                 $d['dayOfMonth'date('d'$t);
  285.                 $d['month'date('m'$t);
  286.                 $d['year'date('Y'$t);
  287.                 $d['hour'date('H'$t);
  288.                 $d['minute'date('i'$t);
  289.                 $d['second'date('s'$t);
  290.                 $doc .= XML_Util::createTag('date'$d);
  291.                 $doc .= XML_Util::createTag('amount'array('value' => $data['x_amount'],
  292.                                                             'currencyCode' => $data['x_currency'],
  293.                                                             'exponent' => $data['x_exponent']));
  294.  
  295.                 $doc .= XML_Util::createEndElement('capture');
  296.             else if ($data['x_action'== PAYMENT_PROCESS_ACTION_BIBIT_REFUND{
  297.                 $doc .= XML_Util::createStartElement('refund');
  298.                 $doc .= XML_Util::createTag('amount'array('value' => $data['x_amount'],
  299.                                                             'currencyCode' => $data['x_currency'],
  300.                                                             'exponent' => $data['x_exponent']));
  301.                 $doc .= XML_Util::createEndElement('refund');
  302.             }
  303.  
  304.             $doc .= XML_Util::createEndElement('orderModification');
  305.             $doc .= XML_Util::createEndElement('modify');
  306.         else {
  307.             $doc .= XML_Util::createStartElement('submit');
  308.             $doc .= XML_Util::createStartElement('order'array('orderCode' => $data['x_ordercode']));
  309.             
  310.             $doc .= XML_Util::createTag('description'null$data['x_descr']);
  311.             $doc .= XML_Util::createTag('amount'array('value' => $data['x_amount'],
  312.                                                         'currencyCode' => $data['x_currency'],
  313.                                                         'exponent' => $data['x_exponent']));
  314.             if (isset($data['x_ordercontent'])) {
  315.                 $doc .= XML_Util::createStartElement('orderContent');
  316.                 $doc .= XML_Util::createCDataSection($data['x_ordercontent']);
  317.                 $doc .= XML_Util::createEndElement('orderContent');
  318.             }
  319.          
  320.             if ($data['x_action'== PAYMENT_PROCESS_ACTION_BIBIT_REDIRECT{
  321.                 if (is_array($data['paymentMethodMask']&& count($data['paymentMethodMask'> 0)) {
  322.                     $doc .= XML_Util::createStartElement('paymentMethodMask');
  323.                     foreach($data['paymentMethodMask']['include'as $code{
  324.                         $doc .= XML_Util::createTag('include'array('code' => $code));
  325.                     }
  326.                     foreach($data['paymentMethodMask']['exclude'as $code{
  327.                         $doc .= XML_Util::createTag('exclude'array('code' => $code));
  328.                     }
  329.                     $doc .= XML_Util::createEndElement('paymentMethodMask');
  330.                 }
  331.             else if ($data['x_action'== PAYMENT_PROCESS_ACTION_BIBIT_AUTH{
  332.                 $doc .= XML_Util::createStartElement('paymentDetails');
  333.                 switch ($this->_payment->type{
  334.                     case PAYMENT_PROCESS_CC_VISA:       $cc_type 'VISA-SSL'; break;
  335.                     case PAYMENT_PROCESS_CC_MASTERCARD$cc_type 'ECMC-SSL'; break;
  336.                     case PAYMENT_PROCESS_CC_AMEX:       $cc_type 'AMEX-SSL'; break;
  337.                 }
  338.  
  339.                 $doc .= XML_Util::createStartElement($cc_type);
  340.                 if (isset($data['x_card_num'])) {
  341.                     $doc .= XML_Util::createTag('cardNumber'null$data['x_card_num']);
  342.                 }
  343.                 if (isset($data['x_exp_date'])) {
  344.                     $doc .= XML_Util::createStartElement('expiryDate');
  345.                     $doc .= XML_Util::createTag('date'array('month' => substr($data['x_exp_date']02),
  346.                                                               'year' => substr($data['x_exp_date']34)));
  347.                     $doc .= XML_Util::createEndElement('expiryDate');
  348.                 }
  349.                 if (isset($this->_payment->firstName&&
  350.                     isset($this->_payment->lastName)) {
  351.                     $doc .= XML_Util::createTag('cardHolderName'null$this->_payment->firstName.' '.$this->_payment->lastName);
  352.                 }
  353.                 if (isset($data['x_card_code'])) {
  354.                     $doc .= XML_Util::createTag('cvc'null$data['x_card_code']);
  355.                 }
  356.               
  357.                 $doc .= XML_Util::createEndElement($cc_type);
  358.                 
  359.                 if ((isset($data['shopperIPAddress']|| isset($data['sessionId']))
  360.                 &&  ($data['shopperIPAddress'!= ''  || $data['sessionId'!= '')) {
  361.                     $t = array();
  362.                     if ($data['shopperIPAddress'!= ''{
  363.                         $t['shopperIPAddress'$data['shopperIPAddress'];
  364.                     }
  365.                     if ($data['sessionId'!= ''{
  366.                         $t['id'$data['sessionId'];
  367.                     }
  368.  
  369.                     $doc .= XML_Util::createTag('session'$t);
  370.                     unset($t);
  371.                 }
  372.               
  373.                 $doc .= XML_Util::createEndElement('paymentDetails');
  374.             }
  375.         
  376.             if ((isset($data['shopperEmailAddress'])    && $data['shopperEmailAddress'!= ''
  377.             ||  (isset($data['authenticatedShopperID']&& $data['authenticatedShopperID'!= '')) {
  378.                 $doc .= XML_Util::createStartElement('shopper');
  379.                 
  380.                 if ($data['shopperEmailAddress'!= ''{
  381.                     $doc .= XML_Util::createTag('shopperEmailAddress'null$data['shopperEmailAddress']);
  382.                 }
  383.                 if ($data['authenticatedShopperID'!= ''{
  384.                     $doc .= XML_Util::createTag('authenticatedShopperID'null$data['authenticatedShopperID']);
  385.                 }
  386.  
  387.                 $doc .= XML_Util::createEndElement('shopper');
  388.             }
  389.        
  390.             if (is_array($data['shippingAddress']&& count($data['shippingAddress']> 0{
  391.                 $a =$data['shippingAddress'];
  392.                 
  393.                 $doc .= XML_Util::createStartElement('shippingAddress');
  394.                 $doc .= XML_Util::createStartElement('address');
  395.  
  396.                 $fields = array('firstName',    'lastName',     'street',
  397.                                 'houseName',    'houseNumber',  'houseNumberExtension',
  398.                                 'postalCode',   'city',         'state',
  399.                                 'countryCode',  'telephoneNumber');
  400.  
  401.                 foreach($fields as $field{
  402.                     if (isset($a[$field])) {
  403.                         $doc .= XML_Util::createTag($fieldnull$a[$field]);
  404.                     }
  405.                 }
  406.                
  407.                 $doc .= XML_Util::createEndElement('address');
  408.                 $doc .= XML_Util::createEndElement('shippingAddress');
  409.             }
  410.        
  411.             $doc .= XML_Util::createEndElement('order');
  412.             $doc .= XML_Util::createEndElement('submit');
  413.         }
  414.         $doc .= XML_Util::createEndElement('paymentService');
  415.  
  416.         $doc1 = domxml_open_mem($doc);
  417.  
  418.         return $doc;
  419.     }
  420.  
  421.     /**
  422.      * Prepare the ordercontent
  423.      *
  424.      * Docs says max size is 10k
  425.      *
  426.      * @access private
  427.      */
  428.     function _handleOrdercontent()
  429.     {
  430.         $specific $this->_fieldMap['ordercontent'];
  431.         if ($this->ordercontent != ''{
  432.             $this->_data[$specificsubstr($this->ordercontent010240);
  433.         }
  434.     }
  435.  
  436.     /**
  437.      * Validate the merchant account login.
  438.      *
  439.      * @access private
  440.      * @return boolean true if valid, false otherwise
  441.      */
  442.     function _validateLogin()
  443.     {
  444.         return Validate::string($this->loginarray(
  445.             'format' => VALIDATE_ALPHA_UPPER,
  446.             'min_length' => 1
  447.         ));
  448.     }
  449.  
  450.     /**
  451.      * Validate the merchant account password.
  452.      *
  453.      * @access private
  454.      * @return boolean true if valid, false otherwise
  455.      */
  456.     function _validatePassword()
  457.     {
  458.         return Validate::string($this->passwordarray(
  459.             'min_length' => 1
  460.         ));
  461.     }
  462.  
  463.     /**
  464.      * Validates the ordercode
  465.      *
  466.      * Docs says up to 64 characters, no spaces or specials characters allowed
  467.      *
  468.      * @access private
  469.      * @return boolean true if valid, false otherwise
  470.      */
  471.     function _validateOrdercode()
  472.     {
  473.         return Validate::string($this->ordercodearray(
  474.             'min_length' => 1,
  475.             'max_length' => 64
  476.         ));
  477.     }
  478.  
  479.     /**
  480.      * Validate the order description.
  481.      *
  482.      * Docs says maximum length is 50 characters...
  483.      *
  484.      * @access private
  485.      * @return boolean true if valid, false otherwise
  486.      */
  487.     function _validateDescription()
  488.     {
  489.         return Validate::string($this->descriptionarray(
  490.             'min_length' => 1,
  491.             'max_length' => 50,
  492.         ));
  493.     }
  494.  
  495.     /**
  496.      * Validate the order amount.
  497.      *
  498.      * Should contain no digits, as those are set with the exponent option.
  499.      *
  500.      * @access private
  501.      * @return boolean true if valid, false otherwise
  502.      */
  503.     function _validateAmount()
  504.     {
  505.         return Validate::number($this->amountarray(
  506.             'decimal' => false
  507.         ));
  508.     }
  509.  
  510.     /** Validate the order amount currency
  511.      *
  512.      * The abbrivation for a currency, usually 2-3 chars
  513.      *
  514.      * @access private
  515.      * @return boolean true if valid, false otherwise
  516.      */
  517.     function _validateCurrency()
  518.     {
  519.         return Validate::string($this->currencyarray(
  520.             'format' => VALIDATE_ALPHA_UPPER,
  521.             'min_length' => 2,
  522.             'max_length' => 3
  523.         ));
  524.     }
  525.  
  526.     /** Validate the exponent of the order amount
  527.      *
  528.      * Occording to the dtd, valid is 0, 2 or 3
  529.      *
  530.      * @access private
  531.      * @return boolean true if valid, false otherwise
  532.      */
  533.     function _validateExponent()
  534.     {
  535.         switch ($this->exponent)
  536.         {
  537.             case 0:
  538.             case 2:
  539.             case 3:
  540.                 return true;
  541.             default:
  542.                 return false;
  543.         }
  544.     }
  545. }
  546.  
  547. /**
  548.  * Payment_Process_Bibit_Result
  549.  *
  550.  *
  551.  * @package Payment_Process
  552.  * @author Robin Ericsson <lobbin@localhost.nu>
  553.  * @version @version@
  554.  */
  555. {
  556.     var $_returnCode = PAYMENT_PROCESS_RESULT_DECLINED;
  557.  
  558.     var $_lastEvent = NULL;
  559.     
  560.     var $_fieldMap = array(
  561.     );
  562.  
  563.     function Payment_Process_Result_Bibit($rawResponse)
  564.     {
  565.         $this->_rawResponse = $rawResponse;
  566.     }
  567.  
  568.     function getErrorCode()
  569.     {
  570.         return $this->_errorCode;
  571.     }
  572.  
  573.     function getCode()
  574.     {
  575.         return $this->_returnCode;
  576.     }
  577.  
  578.     function parse()
  579.     {
  580.         $doc = new XML_XPath();
  581.  
  582.         $e $doc->load($this->_rawResponse'string');
  583.         if (PEAR::isError($e)) {
  584.             $this->_returnCode PAYMENT_PROCESS_RESULT_OTHER;
  585.             $this->message = 'Error parsing reply: '.$e->getMessage()."\n";
  586.             return;
  587.         }
  588.  
  589.         $e $doc->evaluate('//reply/error/attribute::code');
  590.         if (!PEAR::isError($e&& $e->next()) {
  591.             $this->_returnCode PAYMENT_PROCESS_RESULT_OTHER;
  592.             $this->_errorCode $e->getData();
  593.             
  594.             $e $doc->evaluate('//reply/error/text()');
  595.             $this->message = $e->getData();
  596.             return;
  597.         }
  598.         
  599.         $orderType $this->_request->_data['x_action'];
  600.         switch ($orderType{
  601.         case PAYMENT_PROCESS_ACTION_BIBIT_AUTH:
  602.             $e $doc->evaluate('//reply/orderStatus/payment/lastEvent/text()');
  603.             if (!PEAR::isError($e&& $e->next()) {
  604.                 $this->_lastEvent $e->getData();
  605.             }
  606.         
  607.             $amount $doc->evaluate('//reply/orderStatus/payment/amount/attribute::value');
  608.             if (!PEAR::isError($amount&& $amount->next()) {
  609.                if ($this->_lastEvent == 'AUTHORISED'{
  610.                     $this->_returnCode PAYMENT_PROCESS_RESULT_APPROVED;
  611.                     $this->message = '';
  612.                     return;
  613.                 }
  614.             }
  615.  
  616.             break;
  617.             $amount $doc->evaluate('//reply/ok/captureReceived/amount/attribute::value');
  618.             if (!PEAR::isError($amount&& $amount->next()) {
  619.                 $this->_returnCode PAYMENT_PROCESS_RESULT_APPROVED;
  620.                 return;
  621.             }
  622.  
  623.             break;
  624.             $amount $doc->evaluate('//reply/ok/refundReceived/amount/attribute::value');
  625.             if (!PEAR::isError($amount&& $amount->next()) {
  626.                 $this->_returnCode PAYMENT_PROCESS_RESULT_APPROVED;
  627.                 return;
  628.             }
  629.             break;
  630.         }
  631.     }
  632. }
  633.  
  634. ?>

Documentation generated on Mon, 11 Mar 2019 14:16:04 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.