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

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