ФУНКЦИИ ДЛЯ РАБОТЫ С 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; }