Интеграция с платежной системой Robokassa v2

Материал из BiTel WiKi

(Различия между версиями)
Перейти к: навигация, поиск
Строка 1: Строка 1:
Добавляем функционал платежной системы ROBOKASSA в BGBilling
Добавляем функционал платежной системы ROBOKASSA в BGBilling
-
Для реализации функций платежной системы ROBOKASSA будем использовать возможности библиотеки xalan. Подробнее об этой библиотеке прочитать можно [http://xml.apache.org/xalan-j/ тут].
+
Для реализации функций платежной системы ROBOKASSA будем использовать возможности web-action's в BGBilling.
-
Одна из возможностей этой библиотеки – вызов внешних функций Java классов. Это нам и понадобиться для генерации MD5, а так же эта библиотека по-умолчанию используется и в BGBilling в web-интерфейсе для преобразования xml.
+
1. WebAction_OnlinePay - Проверяет не закрыт ли договор. Тут же можно добавить и другие необходимые проверки...
 +
2. WebAction_RequestRobokassa - Регистрирует в таблице запрос на платеж, генерирует MD5 для запроса и перенаправляет запрос на сервер ROBOKASSA.
-
Всё взаимодействие с платежной системой заключается в следующем: отправляем им запрос (с помощью кнопки) на платеж, платежная система отрабатывает свой функционал и возвращает нам ответ (ResultURL), который мы обрабатываем с помощью сервлета (mapping сервлета в BGBilling рассмотрим позже).Возвращаем им результат обработки: положительный или нет. В процессе обработки если результат положительный, то регистрируем приход денег в BGBilling и пересчитываем баланс; иначе не регистрируем платеж в биллинге.
+
Всё взаимодействие с платежной системой заключается в следующем: отправляем им запрос (с помощью кнопки) на платеж, платежная система отрабатывает свой функционал и возвращает нам ответ (ResultURL), который мы обрабатываем с помощью сервлета (mapping сервлета в BGBilling рассмотрим позже).Возвращаем им результат обработки: положительный или нет. В процессе обработки если результат положительный, то регистрируем приход денег в BGBilling, пересчитываем баланс и генерируем событие прихода платежа; иначе не регистрируем платеж в биллинге.
Начнем реализацию.
Начнем реализацию.
Все новые сторонние и самостоятельно сделанные Java классы будем помещать в каталог BGBillingServer/lib/
Все новые сторонние и самостоятельно сделанные Java классы будем помещать в каталог BGBillingServer/lib/
-
В нашем случае это robokassalib.jar, servletrblib.jar, commons-codec-1.4.jar
+
В нашем случае это robokassalib.jar (web-action's), servletrblib.jar (сервлет), commons-codec-1.4.jar
Добавляем в меню в web-интерфейсе пользователя раздел Online платежи.
Добавляем в меню в web-интерфейсе пользователя раздел Online платежи.
Строка 23: Строка 24:
</xsl:template></source>
</xsl:template></source>
-
1. Далее переходим к файлу main.xsl. Убеждаемся что файл начинается со следующих строк
+
1. Добавляем в файл main.xsl обработку action=OnlinePay. Для этого в файле прописываем следующие строки:
-
 
+
-
<source lang="xml">
+
-
<?xml version="1.0" encoding="windows-1251"?>
+
-
<xsl:stylesheet version="1.0"
+
-
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+
-
xmlns:xalan = "http://xml.apache.org/xalan"
+
-
xmlns:java="http://xml.apache.org/xalan/java"
+
-
>
+
-
</source>
+
-
 
+
-
Если нет, добавляем недостающие элементы
+
-
 
+
-
2. Добавляем в файл main.xsl обработку action=OnlinePay. Для этого в файле прописываем следующие строки:
+
<source lang="xml">
<source lang="xml">
Строка 49: Строка 37:
</source>
</source>
-
Далее :
+
Далее в этом же файле:
<source lang="xml">
<source lang="xml">
Строка 70: Строка 58:
<source lang="xml">
<source lang="xml">
<xsl:template name="OnlinePay">
<xsl:template name="OnlinePay">
-
<xsl:variable name="lsum_o" select="''"/>
+
<xsl:variable name="err" select="/data/msg/@err"/>
-
<xsl:variable name="lcid" select="@id"/>
+
<xsl:if test="$err = 1">
-
<xsl:variable name="mlogin" select="java:ru.bgbilling.robokassa.util.md5.getMrthLogin()"/>
+
<xsl:value-of select="/data/msg/@text"/>
-
<xsl:variable name="md5" select="java:ru.bgbilling.robokassa.util.md5.md5c($lsum_o,0,$lcid)"/>
+
</xsl:if>
-
<xsl:variable name="desc" select="concat('Пополнение баланса договора ',@title)"/>
+
<xsl:if test="$err = 0">
-
<table border="0">
+
<table border="0">
-
<tr><td>
+
<tr><td align="left">
-
</td>
+
<form method="POST" action="webexecuter" target="_blank">
-
<td align="left">
+
<input type="hidden" name="action" value="RequestRobokassa" />
-
<form method="POST" action="https://merchant.roboxchange.com/Index.aspx" target="_blank">
+
<input type="hidden" name="mid" value="contract" />
-
<xsl:element name="input">
+
<xsl:call-template name="submit">
-
  <xsl:attribute name="type">hidden</xsl:attribute>
+
<xsl:with-param name="title" select="'Оплатить с помощью ROBOKASSA'"/>
-
  <xsl:attribute name="name">MrchLogin</xsl:attribute>
+
</xsl:call-template>
-
  <xsl:attribute name="value"><xsl:value-of select="$mlogin"/></xsl:attribute>
+
</form>
-
        </xsl:element>
+
</td>
-
<xsl:element name="input">
+
</tr>
-
  <xsl:attribute name="type">hidden</xsl:attribute>
+
</table>
-
  <xsl:attribute name="name">OutSum</xsl:attribute>
+
-
  <xsl:attribute name="value"><xsl:value-of select="$lsum_o"/></xsl:attribute>
+
-
                </xsl:element>
+
-
<xsl:element name="input">
+
-
  <xsl:attribute name="type">hidden</xsl:attribute>
+
-
  <xsl:attribute name="name">InvId</xsl:attribute>
+
-
  <xsl:attribute name="value">0</xsl:attribute>
+
-
</xsl:element>
+
-
<xsl:element name="input">
+
-
  <xsl:attribute name="type">hidden</xsl:attribute>
+
-
  <xsl:attribute name="name">Desc</xsl:attribute>
+
-
  <xsl:attribute name="value"><xsl:value-of select="$desc"/></xsl:attribute>
+
-
</xsl:element>
+
-
<xsl:element name="input">
+
-
  <xsl:attribute name="type">hidden</xsl:attribute>
+
-
  <xsl:attribute name="name">shp_contract</xsl:attribute>
+
-
  <xsl:attribute name="value"><xsl:value-of select="$lcid"/></xsl:attribute>
+
-
</xsl:element>
+
-
<input type="hidden" name="IncCurrLabel" value="PCR" />
+
-
<xsl:element name="input">
+
-
  <xsl:attribute name="type">hidden</xsl:attribute>
+
-
  <xsl:attribute name="name">SignatureValue</xsl:attribute>
+
-
  <xsl:attribute name="value"><xsl:value-of select="$md5" /></xsl:attribute>
+
-
    </xsl:element>
+
-
<input type="hidden" name="Culture" value="ru" />
+
-
<xsl:call-template name="submit"><xsl:with-param name="title" select="'Оплатить с помощью ROBOKASSA'"/></xsl:call-template>
+
-
</form>
+
-
</td></tr></table>
+
 +
</xsl:if>
</xsl:template>
</xsl:template>
</source>
</source>
-
В описании шаблона мы используем параметры
+
В описании шаблона мы проверяем есть ли ошибка, которую показываем. Если ошибки нет, то создаем кнопку для направления клиента на сайт ROBOKASSA.
 +
При создании кнопки есть скрытый параметр action = RequestRobokassa. Это означает что, запрос сначала пойдет на наш web-action, а потом уже на сайт
 +
робокассы.
-
<source lang="xml">
 
-
<xsl:variable name="lsum_o" select="''"/>
 
-
<xsl:variable name="lcid" select="@id"/>
 
-
<xsl:variable name="mlogin" select="java:ru.bgbilling.robokassa.util.md5.getMrthLogin()"/>
 
-
<xsl:variable name="md5" select="java:ru.bgbilling.robokassa.util.md5.md5c($lsum_o,0,$lcid)"/>
 
-
<xsl:variable name="desc" select="concat('Пополнение баланса договора ',@title)"/>
 
-
</source> ,
 
где  lsum_o – сумма платежа. Сумму мы изначально не задаем. Пользователь суму будет указывать позже на страницу оплаты.
где  lsum_o – сумма платежа. Сумму мы изначально не задаем. Пользователь суму будет указывать позже на страницу оплаты.

Версия 01:47, 24 февраля 2010

Добавляем функционал платежной системы ROBOKASSA в BGBilling

Для реализации функций платежной системы ROBOKASSA будем использовать возможности web-action's в BGBilling. 1. WebAction_OnlinePay - Проверяет не закрыт ли договор. Тут же можно добавить и другие необходимые проверки... 2. WebAction_RequestRobokassa - Регистрирует в таблице запрос на платеж, генерирует MD5 для запроса и перенаправляет запрос на сервер ROBOKASSA.

Всё взаимодействие с платежной системой заключается в следующем: отправляем им запрос (с помощью кнопки) на платеж, платежная система отрабатывает свой функционал и возвращает нам ответ (ResultURL), который мы обрабатываем с помощью сервлета (mapping сервлета в BGBilling рассмотрим позже).Возвращаем им результат обработки: положительный или нет. В процессе обработки если результат положительный, то регистрируем приход денег в BGBilling, пересчитываем баланс и генерируем событие прихода платежа; иначе не регистрируем платеж в биллинге.

Начнем реализацию.

Все новые сторонние и самостоятельно сделанные Java классы будем помещать в каталог BGBillingServer/lib/ В нашем случае это robokassalib.jar (web-action's), servletrblib.jar (сервлет), commons-codec-1.4.jar

Добавляем в меню в web-интерфейсе пользователя раздел Online платежи. Для этого в файл common.xsl добавляем следующий строки:

<xsl:template name="standart_menu">
………………
  <tr>
    <th><img src="img/strelki.gif"/></th>
      <td><a href="?action=OnlinePay&amp;mid=contract">Online платежи</a></td>
  </tr>	
</xsl:template>

1. Добавляем в файл main.xsl обработку action=OnlinePay. Для этого в файле прописываем следующие строки:

<xsl:template name="title">
<xsl:choose>
……………
	<xsl:when test="data/@action = 'OnlinePay'">Online платежи</xsl:when>
……………
	<xsl:otherwise>НОВОСТИ</xsl:otherwise>
</xsl:choose>
</xsl:template>

Далее в этом же файле:

<xsl:template match="/data">
<xsl:choose>
……..
	<xsl:when test="@action = 'OnlinePay'">
		<xsl:call-template name="OnlinePay"/>
	</xsl:when>
…….
	<xsl:otherwise>
		<xsl:call-template name="news"/>
	</xsl:otherwise>
</xsl:choose>
</xsl:template>

Далее описываем шаблон OnlinePay в main.xsl:

<xsl:template name="OnlinePay">
	<xsl:variable name="err" select="/data/msg/@err"/>
	<xsl:if test="$err = 1">
		<xsl:value-of select="/data/msg/@text"/>
	</xsl:if>
	<xsl:if test="$err = 0">	
		<table border="0">
			<tr><td align="left">
					<form method="POST" action="webexecuter" target="_blank">
						<input type="hidden" name="action" value="RequestRobokassa" />
						<input type="hidden" name="mid" value="contract" />
						<xsl:call-template name="submit">
							<xsl:with-param name="title" select="'Оплатить с помощью ROBOKASSA'"/>
						</xsl:call-template>
					</form>
				</td>
			</tr>
		</table>
 
	</xsl:if>
</xsl:template>

В описании шаблона мы проверяем есть ли ошибка, которую показываем. Если ошибки нет, то создаем кнопку для направления клиента на сайт ROBOKASSA. При создании кнопки есть скрытый параметр action = RequestRobokassa. Это означает что, запрос сначала пойдет на наш web-action, а потом уже на сайт робокассы.


где lsum_o – сумма платежа. Сумму мы изначально не задаем. Пользователь суму будет указывать позже на страницу оплаты. lcid – идентификатор договора в BGBilling, mlogin – логин под которым зарегистрирован оператор (магазин) в системе робокасса, md5 – MD5 по строке mlogin:lsum_o:invid:pass1:ship_contract=lcid Эта строка формируется с помощью функции md5c класса ru.bgbilling.robokassa.util.md5. InvID в нашем случае всегда будет отправляться нулевой, а платежная система будет его создавать за нас и нам потом отправлять. После этого формируем кнопку с необходимыми параметрами в соответствии с документацией РОБОКАССЫ. В общем если все параметры указаны верно, и правильно генерируется MD5, то кнопка будет работать и правильно отправлять пользователя на страницу оплаты.

3. Обработка ответа платежной системы РОБОКАССА. Ответ платежной системы будет направляться на адрес, указанный на сайте РОБОКАССЫ в личном кабинете оператора (магазина) в поле ResultURL. В нашем случаем обработкой ответа будет заниматься сервлет. Для того чтобы использовать этот сервлет на сервере BGBilling необходимо в файле data/default.web.xml указать сведения об этом сервлете. В нашем случае это следующие строки

<servlet>
	<servlet-name>resultrobokassa</servlet-name>
	<servlet-class>ru.bgbilling.robokassa.servlet.roboxre</servlet-class>
    	 <load-on-startup>6</load-on-startup>
    </servlet>

и далее в этом же файле, где происходит mapping

<servlet-mapping>
	<servlet-name>resultrobokassa</servlet-name>
	<url-pattern>/resrb</url-pattern>
    </servlet-mapping>

Получается сам Java класс это ru.bgbilling.robokassa.servlet.roboxre

Логика обработки ответа платежной системы: Строка, по которой формируется MD5 для ответа sum_o:invid:pass2:ship_contarct=cid Более детально по параметрам ответа платежной системы смотрите в документации робокассы.

А) Сервлет соединяется с БД на основании параметров, которые указаны в файле data/data.properties. Если соединились с Бд удачно, то идем далее. Если не соединились удачно, то возвращаем ответ платежной системе bad sign и не регистрируем платеж в биллинге.

Б) Для генерации MD5 при формировании кнопки для перехода на сайт платежной системы, и при работе сервлета используются параметры из файла data/robokassa.properties

В) Проверяется параметр SignatureValue из ответа платежной с темы со значением, что получиться у нас. Если значения совпадают, то выполняем действия далее. Если не совпали, то возвращаем ответ платежной системе – bad sign и не регистрируем платеж в биллинге.

Г) Регистрируем запись в нашей контролирующей таблице dsi_payment_robokassa.

Скрипт для создания этой таблицы:

CREATE TABLE `dsi_payment_robokassa` (
  `inv_id` int(10) UNSIGNED NOT NULL,
  `cid` int(10) UNSIGNED NOT NULL,
  `dt` datetime NOT NULL,
  `pid` int(10) UNSIGNED DEFAULT NULL,
  `sum` decimal(10,0) DEFAULT NULL,
  PRIMARY KEY  (`inv_id`),
  KEY `cid` (`cid`),
  KEY `dt` (`dt`),
  KEY `pid` (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Как видим внешний ключ у таблицы на поле inv_id – это и есть контролирующий элемент. Сделано это для того, чтобы невозможно было один платеж зарегистрировать несколько раз в системе и чтобы не регистрировать ошибочно приходы в биллинге. Повторно добавить запись с таким же inv_id невозможно, если происходит такая исключительная ситуация, то в сервлете этот момент отрабатывается, платежной системе возвращается bad_sign и по e-mail оповещается о таком случае. Если добавление записи произошло удачно, то идем далее.

Д) С помощью API BGBilling добавляем приход. Пересчитываем баланс. Обновляем в таблице dsi_payment_robokassa значение поля pid на идентификатор прихода.

Г) Если все прошло удачно – возвращаем ответ платежной системе OKnInvID. Допустим, если от платежной системы пришёл ответ, где invid=6, то наш ответ будет OK6

Исходников и сами библиотеки не привожу. Если кому-нибудь будет нужно вышлю на e-mail, обращайтесь.

--focus 24.11.2009

Личные инструменты