Bitrix Site Manager

Pay system integration

A pay system is any facility that enable to pay for an order: on-line pay systems, bank transfers etc.

Different pay systems offer different interfaces that a developer uses to integrate in the site for them to interact. The pay system interfaces are usually completely different, e.g. the PayFlow Pro system requires that queries to the pay system are performed via the installable SDK, whereas banks demand printed receipt. Thus, the pay system integration requires special PHP scripts called pay system handlers (or handlers in this topic).

Handlers are specified individually for every payer type of every pay system using the Pay systems form. When an order is about to be paid, the system calls the handler of a selected pay system for a specified payer type. The system calls the handler after saving the order parameters in the database.

The pay system handlers are arbitrary PHP scripts running in the context of the e-Store module. In other words, the Kernel and the e-Store modules are surely connected and available within a handler. Besides, the following variables are also available in a handler:

The handler algorithm and implementation completely depend on the interface of the pay system.

Pay system integration guidelines

Typical handlers

A typical handler of an off-line pay system displays a ready-to-print receipt (or other document). These are usually banking receipts or invoices. Such handlers usually provide all necessary layout and print the order parameters in the hard-coded areas.

Example of an off-line handler can be found in /bitrix/modules/sale/payment/bill.php.

A typical handler of an on-line pay system displays an HTML form that in its turn post data to a pay system. Examples of these systems are Assist, AuthorizeNet, Payflow, WorldPay.

Pay system fully define the layout, fields and other parameters of the created HTML form. You can find the description of a form required to build a robust pay system handler, in the pay system documentation.

Example of an on-line handler can be found in /bitrix/modules/sale/payment/authorizenet.php (AuthorizeNet), /bitrix/modules/sale/payment/paypal.php (Paypal) etc.

The parameters required by a pay system are available via the array $arOrder as well as can be taken from an order properties. The following example show how to do it.


// The below code forms an associated array,
// in which the order property mnemonic codes 
//     (or ID's if mnemonic code is not available)
// will be assigned to property values supplied at the time of order
// $ORDER_ID - order ID, defined before the handler is called
$arCurOrderProps = array();
$db_res = CSaleOrderPropsValue::GetList(($b=""), 
                                        ($o=""),
                                        array("ORDER_ID"=>$ORDER_ID));
while ($ar_res = $db_res->Fetch())
   $arCurOrderProps[(strlen($ar_res["CODE"])>0) ? 
                                $ar_res["CODE"] :
                                $ar_res["ID"]] = $ar_res["VALUE"];

// Now build a form required by the pay system,
// having the order properties mapped to parameters  
// required by the pay system
if (isset($arCurOrderProps["ADDRESS"])):
   ?><input 
      type="hidden"
      name="address" 
      value="<?= htmlspecialchars($arCurOrderProps["ADDRESS"]) ?>"><?
endif;
if (isset($arCurOrderProps["ZIP"])):
   ?><input 
      type="hidden" 
      name="postcode" 
      value="<?= htmlspecialchars($arCurOrderProps["ZIP"]) ?>"><?
endif;

// Now we have put a value that a customer provided for a property ADDRESS
// in the field with the name required by the pay system 
// to store the customer address.
// We have put a value that a customer provided for a property ZIP
// in the field with the name required by the pay system 
// to store the customer zip code.

Usually, on-line pay systems provide the following two integration interfaces.

  1. The form with the order parameters is sent to the pay system server where a user has to fill in additional fields (e.g. credit card number). After that, the actual payment take place.
  2. A user provide all information on the site and a request is sent to the pay system. After the transaction succeeds, the pay system returns with its result.

The first type is the simplest one to implement. The handler creates an HTML form which sends data to the pay system server, and create fields required by the pay system. The required fields are usually described in the pay system help section. An example of this approach is available in the Assist pay system handler (/bitrix/modules/sale/payment/assist.php).

The first type is more difficult to implement. On the other hand, it is much more flexible. You can see an example in the AuthorizeNet pay system handler template (/bitrix/modules/sale/payment/authorizenet.php). In this case, the common handler structure is as follows.


// If we are ready to pay...
if ($_REQUEST["pay_this_order"]=="Y")
{
   // $strPostQueryString will hold the request parameters
   $strPostQueryString = "x_login=".urlencode("login");

   $arCurOrderProps = array();
   $db_res = CSaleOrderPropsValue::GetList(($b=""),
                                           ($o=""),
                                           array("ORDER_ID"=>$ORDER_ID));
   while ($ar_res = $db_res->Fetch())
      $arCurOrderProps[(strlen($ar_res["CODE"])>0) ? 
                                   $ar_res["CODE"] :
                                   $ar_res["ID"]] = $ar_res["VALUE"];

   if (isset($arCurOrderProps["ADDRESS"]))
      $strPostQueryString .= 
                "&x_address=".urlencode($arCurOrderProps["ADDRESS"]);

    * * *

   if (isset($arCurOrderProps["ZIP"]))
      $strPostQueryString .=
                "&x_ship_to_zip=".urlencode($arCurOrderProps["ZIP"]);

   // Send request to the pay system
   $strResult = QueryGetData("some_url.net", 
                             443,
                             "/some_path/file.dll",
                             $strPostQueryString,
                             $errno, $errstr, "POST", "ssl://");

   // $strResult contains the pay system respond,
   // which depends on the pay system.
   // You can process it and store in the order fields.

    * * *

}
else
{
   ?>
   <form action="" method="post">
      Credit card number: <input type="text" name="ccard_num" size="30"><br>
      * * * <br>
      CVV2: <input type="text" name="ccard_code" size="5"><br>
      <input type="hidden" name="CurrentStep" value="<?= $CurrentStep ?>">
      <input type="hidden" name="ORDER_ID" value="<?= $ORDER_ID ?>">
      <input type="hidden" name="pay_this_order" value="Y">
      <input type="submit" value="Proceed">
   </form>
   <?
}

In the latter case (type 2) the e-Store module obtains the pay system result appropriate for further processing.

If the type 1 is the case, it could be more convenient to automatically acquire the pay system result (i.e. whether the order is actually paid); but it is feasible if only the pay system supports this function. You can get more information on the pay system interface peculiarities in its documentation or the pay system support service.

If the pay system provides interface to obtain the order paid status, you can develop a status acquisition script to get the status automatically. The script is called from the Orders form of the administrative section for each order paid with this pay system. Implementation requires the following steps to be performed.

  1. Create a status acquisition script in the public section (e.g. in /bitrix/php_interface/include/payment/). You can use one of the preinstalled scripts from /bitrix/modules/sale/payment/ as a start (e.g. assist_res.php).
  2. Modify the script to conform to the pay system interface.
  3. In the Create and edit a pay system form of the administrative section, specify for which pay system handlers this status acquisition script is effective.

Some pay systems do not provide interface to acquire the status. Instead, it sends e-mails containing the pay transaction result. In this case, you can as well obtain the status automatically via the Mail module. To do so, create the appropriate mail handler and adjust its settings. For more information, please see the Mail module documentation.

If you develop your own ordering component, the pay system handler structure and algorithm are totally arbitrary.