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:
- $ORDER_ID - the ID of an order to be paid via this pay system;
- $arOrder - an array of the order $ORDER_ID parameters.
The handler algorithm and implementation completely depend on the interface of the pay system.
Pay system integration guidelines
- You have the required handler ready to run
- Copy the existing handler or the handler template to the public interface folder (e.g., to /bitrix/php_interface/include/payment/). There is a number of preinstalled presets in /bitrix/modules/sale/payment/.
- Modify the handler so that its algorithm fully corresponds the site
requirements and the pay system interface. If you create a handler form the
preinstalled template, you will find information on typical changes to be
made in its comments.
Typical changes to on-line pay system handlers are providing the correct connection information (for example, login and password) and synchronizing order property codes with those use in the database. These modifications are to be made to all on-line pay system handlers, without exception.
The pay system connection parameters are provided by the pay system upon registration in the pay system.
A set of order properties that a customer has to fill in when ordering must be customized by the site administrator. The e-Store module possesses no knowledge about the physical meaning of these properties. At the same time, pay system expect the required property values to bear the strictly defined meaning. So, a handler must map order properties stored in the database to those required by a pay system. You will an example of this below. - In the Create and edit a pay system form (in the administrative section) specify to which payer types this handler is to be made available. You mush also provide a valid path to a handler.
- You need a new handler
- Obtain full information on the pay system interface. You can get it, for example, on the pay system web site or in the pay system techsupport service.
- Create a pay system handler in the public section (e.g. in /bitrix/php_interface/include/payment/). If the interface of any existing pay system is similar to that of the new one, you can base your handler on it. You will find the preinstalled handlers in /bitrix/modules/sale/payment/.
- Modify the handler so that its algorithm fully corresponds the site
requirements and the pay system interface. If you create a handler form the
preinstalled template, you will find information on typical changes to be
made in its comments.
Typical changes to on-line pay system handlers are providing the correct connection information (for example, login and password) and synchronizing order property codes with those use in the database. These modifications are to be made to all on-line pay system handlers, without exception.
The pay system connection parameters are provided by the pay system upon registration in the pay system.
A set of order properties that a customer has to fill in when ordering must be customized by the site administrator. The e-Store module possesses no knowledge about the physical meaning of these properties. At the same time, pay system expect the required property values to bear the strictly defined meaning. So, a handler must map order properties stored in the database to those required by a pay system. You will an example of this below. - In the Create and edit a pay system form (in the administrative section) specify to which payer types this handler is to be made available. You mush also provide a valid path to a handler.
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.
- 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.
- 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.
- 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).
- Modify the script to conform to the pay system interface.
- 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.