Создание дополнительных модулей платежных систем

Материал из ISPWiki

Перейти к: навигация, поиск

В интерфейсе BILLmanager работа с платежными системами отражена в двух местах:


1. На уровне провайдера - Компании->Принимаемые методы оплаты;
2. На уровне клиента - Платежи;


Чтобы создать свой платежный интерфейс, необходимо:

  • создать программу или скрипт, который будет заполнять и обрабатывать поля в формах, а также в случае необходимости инициировать оплату;
  • создать xml-документ с описанием элементов интерфейса и текстовыми сообщениями на разных языках;
  • в случае необходимости создать cgi скрипты или программы, которые будут обмениваться данными с платежными шлюзами.

Содержание

XML-документ

XML-документ должен располагаться в папке /usr/local/ispmgr/etc и называться billmgr_mod_xxx.xml, где вместо xxx вы можете указать любое название, например, test (billmgr_mod_test.xml). Документ обязательно должен быть в кодировке UTF-8 и иметь следующий вид:

 <?xml version="1.0" encoding="UTF-8"?>
 <mgrdata>
   <metadata name="company.paymethod.edit_XXX" type="form">
     <form>
       <field name="name">
         <input type="text" name="name" empty="no"/>
       </field>
       <field name="minamount">
         <input type="text" name="minamount"/>
       </field>
       ----поля необходимые вам----
     </form>
       <jscript>
               document.frm.func.value = 'company.paymethod.edit';
       </jscript>
   </metadata>
   <metadata name="credit.pay.XXX" type="form">
     <form>
       <field name="amount">
         <input type="text" name="amount" readonly="yes"/>
       </field>
       ----поля необходимые вам----        
       <field name="merchantfield">  Если используется переход на сайт платежной системы
         <link name="merchant"/>
       </field>
     </form>
     <jscript> Если используется переход на сайт платежной системы
       function GoMerchant(id, lnk) {
         window.open('/mancgi/testcgi?elid='+id);
         if (lnk) {
           lnk.className = 'disabled';
           lnk.onclick = function () { return false; }
         }
       }
     </jscript>
   </metadata>
   <lang name="en">
     <messages name="credit.pay.XXX">
       <msg name="amount">Amount</msg>
       <msg name="merchant">Pay now</msg>
       <msg name="title">XXX pay method</msg>
       <msg name="hint_default">Fill form</msg>
       <msg name="hint_amount">Amount</msg>
       ---остальные сообщения----
     </messages>
   </lang>
 </mgrdata>

XXX - это внутреннее имя платежной системы. Обязательно создавайте описание сообщений для английского языка, иначе могут не создаться и остальные языки. Также обратите внимание на поле merchant, оно необходимо, если платежная система использует переход на их сайт.


Программа обработчик

Программа или скрипт должны располагаться в каталоге /usr/local/ispmgr/sbin/. Название файла должно начинаться с символов pm. Набор символов, следующий после pm, будет внутренним названием платежной системы, и элементы интерфейса будут использовать именно это название. Программа должна отвечать основному параметру - при запуске с параметром feature она должна выдавать список возможностей, которые она поддерживает, перечисленные через пробел.

Список возможностей

altsuccesspage Используется, если метод оплаты поддерживает динамическое указание страницы возврата при успешном завершении платежа.

pmtune Программа будет изменять форму редактирования метода оплаты. Используется для того, чтобы заполнить селекты значениями. BILLmanager передает на стандартный ввод XML-документ, описывающий форму, а потом ждет, когда программа на стандартный вывод подаст модифицированный XML-документ.

pmvalidate Программа будет проверять введенные пользователем значения. Используется для того, чтобы пользователь не мог ввести некорректные значения. BILLmanager передает на стандартный ввод XML-документ, содержащий поля формы с введенными значениями. Если название полей будет param1, param2 b param3, XML будет иметь следующий вид:

 <?xml version="1.0" encoding="UTF-8"?>
 <doc>
   <param1>value</param1>
   <param2>value</param2>
   <param3>value</param3>
 </doc>

Если все параметры имеют корректные значения, программа должна подать на стандартный вывод pmok либо в случае ошибки Error: имя_параметра. В случае успеха BILLmanager запишет параметры в таком же XML-виде в таблицу companycrtype в поле params. В дальнейшем при создании платежей вы можете использовать эти данные.

crtune Программа будет изменять форму создания платежа. Используется, чтобы заполнить селекты. Работает аналогично pmtune.

crvalidate Программа будет проверять введенные пользователем значения при совершении платежа. Работает аналогично pmvalidate.

crget Программа будет заполнять поля формы создания платежа. Необходимо, чтобы заполнить поля формы редактирования платежа значениями из базы. Работает аналогично pmtune.

crset Используется, если пользователь не должен переходить на сайт платежной системы и платеж совершается на основе введенных данных. В BILLmanager данный метод используется при выписке счета WebMoney и оплате через Ogone. Реализовано на основе системы LongTask. В случае ошибки сообщение об ошибке должно быть в следующем формате:

 crid код_платежа описание_ошибки

Пользователь увидит желтый баннер с тестом:

 Во время совершения платежа произошла ошибка. Код: 'код_платежа' Error: 'сообщение об ошибке'. Исправьте некорректные данные, либо обратитесь в техническую поддержку. 

Зачислить платеж можно запустив

 /usr/local/ispmgr/sbin/mgrctl -m billmgr credit.setpaid elid=код_платежа info="данные которые вы хотите сохранить"

Cgi программа

Если понадобится обмен данными с платежной системой, нужно будет создавать cgi программы, которые должны располагаться в /usr/local/ispmgr/cgi Https адрес - https://your_domain/mancgi/XXX, где XXX - название файла. Примеров cgi программы мы приводить не будем, на просторах интернета хватает примеров, в том числе реализующих общение с платежными шлюзами.

Структура базы данных

Перечислим таблицы, которые могут понадобиться для создания модуля:

1. companycrtype - в этой таблице содержатся данные о методе оплаты. Столбцы:
1.1 id - код метода оплаты;
1.2 currency - валюта. Ссылка на табличку currency;
1.3 minamount - минимальная сумма платежа;
1.4 params - XML-документ с параметрами, введенными на форме;

2. credit - таблица с платежами. Столбцы:
2.1 id - код платежа;
2.2 nativeamount - сумма в валюте метода оплаты;
2.3 state - Статус платежа;
2.4 userinfo - XML-документ с введенными на форме данными;
2.5 info - Используется для сохранения данных о платеже; например, данные, присылаемые платежным шлюзом.

Это неполное описание таблиц. В этих таблицах гораздо больше столбцов, но они служебные, и вряд ли понадобятся для платежного шлюза.

Пример скрипта на языке perl

Пример исполняемых файлов

В примере, приведенном ниже, описаны тестовые функции, которые могут понадобиться при создании платежного интерфейса. Для работы понадобятся модули XML::LibXML и Mysql. Название файла - pmtest. Этот пример не реализует какого-либо протокола. Он только показывает, какие возможности можно реализовать, используя нашу систему.
Краткое описание примера:
Основная часть служит для того, чтобы определить, как запущен процесс: как LongTask или нет. В зависимости от этого по разному запускаются функции.
pmtune - показывает, как можно заполнить select значениями. pmvalidate - проверяет, чтобы testinput содержал "test", иначе возвращает ошибку. crtune - делает то же, что и pmtune. crget - берет из базы значения и заполняет ими поля в форме.


Указываем интерпретатор скрипта:

#!/usr/bin/perl
no warnings;

Подключаем необходимые библиотеки:

use XML::LibXML;
use Mysql;
use Env;

Открываем файл лога для добавления записей:

open(DEBUG, ">>/tmp/debug.log");

Устанавливаем флаг ошибка (изменяем на 1 в случае возникновения ошибки в работе модуля):

$errflg = 0;

Обрабатываем команду, переданную модулю:

foreach $x(@ARGV) { 
   if ($x eq "pmtune"){
      pmtune();
   }
   if ($x eq "feature"){
     print "pmtune pmvalidate crtune crget crset";
   }
   if ($x eq "pmvalidate"){
     pmvalidate();
   }	
   if ($x eq "crtune"){
     crtune();
   }
   if ($x eq "crget"){
     crget();
   }
   if ($x eq "crset"){
     crset();
   }
}

Обработка завершения модуля:

if ($env{"MGR_LT_PID"}) {
   if ($errflg) {
     system "/usr/local/ispmgr/sbin/mgrctl -m billmgr longtask.finish elid=".$env{"MGR_LT_PID"}." status=ok";
   } else {
     system "/usr/local/ispmgr/sbin/mgrctl -m billmgr longtask.finish elid=".$env{"MGR_LT_PID"}." status=err errmsg='Error message'";
   }
}

Закрываем лог файл:

close(DEBUG);

Возвращаем XML файл, переданный на стандартный ввод:

sub GetInputXml(){
   my $input;
   my $buf = <STDIN>;
   while($buf) {
     $input = "$input$buf";
     $buf = <STDIN>;
   }
   return $input;
}

Проверяем переданные значения:

sub pmvalidate{
   my $parser = XML::LibXML->new();
   my $xml = $parser->parse_string(GetInputXml());
   @testinput = $xml->getElementsByTagName('testinput');
   print DEBUG $testinput[0]->textContent;
   if($testinput[0]->textContent eq "test"){
     print "pmok";
   } else {
     print "Error: testinput";
   }
}

Получаем XML формы редактирования метода оплаты со стандартного ввода, подставляем значения и возвращаем XML файл формы:

sub pmtune{
   my $input = GetInputXml;
   my $parser = XML::LibXML->new();
   my $xml = $parser->parse_string($input);
   my $root = $xml->getDocumentElement();
   my $elem2 = $xml->createElement("slist");
   $elem2->setAttributeNode($xml->createAttribute("name","testselect")); 
   my $slist1=$xml->createElement("msg");
   $slist1->appendText( "select_1");
   $elem2->appendChild($slist1);
 
   my $slist2=$xml->createElement("msg");
   $slist2->appendText( "select_2");
   $elem2->appendChild($slist2);
 
   my $slist3=$xml->createElement("msg");
   $slist3->appendText( "select_3");
   $elem2->appendChild($slist3);
   $root->appendChild($elem2);
 
   #print DEBUG $root->toString;
   print $root->toString;
}

Получаем XML формы создания платежа со стандартного ввода, изменяем и возвращаем XML файл формы:

sub crtune{
   my $input = GetInputXml;   
   my $parser = XML::LibXML->new();
   my $xml = $parser->parse_string($input);
   my $root = $xml->getDocumentElement();
   my $elem2 = $xml->createElement("slist");
   $elem2->setAttributeNode($xml->createAttribute("name","testselect")); 
   my $slist1=$xml->createElement("msg");
   $slist1->appendText( "select_1");
   $elem2->appendChild($slist1);
 
   my $slist2=$xml->createElement("msg");
   $slist2->appendText( "select_2");
   $elem2->appendChild($slist2);
 
   my $slist3=$xml->createElement("msg");
   $slist3->appendText( "select_3");
   $elem2->appendChild($slist3);
 
 
   $root->appendChild($elem2);
 
   #print DEBUG $root->toString;
   print $root->toString;
}

Получаем XML формы создания платежа со стандартного ввода, заполняем значениями из базы и возвращаем XML файл формы:

sub crget{
   my $input = GetInputXml;  
   my $parser = XML::LibXML->new();
   my $xml = $parser->parse_string($input);
   my $root = $xml->getDocumentElement();
   my @xelid = $xml->getElementsByTagName('elid');
   #print DEBUG $xelid[0]->textContent;
   my $elid = $xelid[0]->textContent;
   $user = "root";
   $password = "1";
   $database = "billmgr";
   $host = "localhost";
   my $query="select cr.nativeamount, cr.state, cu.iso, type.params from credit cr \
        join companycrtype type on type.id=cr.type join currency cu on cu.id=type.currency where cr.id=$elid";
   $dbh = Mysql->Connect($host,$database,$user,$password);
   $sth = $dbh->Query($query);
   @arr = $sth->FetchRow;
   my $elem = $xml->createElement("amount");
   $elem->appendText("$arr[0] $arr[2]");
   $root->appendChild($elem);
   if($arr[1] eq "4"){
     $elem = $xml->createElement("merchant");
     $elem->appendText("GoMerchant($elid, this); return false;");
     $root->appendChild($elem);
   } else {
 	#$root->removeChild($xml->findnodes("//field/merchantfield"));
   }
    print $root->toString;
}

Обработчик платежа (в случае обработки модулем):

sub crset(){
   print DEBUG "\nin crset\n";
   print DEBUG "credit id: $ltparams[2]";
   return "crid $ltparams[2] Test error";	
}

Пример XML-документа

 <?xml version="1.0" encoding="UTF-8"?>
 <mgrdata>
   <metadata name="company.paymethod.edit_test" type="form">
     <form>
       <field name="name">
         <input type="text" name="name" empty="no"/>
       </field>
       <field name="minamount">
         <input type="text" name="minamount"/>
       </field>
       <field name="testselect">
         <select name="testselect"/>
       </field>
       <field name="testinput">
         <input type="text" name="testinput"/>
       </field>
     </form>
     <jscript>
       document.frm.func.value = 'company.paymethod.edit';
     </jscript>
   </metadata>
   <metadata name="credit.pay.test" type="form">
     <form>
       <field name="amount">
         <input type="text" name="amount" readonly="yes"/>
       </field>
       <field name="testselect">
         <select name="testselect"/>
       </field>
         <field name="merchantfield">
       <link name="merchant"/>
         </field>
     </form>
     <jscript>
       function GoMerchant(id, lnk) {
         window.open('/mancgi/testcgi?elid='+id);
         if (lnk) {
           lnk.className = 'disabled';
           lnk.onclick = function () { return false; }
         }
       }
     </jscript>
   </metadata>
   <lang name="en">
     <messages name="credit.pay.test">
       <msg name="amount">Amount</msg>
       <msg name="merchant">pay now</msg>
       <msg name="testselect">Testselect</msg>
       <msg name="title">Test pay method</msg>
       <msg name="hint_default">Fill form</msg>
       <msg name="hint_amount">Amount</msg>
     </messages>
   </lang>
 </mgrdata>

Пример на PHP

Пример описывает модуль для PayPal на PHP. Модуль может содержать функция несовместимые с версией php установленной на вашем сервер. Код примера максимально прост, не содержит дополнительных проверок и может содержать стилистические ошибки.

Пример исполняемых файлов

Файл pmpaypal.php

Файл помещается в каталог /usr/local/ispmgr/sbin/ и выполняет роль основного файла модуля оплаты. Модуль выполняет две задачи, проверяет на валидность email мерчанта при настройке метода оплаты и заполняет сумму платежа на форме оплаты.

#!/usr/bin/php
<?php
	$LOG_FILE = fopen("/usr/local/ispmgr/var/pmpaypal.php.log", "a");

	function Debug($log_str) {
           fwrite($GLOBALS["LOG_FILE"], date("M d H:i:s")." [".posix_getpid()."] ".$log_str."\n");
	}

	function defErrorHandler($errno, $errstr, $errfile, $errline) {
		if (!(error_reporting() & $errno)) {
			return;
		}
		Debug($errfile.":".$errline." Error: ".$errno.", error message: ".$errstr);
		return true;
	}
       
       class DB extends mysqli {
           public function __construct($host, $user, $pass, $db) {
               parent::init();
               if (!parent::options(MYSQLI_INIT_COMMAND, "SET AUTOCOMMIT = 0")) {
                   die("Установка MYSQLI_INIT_COMMAND завершилась провалом");
               }
               if (!parent::options(MYSQLI_OPT_CONNECT_TIMEOUT, 5)) {
                   die("Установка MYSQLI_OPT_CONNECT_TIMEOUT завершилась провалом");
               }
               if (!parent::real_connect($host, $user, $pass, $db)) {
                   die("Ошибка подключения (".mysqli_connect_errno().") ".mysqli_connect_error());
               }
               Debug("MySQL connection established");
           }
           
           public function __destruct() {
               parent::close();
               Debug("MySQL connection closed");
           }
       }
       
       function DBConnect() {
           $config = file_get_contents("/usr/local/ispmgr/etc/billmgr.conf");
           $lines = explode("\n", $config);
           $params = array();
           $params["DBHost"] = "localhost";
           $params["DBUser"] = "root";
           $params["DBName"] = "billmgr";
           foreach ($lines as $line) {
               $param_line = preg_split("/\s+/", $line, 2);
               if (count($param_line) == 2) {
                   $params[$param_line[0]] = $param_line[1];
               }
           }
           
           return new DB($params["DBHost"], $params["DBUser"], $params["DBPassword"], $params["DBName"]);
       }
       
       function GetInput() {
           return file_get_contents("php://stdin");
       }

       function PMValidate() {
           $input = GetInput();
           Debug("input: ".$input);
           $pm_params = new SimpleXMLElement($input);
           if (!filter_var((string)$pm_params->aemail, FILTER_VALIDATE_EMAIL)) {
               echo "aemail";
           } else {
               echo "pmok";
           }
       }
       
       function CRGet() {
           $db = DBConnect();
           $input = GetInput();
           Debug("input: ".$input);
           $cr_params = new SimpleXMLElement($input);
           $res = $db->query("select concat(cr.nativeamount, ' ', cu.iso) from credit cr join companycrtype type on type.id=cr.type join currency cu on cu.id=type.currency where cr.id=".(string)$cr_params->elid);
           $res_array = $res->fetch_array();
           $cr_params->addChild("amount", $res_array[0]);
           $res->close();
           echo $cr_params->asXML();
       }

       function CRTune() {
           $db = DBConnect();
           $input = GetInput();
           Debug("input: ".$input);
           $cr_params = new SimpleXMLElement($input);
           $res = $db->query("select cr.state from credit cr where cr.id=".(string)$cr_params->elid);
           $res_array = $res->fetch_array();
           if ($res_array[0] == "4") {
               $cr_params->metadata->form->addAttribute("nosubmit", "yes");
           }
           $res->close();
           echo $cr_params->asXML();
       }

	set_error_handler("defErrorHandler");

       $request_str = "";
       foreach ($argv as $arg) {
           $request_str .= $arg;
       }
       
       Debug("Request: ".$request_str);
       $cmd = ($argc > 1 ? $argv[1] : "");
       Debug("Command: ".$cmd);
       
       switch ($cmd) {
           case "feature":
               echo "pmvalidate crget crtune";
               break;
           case "pmvalidate":
               PMValidate();
               break;
           case "crget":
               CRGet();
               break;
           case "crtune":
               CRTune();
               break;
       }
?>

Файл paypalpayment.php

Файл помещается в каталог /usr/local/ispmgr/cgi/ и отвечает за переадресацию пользователя на страницу оплаты. Для этого производится формирование html формы без отображения клиенту и автоматическая ее отправка по заданному адресу после загрузки страницы.

#!/usr/bin/php
<?php
   echo "Content-type: text/html\n\n";

   $LOG_FILE = fopen("/usr/local/ispmgr/var/paypalpayment.php.log", "a");
   
   function Debug($log_str) {
       fwrite($GLOBALS["LOG_FILE"], date("M d H:i:s")." [".posix_getpid()."] ".$log_str."\n");
   }
   
   function defErrorHandler($errno, $errstr, $errfile, $errline) {
       if (!(error_reporting() & $errno)) {
           return;
       }
       Debug($errfile.":".$errline." Error: ".$errno.", error message: ".$errstr);
       return true;
   }
   
   function GetMgrObject($func, $elid, $auth) {
       Debug("execute: ".$func.", elid: ".$elid);
       $out = shell_exec("/usr/local/ispmgr/sbin/mgrctl -m billmgr -o json ".$func." elid=".$elid.($auth != "" ? " sesid=".$auth : ""));
       Debug($out);
       return json_decode($out);
   }

   set_error_handler("defErrorHandler");
   
   if($_SERVER['REQUEST_METHOD'] == 'POST'){
       $input = file_get_contents("php://stdin");
   }elseif($_SERVER['REQUEST_METHOD'] == 'GET'){
       $input = $_SERVER['QUERY_STRING'];
   }
   
   $param = array();
   parse_str($input, $param);
   
   $auth = "";
   $lang = "";
   
   if (isset($param["auth"])) {
       Debug("by auth param");
       $auth = $param["auth"];
   } elseif (isset($_COOKIE["billmgr4"])) {
       Debug("by standart cookie");
       $cookie = $_COOKIE["billmgr4"];
       $cookie_param = explode(":", $cookie);
       $lang = $cookie_param[1];
       $auth = $cookie_param[2];
   } elseif (isset($_SERVER["HTTP_COOKIE"])) {
       Debug("by server cookie");
       $cookies = explode("; ", $_SERVER["HTTP_COOKIE"]);
       foreach ($cookies as $cookie) {
           $param_line = explode("=", $cookie);
           if (count($param_line) > 1 && $param_line[0] == "billmgr4") {
               $cookies_bill = explode(":", $param_line[1]);
               $lang = $cookies_bill[1];
               $auth = $cookies_bill[2];
           }
       }
   }
    
   if ($auth == "") {
       echo "Not authorized";
       exit();
   }
   
   $credit = GetMgrObject("credit.info", $param["elid"], $auth);
   
   $url = $credit->{"posturl"};
   $amount = $credit->{"nativeamount"};
   $currency = $credit->{"typecurrency"};
   $logourl = $credit->{"logourl"};
   $merchant_email = $credit->{"aemail"};

   echo "<html>\n";
   echo "<head>\n\t<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>\n";
   echo "\t<link rel='shortcut icon' href='billmgr.ico' type='image/x-icon'/>\n";
   echo "\t<script language='JavaScript'>\n";
   echo "\t\tfunction SubmitForm() {\n";
   echo "\t\t\tvar loc = location.host;\n";
   echo "\t\t\tdocument.ppform.notify_url.value = loc+'/mancgi/paypalresult.php';\n";
   echo "\t\t\tdocument.ppform.return.value = loc+'/manimg/userdata/paysuccess_".$lang.".html';\n";
   echo "\t\t\tdocument.ppform.cancel_return.value = loc+'/manimg/userdata/payfail_".$lang.".html';\n";
   echo "\t\t\tdocument.ppform.submit();\n";
   echo "\t\t}\n";
   echo "\t</script>\n";
   echo "</head>\n";
   echo "<body onload='SubmitForm()'>\n";
   echo "\t<form name='ppform' action='".$url."' method='post'>\n";
   echo "\t\t<input type='hidden' name='cmd' value='_xclick'>\n";
   echo "\t\t<input type='hidden' name='business' value='".$merchant_email."'>\n";
   echo "\t\t<input type='hidden' name='item_name' value='Advance payment #".$param["elid"]."'>\n";
   echo "\t\t<input type='hidden' name='item_number' value='".$param["elid"]."'>\n";
   echo "\t\t<input type='hidden' name='invoice' value='".$param["elid"]."'>\n";
   echo "\t\t<input type='hidden' name='amount' value='".$amount."'>\n";
   echo "\t\t<input type='hidden' name='currency_code' value='".$currency."'>\n";
   echo "\t\t<input type='hidden' name='no_shipping' value='1'>\n";
   echo "\t\t<input type='hidden' name='no_note' value='1'>\n";
   echo "\t\t<input type='hidden' name='notify_url' value=>\n";
   echo "\t\t<input type='hidden' name='return' value=>\n";
   echo "\t\t<input type='hidden' name='cancel_return' value=>\n";
   echo "\t\t<input type='hidden' name='lc' value='".$lang."'>\n";
   if ($logourl != "") {
       echo "\t\t<input type='hidden' name='image_url' value='".$logourl."'>\n";
   }
   echo "\t</form>\n";
   echo "</body>\n";
   echo "</html>\n"; 
?>

Файл paypalresult.php

Файл помещается в каталог /usr/local/ispmgr/cgi/ и отвечает за обработку входящих IPN сообщений от PayPal для проверки корректности и достоверности полученных данных производится их отправка на сервер PayPay для валидации. Так же проверяется сумма и получатель платежа. После того как данные проверены платежу выставляется статус в соответствии с полученной информацией.

#!/usr/bin/php
<?php
   echo "Content-type: text/html\n\n";
   
   $LOG_FILE = fopen("/usr/local/ispmgr/var/paypalresult.php.log", "a");
   
   function Debug($log_str) {
       fwrite($GLOBALS["LOG_FILE"], date("M d H:i:s")." [".posix_getpid()."] ".$log_str."\n");
   }
   
   function defErrorHandler($errno, $errstr, $errfile, $errline) {
       if (!(error_reporting() & $errno)) {
           return;
       }
       Debug($errfile.":".$errline." Error: ".$errno.", error message: ".$errstr);
       return true;
   }
   
   function GetMgrObject($func, $elid, $auth) {
       Debug("execute: ".$func.", elid: ".$elid);
       $out = shell_exec("/usr/local/ispmgr/sbin/mgrctl -m billmgr -o json ".$func." elid=".$elid.($auth != "" ? " auth=".$auth : ""));
       Debug($out);
       return json_decode($out);
   }
   
   function SetPaymentInfo($func, $elid, $info) {
       Debug("execute: ".$func.", elid: ".$elid);
       $out = shell_exec("/usr/local/ispmgr/sbin/mgrctl -m billmgr -o json ".$func." elid=".$elid.($info != "" ? " info=".escapeshellarg($info) : ""));
       Debug($out);
       return json_decode($out);
   }
   
   set_error_handler("defErrorHandler");
   
   if ($_SERVER['REQUEST_METHOD'] == 'POST'){
       $input = file_get_contents("php://stdin");
   } elseif ($_SERVER['REQUEST_METHOD'] == 'GET'){
       $input = $_SERVER['QUERY_STRING'];
   }
   
   Debug(print_r($_SERVER, true));
   
   Debug("input data: ".$input);
   
   $param = array();
   parse_str($input, $param);
   
   $credit_id = $param["invoice"];
   
   if ($credit_id == "") {
       echo "Epmty invoice";
   } else {
       $credit = GetMgrObject("credit.info", $credit_id, "");
       
       Debug(print_r($credit, true));
       
       $url = $credit->{"posturl"};
       $amount = $credit->{"nativeamount"};
       $merchant_email = $credit->{"aemail"};
       
       if ($param["receiver_email"] != $merchant_email) {
           echo "Invalid receiver";
           exit();
       }
       
       if ($param["mc_gross"] != $amount) {
           echo "Invalid amount";
           exit();
       }
       
       $result = file_get_contents($url."?cmd=_notify-validate&".$input);
       
       Debug($result);
       
       if ($result == "VERIFIED") {
           $payment_status = $param["payment_status"];
           
           if ($payment_status == "Completed") {
               SetPaymentInfo("credit.setpaid", $credit_id, $input);
           } else if ($payment_status == "Pending") {
               SetPaymentInfo("credit.setinpay", $credit_id, $input);
           } else if ($payment_status == "Denied") {
               SetPaymentInfo("credit.setnotpay", $credit_id, "");
           }
           echo "OK\n";
       } else {
           echo "Data not verified";
           exit();
       }
   }
?>

Пример XML

Файл billmgr_mod_paypal.php.xml

Файл помещается в каталог /usr/local/ispmgr/etc/ и отвечает за формирование форм настройки метода оплаты и непосредственно оплаты счета. Так же в файле задаются подписи к полям форм и их переводы на различные языки.

<?xml version="1.0" encoding="UTF-8"?>
<mgrdata>
	<metadata name="company.paymethod.edit_paypal.php" type="form">
		<form>
			<field name="name">
				<input type="text" name="name" empty="no"/>
			</field>
			<field name="ptype">
				<select name="ptype"/>
			</field>
			<field name="autodelete">
				<input type="text" name="autodelete"/>
				<desc name="days"/>
			</field>
			<field name="minamount">
				<input type="text" name="minamount"/>
			</field>
			<field name="priority">
				<input type="text" name="priority"/>
			</field>
			<field name="commission">
				<input type="text" name="commission"/>
				<desc name="percent"/>
			</field>
			<field name="checkpayer">
				<input type="checkbox" name="checkpayer"/>
				<desc name="checkpayerd"/>
			</field>
			<field name="posturl">
				<input type="text" name="posturl"/>
			</field>
			<field name="logourl">
				<input type="text" name="logourl"/>
			</field>
			<field name="aemail">
				<input type="text" name="aemail"/>
			</field>		
		</form>
		<jscript>
			document.frm.func.value = 'company.paymethod.edit';
		</jscript>
	</metadata>
	<metadata name="credit.pay.paypal.php" type="form">
		<form extokmsg="yes" event="yes">
			<field name="amount">
				<input type="text" name="amount" readonly="yes"/>
			</field>
		</form>
		<jscript>
		function frm_event() {
			var id = frm.elid.value;
			window.open('/mancgi/paypalpayment.php?elid='+id);
			return true;
		}
		</jscript>
	</metadata>
	<lang name="ru">
		<messages name="company.paymethod.edit">
			<msg name="paypal.php">PayPal PHP</msg>
		</messages>
		<messages name="company.paymethod">
			<msg name="module_paypal.php">PayPal PHP</msg>
		</messages>
		<messages name="company.paymethod.edit_paypal.php">
			<msg name="hint_name">Название типа метода оплаты</msg>
			<msg name="days">дней</msg>
			<msg name="autodelete">Период удаления неоплаченных платежей</msg>
			<msg name="hint_autodelete">Укажите период автоматического удаления неоплаченных платежей.</msg>
			<msg name="hint_default">Укажите данные необходимые для взаимодействия с платежной системой, а также другие параметры, применяемые к платежам</msg>
			<msg name="hint_minamount">Минимальная сумма для осуществления платежа</msg>	  
			<msg name="minamount">Минимальная сумма платежа</msg>
			<msg name="title">Параметры</msg>
			<msg name="priority">Приоритет</msg>
			<msg name="percent">процентов</msg>
			<msg name="hint_priority">Методы оплаты будут упорядочены в соответствии с приоритетом. Чем выше приоритет, тем метод оплаты будет выше в выпадающем списке.</msg>
			<msg name="commission">Комисcия</msg>
			<msg name="hint_commission">Комиссия платежной системы. Если указана комиссия, то после зачисления платежа на указанный процент будет произведен расход</msg>
			<msg name="pperson">Частное лицо</msg>
			<msg name="psoleproprietor">Индивидуальный предприниматель</msg>
			<msg name="pcompany">Компания</msg>
			<msg name="ptype">Статус плательщика</msg>
			<msg name="hint_ptype">Укажите статус плательщиков, для которых будет доступен данный метод оплаты</msg>
			<msg name="null">Любой</msg>
			<msg name="checkpayerd">Проверять заполненность свойств плательщика</msg>
			<msg name="hint_checkpayer">Опция включает проверку заполненности свойств плательщика и отказ в оплате в случае наличия пустых полей</msg>
			<msg name="aemail">E-mail счета</msg>
			<msg name="hint_aemail">Авторизационный E-mail счета (адрес paypal)</msg>
			<msg name="hint_default">Заполните поля формы</msg>
			<msg name="hint_logourl">Адрес по которому загружен логотип</msg>
			<msg name="hint_posturl">Адрес к которому осуществляется доступ средствами API</msg>
			<msg name="hint_country">Определите язык подтверждения платежа по стране</msg>
			<msg name="logourl">Логотип (URL)</msg>
			<msg name="minamount">Минимальная сумма платежа</msg>
			<msg name="posturl">API URL</msg>
			<msg name="title">Подробности</msg>
		</messages>
		<messages name="credit.pay.paypal.php">
			<msg name="msg_extokmsg">Оплата</msg>
			<msg name="amount">Вам необходимо оплатить</msg>
			<msg name="hint_amount">Итоговая сумма к оплате</msg>
			<msg name="title">Платеж PayPal PHP</msg>
			<msg name="hint_default">Форма оплаты через PayPal PHP</msg>        
		</messages>
	</lang>
	<lang name="en">
		<messages name="company.paymethod.edit">
			<msg name="paypal.php">PayPal PHP</msg>
		</messages>
		<messages name="company.paymethod">
			<msg name="module_paypal.php">PayPal PHP</msg>
		</messages>
		<messages name="company.paymethod.edit_paypal.php">
			<msg name="hint_name">Payment method name</msg>
			<msg name="days">days</msg>
			<msg name="autodelete">The period of removal of unpaid fees</msg>
			<msg name="hint_autodelete">Enter the auto deletion of unpaid fees</msg>
			<msg name="hint_default">Enter the data necessary for the interaction with the payment system, as well as other parameters that apply to payments</msg>
			<msg name="hint_minamount">The minimum amount for payment</msg>	  
			<msg name="minamount">The minimum payment</msg>
			<msg name="title">Options</msg>
			<msg name="priority">Priority</msg>
			<msg name="percent">percent</msg>
			<msg name="hint_priority">Methods of payment will be arranged according to priority. The higher the priority, the method of payment will be higher than in the drop-down list.</msg>
			<msg name="commission">Commission</msg>
			<msg name="hint_commission">Commission payment system. If the Commission pointed out, after the transfer of the payment to a specified percentage rate will be made</msg>
			<msg name="pperson">Private individual</msg>
			<msg name="psoleproprietor">Solo Entrepreneur</msg>
			<msg name="pcompany">Company</msg>
			<msg name="ptype">Status of the payer</msg>
			<msg name="hint_ptype">Specify the status of payers, which will be available this method of payment</msg>
			<msg name="null">Any</msg>
			<msg name="checkpayerd">Check the occupancy of properties payer</msg>
			<msg name="hint_checkpayer">The option includes checking the occupancy of properties payer and refusal to pay in case of empty fields</msg>
			<msg name="aemail">E-mail</msg>
			<msg name="hint_aemail">E-mail</msg>
			<msg name="hint_default">Fill in the form</msg>
			<msg name="hint_logourl">Address at which the logo is loaded</msg>
			<msg name="hint_posturl">API URL</msg>
			<msg name="logourl">Logo (URL)</msg>
			<msg name="posturl">API URL</msg>
		</messages>
		<messages name="credit.pay.paypal.php">
			<msg name="msg_extokmsg">Payment</msg>
			<msg name="amount">Amount</msg>
			<msg name="hint_amount">Total amount</msg>
			<msg name="title">PayPal PHP</msg>
			<msg name="hint_default">PayPal PHP</msg>        
		</messages>
	</lang>
</mgrdata>
Была ли эта информация полезной? Да | Нет
Личные инструменты