ФУНКЦИИ ДЛЯ РАБОТЫ С XML ИНТЕРФЕЙСАМИ WEBMONEY
Информация взята с сайта http://owebmoney.ru/download/
// ФУНКЦИИ ДЛЯ РАБОТЫ С XML ИНТЕРФЕЙСАМИ WEBMONEY
// Описания:
// - http://owebmoney.ru/xml1.shtml
// - http://owebmoney.ru/xml2.shtml
// - http://owebmoney.ru/articles/xml3.shtml
// - http://owebmoney.ru/articles/robots.shtml
// Последнее обновление - 7.08.09
// Для работы этих функций необходимы библиотеки PHP: simplexml, iconv, curl
// (c) Никита Сенченко, owebmoney.ru
БЛОК КОНСТАНТ
$Global_WMID="XXXXXXXXXXX"; // Ваш WMID $Path_Folder = "/home/site.ru/data/signer/"; // Путь к директории, в которой лежит .kwm $Path_Signer = "/home/site.ru/data/signer/wmsigner"; // Путь к WMSigner $XML_addr[1]="https://w3s.webmoney.ru/asp/XMLInvoice.asp"; $XML_addr[2]="https://w3s.webmoney.ru/asp/XMLTrans.asp"; $XML_addr[3]="https://w3s.webmoney.ru/asp/XMLOperations.asp"; $XML_addr[4]="https://w3s.webmoney.ru/asp/XMLOutInvoices.asp"; $XML_addr[5]="https://w3s.webmoney.ru/asp/XMLFinishProtect.asp"; $XML_addr[6]="https://w3s.webmoney.ru/asp/XMLSendMsg.asp"; $XML_addr[7]="https://w3s.webmoney.ru/asp/XMLClassicAuth.asp"; $XML_addr[8]="https://w3s.webmoney.ru/asp/XMLFindWMPurse.asp"; $XML_addr[9]="https://w3s.webmoney.ru/asp/XMLPurses.asp"; $XML_addr[10]="https://w3s.webmoney.ru/asp/XMLInInvoices.asp"; $XML_addr[11]="https://passport.webmoney.ru/asp/XMLGetWMPassport.asp"; $XML_addr[13]="https://w3s.webmoney.ru/asp/XMLRejectProtect.asp"; $XML_addr[14]="https://w3s.webmoney.ru/asp/XMLTransMoneyback.asp"; $XML_addr[151]="https://w3s.webmoney.ru/asp/XMLTrustList.asp"; $XML_addr[152]="https://w3s.webmoney.ru/asp/XMLTrustList2.asp"; $XML_addr[153]="https://w3s.webmoney.ru/asp/XMLTrustSave2.asp"; $XML_addr[16]="https://w3s.webmoney.ru/asp/XMLCreatePurse.asp"; $XML_addr[171]="https://arbitrage.webmoney.ru/xml/X17_CreateContract.aspx"; $XML_addr[172]="https://arbitrage.webmoney.ru/xml/X17_GetContractInfo.aspx"; $XML_addr[18]="https://merchant.webmoney.ru/conf/xml/XMLTransGet.asp";
ФУНКЦИЯ ФОРМИРУЕТ УНИКАЛЬНЫЙ УВЕЛИЧИВАЮЩИЙСЯ REQN
function _GetReqn(){
$time=microtime();
$int=substr($time,11);
$flo=substr($time,2,5);
return $int.$flo;
};
ФУНКЦИЯ ФОРМИРОВАНИЯ ПОДПИСИ
// На входе: строка для подписи. На выходе: строка с результатом подписывания
function _GetSign($inStr) {
global $Path_Folder, $Path_Signer;
// chdir($Path_Folder);
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "r") );
$process = proc_open($Path_Signer, $descriptorspec, $pipes);
fwrite($pipes[0], "$inStr\004\r\n");
fclose($pipes[0]);
$s = fgets($pipes[1], 133);
fclose($pipes[1]);
$return_value = proc_close($process);
return $s;
}АЛЬТЕРНАТИВНАЯ ФУНКЦИЯ ПОДПИСИ ДЛЯ PHP НИЖЕ 4.3.0
// На входе: строка для подписи. На выходе: строка с результатом подписывания
function _GetSign2($inStr){
global $Path_Folder, $Path_Signer;
chdir($Path_Folder);
$PlanStr = "$inStr\004\r\n";
$fp = popen($Path_Signer, "r+");
fwrite($fp,$PlanStr);
$s = fgets($fp, 133);
pclose($fp);
return $s;
}ОТПРАВКА POST-ЗАПРОСА ЧЕРЕЗ CURL
// На входе: URL для отправки и содержимое XML-запроса. На выходе: XML-ответ от WebMoney
function _GetAnswer($address, $xml){
// Инициализируем сеанс CURL
$ch = curl_init($address);
// В выводе CURL http-заголовки не нужны
curl_setopt($ch, CURLOPT_HEADER, 0);
// Возвращать результат, а не выводить его в браузер
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
// Метод http-запроса - POST
curl_setopt($ch, CURLOPT_POST,1);
// Что передаем?
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
// Путь к корневому сертификату
if($address=="https://passport.webmoney.ru/asp/XMLGetWMPassport.asp")
curl_setopt($ch, CURLOPT_CAINFO, "/home/site.ru/data/certs/ns.cer"); // для X11
elseif($address=="https://merchant.webmoney.ru/conf/xml/XMLTransGet.asp");
curl_setopt($ch, CURLOPT_CAINFO, "/home/site.ru/data/certs/verisign.cer"); // для X18
else
curl_setopt($ch, CURLOPT_CAINFO, "/home/site.ru/data/certs/WebMoneyCA.cer"); // для всех остальных
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
// Выполняем запрос, ответ помещаем в переменную $result;
$result=curl_exec($ch);
return $result;
}ИНТЕРФЕЙС X1. ВЫПИСКА СЧЕТА.
// На выходе: массив ['retval'=>код выполнения, 'retdesc'=>описание результата,
// 'date'=>дата и время, 'wminvid'=>уникальный номер счета]
function _WMXML1 ($orderid,$wmid,$purse,$amount,$desc,$address,$period,$expiration) {
global $Global_WMID, $XML_addr;
$reqn=_GetReqn();
$desc=trim($desc); $address=trim($address); $amount=floatval($amount);
$rsign=_GetSign($orderid.$wmid.$purse.$amount.$desc.$address.$period.$expiration.$reqn);
$address=htmlspecialchars($address, ENT_QUOTES);
$desc=htmlspecialchars($desc, ENT_QUOTES);
$address=iconv("CP1251", "UTF-8", $address);
$desc=iconv("CP1251", "UTF-8", $desc);
$xml="
<w3s.request>
<reqn>$reqn</reqn>
<wmid>$Global_WMID</wmid>
<sign>$rsign</sign>
<invoice>
<orderid>$orderid</orderid>
<customerwmid>$wmid</customerwmid>
<storepurse>$purse</storepurse>
<amount>$amount</amount>
<desc>$desc</desc>
<address>$address</address>
<period>$period</period>
<expiration>$expiration</expiration>
</invoice>
</w3s.request>";
$resxml=_GetAnswer($XML_addr[1], $xml);
//echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
return $result;
}
$result['retval']=strval($xmlres->retval);
$result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
$result['date']=strval($xmlres->invoice->datecrt);
$result['wminvid']=strval($xmlres->invoice->attributes()->id);
return $result;
}ИНТЕРФЕЙС X2. ОТПРАВКА ПЕРЕВОДА.
// На выходе: массив ['retval'=>код выполнения, 'retdesc'=>описание результата, 'date'=>дата и время]
function _WMXML2 ($tranid,$purse,$rpurse,$amount,$period,$pcode,$desc,$wminvid) {
global $Global_WMID, $XML_addr;
$reqn=_GetReqn();
$desc=trim($desc); $pcode=trim($pcode); $amount=floatval($amount);
$rsign=_GetSign($reqn.$tranid.$purse.$rpurse.$amount.$period.$pcode.$desc.$wminvid);
$pcode=htmlspecialchars($pcode, ENT_QUOTES);
$desc=htmlspecialchars($desc, ENT_QUOTES);
$pcode=iconv("CP1251", "UTF-8", $pcode);
$desc=iconv("CP1251", "UTF-8", $desc);
$xml="
<w3s.request>
<reqn>$reqn</reqn>
<wmid>$Global_WMID</wmid>
<sign>$rsign</sign>
<trans>
<tranid>$tranid</tranid>
<pursesrc>$purse</pursesrc>
<pursedest>$rpurse</pursedest>
<amount>$amount</amount>
<period>$period</period>
<pcode>$pcode</pcode>
<desc>$desc</desc>
<wminvid>$wminvid</wminvid>
</trans>
</w3s.request>";
$resxml=_GetAnswer($XML_addr[2], $xml);
// echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
return $result;
}
$result['retval']=strval($xmlres->retval);
$result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
$result['date']=strval($xmlres->operation->datecrt);
return $result;
}ИНТЕРФЕЙС X3. ПОЛУЧЕНИЕ ИСТОРИИ ОПЕРАЦИЙ.
// На выходе: массив ['retval'=>код выполнения, 'retdesc'=>описание результата,
// 'cnt'=>количество операций в выборке, 'operations'=>массив с операциями]
function _WMXML3 ($purse,$wmtranid,$tranid,$wminvid,$orderid,$datestart,$datefinish) {
global $Global_WMID, $XML_addr;
$reqn=_GetReqn();
$rsign=_GetSign($purse.$reqn);
$xml="
<w3s.request>
<reqn>$reqn</reqn>
<wmid>$Global_WMID</wmid>
<sign>$rsign</sign>
<getoperations>
<purse>$purse</purse>
<wmtranid>$wmtranid</wmtranid>
<tranid>$tranid</tranid>
<wminvid>$wminvid</wminvid>
<orderid>$orderid</orderid>
<datestart>$datestart</datestart>
<datefinish>$datefinish</datefinish>
</getoperations>
</w3s.request>";
$resxml=_GetAnswer($XML_addr[3], $xml);
// echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
return $result;
}
$result['retval']=strval($xmlres->retval);
$result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
$result['cnt']=strval($xmlres->operations->attributes()->cnt);
if($result['cnt']>0) {
// В элементе $result['operations'] формируем элементы, каждый из которых является
// массивом с параметрами операции
foreach ($xmlres->operations->operation as $operation) {
// определяем тип операции (входящая, исходящая)
// и кошелек корреспондента
$pursesrc=strval($operation->pursesrc);
$pursedest=strval($operation->pursedest);
if($pursesrc==$purse) {
$type="out"; $corrpurse=$pursedest;
} elseif($pursedest==$purse) {
$type="in"; $corrpurse=$pursesrc;
}
$result['operations'][strval($operation->attributes()->id)] = Array
(
'tranid'=>strval($operation->tranid),
'wminvid'=>strval($operation->wminvid),
'orderid'=>strval($operation->orderid),
'type'=>$type,
'corrpurse'=>$corrpurse,
'corrwmid'=>strval($operation->corrwm),
'amount'=>floatval($operation->amount),
'comiss'=>floatval($operation->comiss),
'rest'=>floatval($operation->rest),
'protection'=>strval($operation->opertype),
'desc'=>iconv("UTF-8", "CP1251", strval($operation->desc)),
'datecrt'=>strval($operation->datecrt)
);
}
}
return $result;
}ИНТЕРФЕЙС X4. ПРОВЕРКА ВЫПИСАННЫХ СЧЕТОВ.
// На выходе: массив ['retval'=>код выполнения, 'retdesc'=>описание результата,
// 'cnt'=>количество счетов вошедших в выборку, 'invoices'=>массив со счетами]
function _WMXML4 ($purse,$wminvid,$orderid,$datestart,$datefinish) {
global $Global_WMID, $XML_addr;
$reqn=_GetReqn();
$rsign=_GetSign($purse.$reqn);
$xml="
<w3s.request>
<reqn>$reqn</reqn>
<wmid>$Global_WMID</wmid>
<sign>$rsign</sign>
<getoutinvoices>
<purse>$purse</purse>
<wminvid>$wminvid</wminvid>
<orderid>$orderid</orderid>
<datestart>$datestart</datestart>
<datefinish>$datefinish</datefinish>
</getoutinvoices>
</w3s.request>";
$resxml=_GetAnswer($XML_addr[4], $xml);
//echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
return $result;
}
$result['retval']=strval($xmlres->retval);
$result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
$result['cnt']=strval($xmlres->outinvoices->attributes()->cnt);
if($result['cnt']>0) {
// В элементе $result['invoices'] формируем массив [номер счета в WM] = состояние оплаты
foreach ($xmlres->outinvoices->outinvoice as $invoice) {
$wminvid=strval($invoice->attributes()->id);
$state=strval($invoice->state);
$result['invoices'][$wminvid]=$state;
}
}
return $result;
}ИНТЕРФЕЙС X6. ОТПРАВКА СООБЩЕНИЯ.
// На выходе: массив ['retval'=>код выполнения, 'retdesc'=>описание результата, 'date'=>дата и время]
function _WMXML6 ($wmid,$msg,$subj) {
global $Global_WMID, $XML_addr;
$reqn=_GetReqn();
$msg=trim($msg); $subj=trim($subj);
$msg=str_replace ("\r", "", $msg);
$rsign=_GetSign($wmid.$reqn.$msg.$subj);
$msg=htmlspecialchars($msg, ENT_QUOTES);
$subj=htmlspecialchars($subj, ENT_QUOTES);
$msg=iconv("CP1251", "UTF-8", $msg);
$subj=iconv("CP1251", "UTF-8", $subj);
$xml="
<w3s.request>
<reqn>$reqn</reqn>
<wmid>$Global_WMID</wmid>
<sign>$rsign</sign>
<message>
<receiverwmid>$wmid</receiverwmid>
<msgsubj>$subj</msgsubj>
<msgtext>$msg</msgtext>
</message>
</w3s.request>";
$resxml=_GetAnswer($XML_addr[6], $xml);
// echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
return $result;
}
$result['retval']=strval($xmlres->retval);
$result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
$result['date']=strval($xmlres->message->datecrt);
return $result;
}ИНТЕРФЕЙС X7. Проверка подписи
// На входе: WMID, чью подпись нужно проверить; исходная строка; подпись исходной строки
// На выходе: массив ['retval'=>код выполнения, 'retdesc'=>описание результата, 'res'=>результат проверки (yes\no)]
function _WMXML7 ($wmid,$string,$sign) {
global $Global_WMID, $XML_addr;
$rsign=_GetSign($Global_WMID.$wmid.$string.$sign);
$xml="
<w3s.request>
<wmid>$Global_WMID</wmid>
<sign>$rsign</sign>
<testsign>
<wmid>$wmid</wmid>
<plan><![CDATA[$string]]></plan>
<sign>$sign</sign>
</testsign>
</w3s.request>";
$resxml=_GetAnswer($XML_addr[7], $xml);
// echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
} else {
$result['retval']=strval($xmlres->retval);
$result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
$result['res']=strval($xmlres->testsign->res);
}
return $result;
}ИНТЕРФЕЙС X8. ОПРЕДЕЛЕНИЕ ПРИНАДЛЕЖНОСТИ КОШЕЛЬКА.
// На выходе: массив ['wmid'=>wmid, 'purse'=>кошелек, 'retval'=>код выполнения, 'retdesc'=>описание результата]
function _WMXML8 ($wmid,$purse) {
global $Global_WMID, $XML_addr;
$reqn=_GetReqn();
$rsign=_GetSign($wmid.$purse);
$xml="
<w3s.request>
<reqn>$reqn</reqn>
<wmid>$Global_WMID</wmid>
<sign>$rsign</sign>
<testwmpurse>
<wmid>$wmid</wmid>
<purse>$purse</purse>
</testwmpurse>
</w3s.request>";
$resxml=_GetAnswer($XML_addr[8], $xml);
// echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
return $result;
}
$result['wmid']=strval($xmlres->testwmpurse->wmid);
$result['purse']=strval($xmlres->testwmpurse->purse);
$result['retval']=strval($xmlres->retval);
$result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
return $result;
}ИНТЕРФЕЙС X9. ПОЛУЧЕНИЕ БАЛАНСОВ
// На выходе: массив ['retval'=>код выполнения, 'retdesc'=>описание результата,
// 'purses'=>массив балансов]
function _WMXML9 () {
global $Global_WMID, $XML_addr;
$reqn=_GetReqn();
$rsign=_GetSign($Global_WMID.$reqn);
$xml="
<w3s.request>
<reqn>$reqn</reqn>
<wmid>$Global_WMID</wmid>
<sign>$rsign</sign>
<getpurses>
<wmid>$Global_WMID</wmid>
</getpurses>
</w3s.request>";
$resxml=_GetAnswer($XML_addr[9], $xml);
// echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
return $result;
}
$result['retval']=strval($xmlres->retval);
$result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
if($result['retval']==0 && $result['retval']!==false) {
// Формируем массив [номер кошелька] = баланс
foreach ($xmlres->purses->purse as $purse) {
$pursename=strval($purse->pursename);
$amount=floatval($purse->amount);
$result['purses'][$pursename]=$amount;
}
}
return $result;
}ИНТЕРФЕЙС X11. ПОЛУЧЕНИЕ ИНФОРМАЦИИ ИЗ АТТЕСТАТА.
// На выходе: массив ['att'=>код аттестата, 'recalled'=>флаг отзыва аттестата, 'retval'=>код выполнения, 'retdesc'=>описание результата]
function _WMXML11 ($wmid) {
global $XML_addr;
$xml="
<request>
<wmid></wmid>
<passportwmid>$wmid</passportwmid>
<sign></sign>
<params>
<dict>1</dict>
<info>1</info>
<mode>0</mode>
</params>
</request>";
$resxml=_GetAnswer($XML_addr[11], $xml);
// echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['att']=0;
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
return $result;
}
if($xmlres->certinfo->attestat->row)
$result['att']=strval($xmlres->certinfo->attestat->row->attributes()->tid);
else {
$result['att']=0;
$result['retval']=1001;
$result['retdesc']="Информация об аттестате не получена. Возможно, неверно указан WMID.";
return $result;
}
$result['recalled']=$xmlres->certinfo->attestat->row->attributes()->recalled;
$result['retval']=strval($xmlres->attributes()->retval);
return $result;
}ИНТЕРФЕЙС X14. БЕСКОМИССИОННЫЙ ВОЗВРАТ.
// На выходе: массив ['retval'=>код выполнения, 'retdesc'=>описание результата,
// 'date'=>дата и время, 'wmtranid_ret'=>номер транзакции возврата]
function _WMXML14 ($wmtranid,$amount) {
global $Global_WMID, $XML_addr;
$reqn=_GetReqn();
$amount=floatval($amount);
$rsign=_GetSign($reqn.$wmtranid.$amount);
$xml="
<w3s.request>
<reqn>$reqn</reqn>
<wmid>$Global_WMID</wmid>
<sign>$rsign</sign>
<trans>
<inwmtranid>$wmtranid</inwmtranid>
<amount>$amount</amount>
</trans>
</w3s.request>";
$resxml=_GetAnswer($XML_addr[14], $xml);
// echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
return $result;
}
$result['retval']=strval($xmlres->retval);
$result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
$result['wmtranid_ret']=strval($xmlres->operation->attributes()->id);
$result['date']=strval($xmlres->operation->datecrt);
return $result;
}ИНТЕРФЕЙС X16. СОЗДАНИЕ КОШЕЛЬКА.
// На выходе: массив ['retval'=>код выполнения, 'retdesc'=>описание результата, 'purse'=>номер кошелька]
function _WMXML16 ($type,$desc) {
global $Global_WMID, $XML_addr;
$reqn=_GetReqn();
$rsign=_GetSign($Global_WMID.$type.$reqn);
$desc=trim($desc);
$desc=htmlspecialchars($desc, ENT_QUOTES);
$desc=iconv("CP1251", "UTF-8", $desc);
$xml="
<w3s.request>
<reqn>$reqn</reqn>
<wmid>$Global_WMID</wmid>
<sign>$rsign</sign>
<createpurse>
<wmid>$Global_WMID</wmid>
<pursetype>$type</pursetype>
<desc>$desc</desc>
</createpurse>
</w3s.request>";
$resxml=_GetAnswer($XML_addr[16], $xml);
// echo $resxml;
$xmlres = simplexml_load_string($resxml);
if(!$xmlres) {
$result['retval']=1000;
$result['retdesc']="Не получен XML-ответ";
return $result;
}
$result['retval']=strval($xmlres->retval);
$result['retdesc']=iconv("UTF-8", "CP1251", strval($xmlres->retdesc));
$result['purse']=strval($xmlres->purse->pursename);
return $result;
}
не согласятся-фиг с ними, согласятся-хорошо. А что ответить? Вот сообщение какое написать?