payneteasy-payneteasyapi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gemtest +0 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +18 -0
- data/README.md +54 -0
- data/Rakefile +8 -0
- data/doc/00-basic-tutorial.md +254 -0
- data/doc/01-library-internals.md +6 -0
- data/doc/02-payment-scenarios.md +9 -0
- data/doc/library-internals/00-payment-data.md +162 -0
- data/doc/library-internals/01-payment-processor.md +163 -0
- data/doc/library-internals/02-validator.md +55 -0
- data/doc/library-internals/03-property-accessor.md +76 -0
- data/doc/payment-scenarios/00-sale-transactions.md +90 -0
- data/doc/payment-scenarios/01-preauth-capture-transactions.md +105 -0
- data/doc/payment-scenarios/02-transfer-transactions.md +89 -0
- data/doc/payment-scenarios/03-return-transactions.md +52 -0
- data/doc/payment-scenarios/04-recurrent-transactions.md +110 -0
- data/doc/payment-scenarios/05-payment-form-integration.md +59 -0
- data/doc/payment-scenarios/06-merchant-callbacks.md +29 -0
- data/example/capture.rb +12 -0
- data/example/common/functions.rb +56 -0
- data/lib/paynet_easy/paynet_easy_api/callback/callback_factory.rb +47 -0
- data/lib/paynet_easy/paynet_easy_api/callback/callback_prototype.rb +186 -0
- data/lib/paynet_easy/paynet_easy_api/callback/customer_return_callback.rb +28 -0
- data/lib/paynet_easy/paynet_easy_api/callback/paynet_easy_callback.rb +44 -0
- data/lib/paynet_easy/paynet_easy_api/error/paynet_error.rb +4 -0
- data/lib/paynet_easy/paynet_easy_api/error/request_error.rb +6 -0
- data/lib/paynet_easy/paynet_easy_api/error/response_error.rb +6 -0
- data/lib/paynet_easy/paynet_easy_api/error/validation_error.rb +6 -0
- data/lib/paynet_easy/paynet_easy_api/payment_data/billing_address.rb +41 -0
- data/lib/paynet_easy/paynet_easy_api/payment_data/credit_card.rb +32 -0
- data/lib/paynet_easy/paynet_easy_api/payment_data/customer.rb +35 -0
- data/lib/paynet_easy/paynet_easy_api/payment_data/data.rb +13 -0
- data/lib/paynet_easy/paynet_easy_api/payment_data/payment.rb +190 -0
- data/lib/paynet_easy/paynet_easy_api/payment_data/payment_transaction.rb +188 -0
- data/lib/paynet_easy/paynet_easy_api/payment_data/query_config.rb +95 -0
- data/lib/paynet_easy/paynet_easy_api/payment_data/recurrent_card.rb +40 -0
- data/lib/paynet_easy/paynet_easy_api/payment_processor.rb +251 -0
- data/lib/paynet_easy/paynet_easy_api/paynet_easy_api.rb +26 -0
- data/lib/paynet_easy/paynet_easy_api/query/capture_query.rb +30 -0
- data/lib/paynet_easy/paynet_easy_api/query/create_card_ref_query.rb +78 -0
- data/lib/paynet_easy/paynet_easy_api/query/get_card_info_query.rb +49 -0
- data/lib/paynet_easy/paynet_easy_api/query/make_rebill_query.rb +37 -0
- data/lib/paynet_easy/paynet_easy_api/query/preauth_form_query.rb +10 -0
- data/lib/paynet_easy/paynet_easy_api/query/preauth_query.rb +10 -0
- data/lib/paynet_easy/paynet_easy_api/query/prototype/payment_form_query.rb +69 -0
- data/lib/paynet_easy/paynet_easy_api/query/prototype/payment_query.rb +71 -0
- data/lib/paynet_easy/paynet_easy_api/query/prototype/query.rb +302 -0
- data/lib/paynet_easy/paynet_easy_api/query/query_factory.rb +19 -0
- data/lib/paynet_easy/paynet_easy_api/query/return_query.rb +46 -0
- data/lib/paynet_easy/paynet_easy_api/query/sale_form_query.rb +10 -0
- data/lib/paynet_easy/paynet_easy_api/query/sale_query.rb +53 -0
- data/lib/paynet_easy/paynet_easy_api/query/status_query.rb +50 -0
- data/lib/paynet_easy/paynet_easy_api/query/transfer_by_ref_query.rb +41 -0
- data/lib/paynet_easy/paynet_easy_api/query/transfer_form_query.rb +10 -0
- data/lib/paynet_easy/paynet_easy_api/transport/callback_response.rb +21 -0
- data/lib/paynet_easy/paynet_easy_api/transport/gateway_client.rb +91 -0
- data/lib/paynet_easy/paynet_easy_api/transport/request.rb +20 -0
- data/lib/paynet_easy/paynet_easy_api/transport/response.rb +136 -0
- data/lib/paynet_easy/paynet_easy_api/util/property_accessor.rb +60 -0
- data/lib/paynet_easy/paynet_easy_api/util/string.rb +9 -0
- data/lib/paynet_easy/paynet_easy_api/util/validator.rb +110 -0
- data/payneteasy-payneteasyapi.gemspec +16 -0
- data/test/paynet_easy/paynet_easy_api/callback/callback_factory_test.rb +22 -0
- data/test/paynet_easy/paynet_easy_api/callback/callback_test_prototype.rb +168 -0
- data/test/paynet_easy/paynet_easy_api/callback/customer_return_callback_test.rb +95 -0
- data/test/paynet_easy/paynet_easy_api/callback/paynet_easy_callback_test.rb +101 -0
- data/test/paynet_easy/paynet_easy_api/fake.rb +71 -0
- data/test/paynet_easy/paynet_easy_api/payment_processor_test.rb +255 -0
- data/test/paynet_easy/paynet_easy_api/query/capture_query_test.rb +48 -0
- data/test/paynet_easy/paynet_easy_api/query/create_card_ref_query_test.rb +116 -0
- data/test/paynet_easy/paynet_easy_api/query/get_card_info_query_test.rb +116 -0
- data/test/paynet_easy/paynet_easy_api/query/make_rebill_query_test.rb +59 -0
- data/test/paynet_easy/paynet_easy_api/query/prototype/payment_query_test_prototype.rb +117 -0
- data/test/paynet_easy/paynet_easy_api/query/prototype/query_test_prototype.rb +190 -0
- data/test/paynet_easy/paynet_easy_api/query/prototype/sync_query_test_prototype.rb +88 -0
- data/test/paynet_easy/paynet_easy_api/query/query_factory_test.rb +21 -0
- data/test/paynet_easy/paynet_easy_api/query/return_query_test.rb +58 -0
- data/test/paynet_easy/paynet_easy_api/query/sale_form_query_test.rb +96 -0
- data/test/paynet_easy/paynet_easy_api/query/sale_query_test.rb +78 -0
- data/test/paynet_easy/paynet_easy_api/query/status_query_test.rb +81 -0
- data/test/paynet_easy/paynet_easy_api/query/transfer_by_ref_query_test.rb +63 -0
- data/test/paynet_easy/paynet_easy_api/transport/gateway_client_test.rb +22 -0
- data/test/paynet_easy/paynet_easy_api/transport/response_test.rb +26 -0
- data/test/paynet_easy/paynet_easy_api/util/property_accessor_test.rb +52 -0
- data/test/paynet_easy/paynet_easy_api/util/validator_test.rb +42 -0
- metadata +204 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Return transactions
|
|
2
|
+
|
|
3
|
+
Список запросов сценария:
|
|
4
|
+
* [Запрос "return"](#return)
|
|
5
|
+
* [Запрос "status"](#status)
|
|
6
|
+
|
|
7
|
+
## Общие положения
|
|
8
|
+
|
|
9
|
+
* В данной статье описывается исключительно работа с библиотекой. Полная информация о выполнении Return transactions расположена в [статье в wiki PaynetEasy](http://wiki.payneteasy.com/index.php/PnE:Return_Transactions).
|
|
10
|
+
* Описание правил валидации можно найти в описании метода **[Validator::validateByRule()](../library-internals/02-validator.md#validateByRule)**.
|
|
11
|
+
* Описание работы с цепочками свойств можно найти в описании класса **[PropertyAccessor](../library-internals/03-property-accessor.md)**
|
|
12
|
+
|
|
13
|
+
## <a name="return"></a> Запрос "return"
|
|
14
|
+
|
|
15
|
+
Запрос применяется для возврата средств на счет клиента.
|
|
16
|
+
Перед выполнением этого запроса необходимо провести платеж, средства за который будут возвращены.
|
|
17
|
+
После выполнения данного запроса необходимо выполнить серию запросов "**status**" для обновления статуса платежа. Для этого сервис мерчанта может вывести самообновляющуюся страницу, каждая перезагрузка которой будет выполнять запрос "**status**".
|
|
18
|
+
|
|
19
|
+
##### Обязательные параметры запроса
|
|
20
|
+
|
|
21
|
+
Поле запроса |Цепочка свойств платежа|Правило валидации
|
|
22
|
+
----------------|-----------------------|-----------------
|
|
23
|
+
client_orderid |payment.clientId |Validator::ID
|
|
24
|
+
orderid |payment.paynetId |Validator::ID
|
|
25
|
+
amount |payment.amount |Validator::AMOUNT
|
|
26
|
+
currency |payment.currency |Validator::CURRENCY
|
|
27
|
+
comment |payment.comment |Validator::MEDIUM_STRING
|
|
28
|
+
login |queryConfig.login |Validator::MEDIUM_STRING
|
|
29
|
+
|
|
30
|
+
[Пример выполнения запроса return](../../example/return.php)
|
|
31
|
+
|
|
32
|
+
## <a name="status"></a> Запрос "status"
|
|
33
|
+
|
|
34
|
+
Запрос применяется для проверки статуса платежа. Обычно требуется серия таких запросов из-за того, что обработка платежа занимает некоторое время. В зависимости от статуса платежа обработка результата этого запроса может происходить несколькими путями.
|
|
35
|
+
|
|
36
|
+
##### Необходимо обновление платежа
|
|
37
|
+
|
|
38
|
+
В том случае, если статус платежа не изменился (значение поля **status** - **processing**) и нет необходимости в дополнительных шагах авторизации, то запустить проверку статуса еще раз.
|
|
39
|
+
|
|
40
|
+
##### Обработка платежа завершена
|
|
41
|
+
|
|
42
|
+
В ответе на запрос поле **status** содержит результат обработки платежа - **approved**, **filtered**, **declined**, **error**
|
|
43
|
+
|
|
44
|
+
##### Обязательные параметры запроса
|
|
45
|
+
|
|
46
|
+
Поле запроса |Цепочка свойств платежа|Правило валидации
|
|
47
|
+
----------------|-----------------------|-----------------
|
|
48
|
+
client_orderid |payment.clientId |Validator::ID
|
|
49
|
+
orderid |payment.paynetId |Validator::ID
|
|
50
|
+
login |queryConfig.login |Validator::MEDIUM_STRING
|
|
51
|
+
|
|
52
|
+
[Пример выполнения запроса status](../../example/status.php)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Recurrent transactions
|
|
2
|
+
|
|
3
|
+
Список запросов сценария:
|
|
4
|
+
* [Запрос "create-card-ref"](#create-card-ref)
|
|
5
|
+
* [Запрос "get-card-info"](#get-card-info)
|
|
6
|
+
* [Запрос "make-rebill"](#make-rebill)
|
|
7
|
+
* [Запрос "status"](#status)
|
|
8
|
+
|
|
9
|
+
## Общие положения
|
|
10
|
+
|
|
11
|
+
* В данной статье описывается исключительно работа с библиотекой. Полная информация о выполнении Recurrent transactions расположена в [статье в wiki PaynetEasy](http://wiki.payneteasy.com/index.php/PnE:Recurrent_Transactions).
|
|
12
|
+
* Описание правил валидации можно найти в описании метода **[Validator::validateByRule()](../library-internals/02-validator.md#validateByRule)**.
|
|
13
|
+
* Описание работы с цепочками свойств можно найти в описании класса **[PropertyAccessor](../library-internals/03-property-accessor.md)**
|
|
14
|
+
|
|
15
|
+
## <a name="create-card-ref"></a> Запрос "create-card-ref"
|
|
16
|
+
|
|
17
|
+
Запрос применяется для получения id для кредитной карты, сохраненной на стороне PaynetEasy. Этот id позволяет совершать повторные платежи без ввода данных кредитной карты как на стороне сервиса мерчанта так и на стороне PaynetEasy.
|
|
18
|
+
Перед выполнением этого запроса необходимо выполнить один из следующих сценариев для проверки данных, которые ввел клиент:
|
|
19
|
+
* [Sale Transactions](00-sale-transactions.md)
|
|
20
|
+
* [Preauth/Capture Transactions](01-preauth-capture-transactions.md)
|
|
21
|
+
* [Payment Form Integration](05-payment-form-integration.md)
|
|
22
|
+
|
|
23
|
+
##### Обязательные параметры запроса
|
|
24
|
+
|
|
25
|
+
Поле запроса |Цепочка свойств платежа |Правило валидации
|
|
26
|
+
--------------------|-------------------------------|-----------------
|
|
27
|
+
client_orderid |clientId |Validator::ID
|
|
28
|
+
orderid |paynetId |Validator::ID
|
|
29
|
+
login |queryConfig.login |Validator::MEDIUM_STRING
|
|
30
|
+
|
|
31
|
+
[Пример выполнения запроса create-card-ref](../../example/create-card-ref.php)
|
|
32
|
+
|
|
33
|
+
После выполнения данного запроса будет получен id сохраненной кредитной карты и создан объект **[RecurrentCard](../library-internals/00-payment-data.md#RecurrentCard)**. Получить доступ к **RecurrentCard** можно с помощью вызова
|
|
34
|
+
`$payment->getRecurrentCardFrom()`, а к ее id с помощью вызова `$payment->getRecurrentCardFrom()->getCardReferenceId()`
|
|
35
|
+
|
|
36
|
+
## <a name="get-card-info"></a> Запрос "get-card-info"
|
|
37
|
+
|
|
38
|
+
Запрос применяется для получения некоторых данных сохраненной кредитной карты.
|
|
39
|
+
Перед выполнением данного запроса необходимо выполнить запрос [create-card-ref](#create-card-ref).
|
|
40
|
+
|
|
41
|
+
##### Обязательные параметры запроса
|
|
42
|
+
|
|
43
|
+
Поле запроса |Цепочка свойств платежа |Правило валидации
|
|
44
|
+
--------------------|---------------------------|-----------------
|
|
45
|
+
cardrefid |recurrentCardFrom.paynetId |Validator::ID
|
|
46
|
+
login |queryConfig.login |Validator::MEDIUM_STRING
|
|
47
|
+
|
|
48
|
+
[Пример выполнения запроса get-card-info](../../example/get-card-info.php)
|
|
49
|
+
|
|
50
|
+
После выполнения данного запроса будут получены данные сохраненной кредитной карты и создан объект **[RecurrentCard](../library-internals/00-payment-data.md#RecurrentCard)**. Получить доступ к **RecurrentCard** можно с помощью вызова `$payment->getRecurrentCardFrom()`. В объекте будут заполнены следующие данные:
|
|
51
|
+
* **cardPrintedName** - данные доступны с помощью вызова `$payment->getRecurrentCardFrom()->getСardPrintedName()`
|
|
52
|
+
* **expireYear** - данные доступны с помощью вызова `$payment->getRecurrentCardFrom()->getExpireYear()`
|
|
53
|
+
* **expireMonth** - данные доступны с помощью вызова `$payment->getRecurrentCardFrom()->getExpireMonth()`
|
|
54
|
+
* **bin** - данные доступны с помощью вызова `$payment->getRecurrentCardFrom()->getBin()`
|
|
55
|
+
* **lastFourDigits** - данные доступны с помощью вызова `$payment->getRecurrentCardFrom()->getLastFourDigits()`
|
|
56
|
+
|
|
57
|
+
## <a name="make-rebill"></a> Запрос "make-rebill"
|
|
58
|
+
|
|
59
|
+
Запрос применяется для списания средств с кредитной карты клиента.
|
|
60
|
+
Перед выполнением данного запроса необходимо выполнить запрос [create-card-ref](#create-card-ref).
|
|
61
|
+
После выполнения данного запроса необходимо выполнить серию запросов "**status**" для обновления статуса платежа. Для этого сервис мерчанта может вывести самообновляющуюся страницу, каждая перезагрузка которой будет выполнять запрос "**status**".
|
|
62
|
+
|
|
63
|
+
##### Обязательные параметры запроса
|
|
64
|
+
|
|
65
|
+
Поле запроса |Цепочка свойств платежа |Правило валидации
|
|
66
|
+
--------------------|-----------------------------------|-----------------
|
|
67
|
+
client_orderid |payment.clientId |Validator::ID
|
|
68
|
+
order_desc |payment.description |Validator::LONG_STRING
|
|
69
|
+
amount |payment.amount |Validator::AMOUNT
|
|
70
|
+
currency |payment.currency |Validator::CURRENCY
|
|
71
|
+
ipaddress |payment.customer.ipAddress |Validator::IP
|
|
72
|
+
cardrefid |payment.recurrentCardFrom.paynetId |Validator::ID
|
|
73
|
+
login |queryConfig.login |Validator::MEDIUM_STRING
|
|
74
|
+
|
|
75
|
+
##### Необязательные параметры запроса
|
|
76
|
+
|
|
77
|
+
Поле запроса |Цепочка свойств платежа |Правило валидации
|
|
78
|
+
--------------------|-------------------------------|-----------------
|
|
79
|
+
comment |payment.comment |Validator::MEDIUM_STRING
|
|
80
|
+
cvv2 |payment.recurrentCardFrom.cvv2 |Validator::CVV2
|
|
81
|
+
server_callback_url |queryConfig.callbackUrl |Validator::URL
|
|
82
|
+
|
|
83
|
+
[Пример выполнения запроса make-rebill](../../example/make-rebill.php)
|
|
84
|
+
|
|
85
|
+
## <a name="status"></a> Запрос "status"
|
|
86
|
+
|
|
87
|
+
Запрос применяется для проверки статуса платежа. Обычно требуется серия таких запросов из-за того, что обработка платежа занимает некоторое время. В зависимости от статуса платежа обработка результата этого запроса может происходить несколькими путями.
|
|
88
|
+
|
|
89
|
+
##### Необходимо обновление платежа
|
|
90
|
+
|
|
91
|
+
В том случае, если статус платежа не изменился (значение поля **status** - **processing**) и нет необходимости в дополнительных шагах авторизации, то запустить проверку статуса еще раз.
|
|
92
|
+
|
|
93
|
+
##### Обработка платежа завершена
|
|
94
|
+
|
|
95
|
+
В ответе на запрос поле **status** содержит результат обработки платежа - **approved**, **filtered**, **declined**, **error**
|
|
96
|
+
|
|
97
|
+
##### Обязательные параметры запроса
|
|
98
|
+
|
|
99
|
+
Поле запроса |Цепочка свойств платежа|Правило валидации
|
|
100
|
+
--------------------|-----------------------|-----------------
|
|
101
|
+
client_orderid |payment.clientId |Validator::ID
|
|
102
|
+
orderid |payment.paynetId |Validator::ID
|
|
103
|
+
login |queryConfig.login |Validator::MEDIUM_STRING
|
|
104
|
+
|
|
105
|
+
[Пример выполнения запроса status](../../example/status.php)
|
|
106
|
+
|
|
107
|
+
## <a name="callback"></a> Обработка обратного вызова
|
|
108
|
+
|
|
109
|
+
После завершения обработки платежа на стороне PaynetEasy, данные с результатом обработки передаются в сервис мерчанта с помощью обратного вызова. Это необходимо, чтобы платеж был обработан сервисом мерчанта независимо от того, выполнил пользователь корректно возврат с шлюза PaynetEasy или нет.
|
|
110
|
+
[Подробнее о Merchant callbacks](06-merchant-callbacks.md)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Payment form integration
|
|
2
|
+
|
|
3
|
+
## Общие положения
|
|
4
|
+
|
|
5
|
+
* В данной статье описывается исключительно работа с библиотекой. Полная информация о выполнении Payment form integration расположена в [статье в wiki PaynetEasy](http://wiki.payneteasy.com/index.php/PnE:Payment_Form_integration).
|
|
6
|
+
* Описание правил валидации можно найти в описании метода **[Validator::validateByRule()](../library-internals/02-validator.md#validateByRule)**.
|
|
7
|
+
* Описание работы с цепочками свойств можно найти в описании класса **[PropertyAccessor](../library-internals/03-property-accessor.md)**
|
|
8
|
+
|
|
9
|
+
## <a name="form"></a> Запросы "sale-form", "preauth-form", "transfer-form"
|
|
10
|
+
|
|
11
|
+
* **sale-form** - применяется для оплаты с помощью кредитной карты
|
|
12
|
+
* **preauth-form** - применяется для блокирования части средств кредитной карты клиента. После успешного завершения этого запроса для списания средств с карты клиента необходимо выполнить запрос **[capture](01-preauth-capture-transactions.md#capture)**
|
|
13
|
+
* **transfer-form** - применяется для перевода средств с одного счета на другой
|
|
14
|
+
|
|
15
|
+
При выполнении запросов информация о карте вводится на стороне PaynetEasy.
|
|
16
|
+
|
|
17
|
+
##### Обязательные параметры запроса
|
|
18
|
+
|
|
19
|
+
Поле запроса |Цепочка свойств платежа |Правило валидации
|
|
20
|
+
--------------------|-----------------------------------|-----------------
|
|
21
|
+
client_orderid |payment.clientId |Validator::ID
|
|
22
|
+
order_desc |payment.description |Validator::LONG_STRING
|
|
23
|
+
amount |payment.amount |Validator::AMOUNT
|
|
24
|
+
currency |payment.currency |Validator::CURRENCY
|
|
25
|
+
address1 |payment.billingAddress.firstLine |Validator::MEDIUM_STRING
|
|
26
|
+
city |payment.billingAddress.city |Validator::MEDIUM_STRING
|
|
27
|
+
zip_code |payment.billingAddress.zipCode |Validator::ZIP_CODE
|
|
28
|
+
country |payment.billingAddress.country |Validator::COUNTRY
|
|
29
|
+
phone |payment.billingAddress.phone |Validator::PHONE
|
|
30
|
+
ipaddress |payment.customer.ipAddress |Validator::IP
|
|
31
|
+
email |payment.customer.email |Validator::EMAIL
|
|
32
|
+
redirect_url |queryConfig.redirectUrl |Validator::URL
|
|
33
|
+
|
|
34
|
+
##### Необязательные параметры запроса
|
|
35
|
+
|
|
36
|
+
Поле запроса |Цепочка свойств платежа |Правило валидации
|
|
37
|
+
--------------------|-----------------------------------|-----------------
|
|
38
|
+
first_name |payment.customer.firstName |Validator::MEDIUM_STRING
|
|
39
|
+
last_name |payment.customer.lastName |Validator::MEDIUM_STRING
|
|
40
|
+
ssn |payment.customer.ssn |Validator::SSN
|
|
41
|
+
birthday |payment.customer.birthday |Validator::DATE
|
|
42
|
+
state |payment.billingAddress.state |Validator::COUNTRY
|
|
43
|
+
cell_phone |payment.billingAddress.cellPhone |Validator::PHONE
|
|
44
|
+
site_url |queryConfig.siteUrl |Validator::URL
|
|
45
|
+
server_callback_url |queryConfig.callbackUrl |Validator::URL
|
|
46
|
+
|
|
47
|
+
[Пример выполнения запроса sale-form](../../example/sale-form.php)
|
|
48
|
+
[Пример выполнения запроса preauth-form](../../example/preauth-form.php)
|
|
49
|
+
[Пример выполнения запроса transfer-form](../../example/transfer-form.php)
|
|
50
|
+
|
|
51
|
+
## <a name="form-redirect"> Обработка результата платежа после возвращения клиента с платежной формы
|
|
52
|
+
|
|
53
|
+
При возвращении пользователя с платежной формы на сервис мерчанта будут переданы данные с результатом обработки платежа. Обработка этих данных описана в [базовом примере использования библиотеки](../00-basic-tutorial.md#stage_2).
|
|
54
|
+
|
|
55
|
+
## <a name="callback"></a> Обработка обратного вызова
|
|
56
|
+
|
|
57
|
+
После завершения обработки платежа на стороне PaynetEasy, данные с результатом обработки передаются в сервис мерчанта с помощью обратного вызова. Это необходимо, чтобы платеж был обработан сервисом мерчанта независимо от того, выполнил пользователь корректно возврат с шлюза PaynetEasy или нет. Обработка этих данных совпадает с обработкой данных для [sale-form, preauth-form или transfer-form](05-payment-form-integration.md) и описана в [базовом примере использования библиотеки](../00-basic-tutorial.md#stage_2).
|
|
58
|
+
|
|
59
|
+
[Подробнее о Merchant callbacks](06-merchant-callbacks.md)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Merchant callbacks
|
|
2
|
+
|
|
3
|
+
## Общие положения
|
|
4
|
+
|
|
5
|
+
* В данной статье описывается исключительно работа с библиотекой. Полная информация о Merchant callbacks расположена в [статье в wiki PaynetEasy](http://wiki.payneteasy.com/index.php/PnE:Merchant_Callbacks).
|
|
6
|
+
* Описание работы с цепочками свойств можно найти в описании класса **[PropertyAccessor](../library-internals/03-property-accessor.md)**
|
|
7
|
+
|
|
8
|
+
## <a name="main-callbacks"></a> Sale, Return, Chargeback callbacks
|
|
9
|
+
|
|
10
|
+
После завершения обработки платежа на стороне PaynetEasy, данные с результатом обработки передаются в сервис мерчанта с помощью обратного вызова. Это необходимо, чтобы платеж был обработан сервисом мерчанта независимо от того, выполнил пользователь корректно возврат с шлюза PaynetEasy или нет. Обработка этих данных совпадает с обработкой данных для [sale-form, preauth-form или transfer-form](05-payment-form-integration.md) и описана в [базовом примере использования библиотеки](../00-basic-tutorial.md#stage_2).
|
|
11
|
+
При обработке платежа библиотека сначала проверяет наличие необходимых полей в данных обратного вызова, а потом сравнивает значения некоторых полей в платеже и данных обратного вызова. После проверки в платеже обновляется поле **status**.
|
|
12
|
+
|
|
13
|
+
##### Обязательные параметры данных обратного вызова
|
|
14
|
+
|
|
15
|
+
Поле запроса |Цепочка свойств платежа для проверки
|
|
16
|
+
--------------------|---------------------------------------
|
|
17
|
+
orderid |payment.paynetId
|
|
18
|
+
merchant_order |payment.clientId
|
|
19
|
+
client_orderid |payment.clientId
|
|
20
|
+
amount |payment.amount
|
|
21
|
+
status |
|
|
22
|
+
type |
|
|
23
|
+
control |
|
|
24
|
+
|
|
25
|
+
[Пример выполнения запроса sale](../../example/sale.php#L102)
|
|
26
|
+
[Пример выполнения запроса preauth](../../example/preauth.php#L102)
|
|
27
|
+
[Пример выполнения запроса sale-form](../../example/sale-form.php#L81)
|
|
28
|
+
[Пример выполнения запроса preauth-form](../../example/preauth-form.php#81)
|
|
29
|
+
[Пример выполнения запроса transfer-form](../../example/transfer-form.php#81)
|
data/example/capture.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'paynet_easy_api'
|
|
2
|
+
require_relative './common/functions'
|
|
3
|
+
|
|
4
|
+
payment_transaction = PaymentTransaction.new(
|
|
5
|
+
{
|
|
6
|
+
'payment' => Payment.new(
|
|
7
|
+
{
|
|
8
|
+
'client_id' => 'CLIENT-112244',
|
|
9
|
+
'paynet_id' => 1969596,
|
|
10
|
+
}),
|
|
11
|
+
'query_config' => query_config
|
|
12
|
+
})
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'paynet_easy_api'
|
|
2
|
+
|
|
3
|
+
query_config = -> () do
|
|
4
|
+
QueryConfig.new(
|
|
5
|
+
{
|
|
6
|
+
# Точка входа для аккаунта мерчанта, выдается при подключении
|
|
7
|
+
'end_point' => 253,
|
|
8
|
+
# Логин мерчанта, выдается при подключении
|
|
9
|
+
'login' => 'rp-merchant1',
|
|
10
|
+
# Ключ мерчанта для подписывания запросов, выдается при подключении
|
|
11
|
+
'signing_key' => '3FD4E71A-D84E-411D-A613-40A0FB9DED3A',
|
|
12
|
+
# URL на который пользователь будет перенаправлен после окончания запроса
|
|
13
|
+
'redirect_url' => "http://{$_SERVER['HTTP_HOST']}/{$_SERVER['REQUEST_URI']}?stage=processCustomerReturn",
|
|
14
|
+
# URL на который пользователь будет перенаправлен после окончания запроса
|
|
15
|
+
'callback_url' => "http://{$_SERVER['HTTP_HOST']}/{$_SERVER['REQUEST_URI']}?stage=processPaynetEasyCallback",
|
|
16
|
+
# Режим работы библиотеки: sandbox, production
|
|
17
|
+
'gateway_mode' => QueryConfig::GATEWAY_MODE_SANDBOX,
|
|
18
|
+
# Ссылка на шлюз PaynetEasy для режима работы sandbox
|
|
19
|
+
'gateway_url_sandbox' => 'https://sandbox.domain.com/paynet/api/v2/',
|
|
20
|
+
# Ссылка на шлюз PaynetEasy для режима работы production
|
|
21
|
+
'gateway_url_production' => 'https://payment.domain.com/paynet/api/v2/'
|
|
22
|
+
})
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
load_payment_transaction = ->() do
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
save_payment_transaction = ->() do
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
display_wait_page = ->() do
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
display_response_html = ->(response) do
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
redirect_to_response_url = ->() do
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
display_ended_payment = ->() do
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
display_exception = ->() do
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
payment_processor = ->() do
|
|
47
|
+
PaymentProcessor.new(
|
|
48
|
+
{
|
|
49
|
+
PaymentProcessor::HANDLER_CATCH_EXCEPTION => display_exception,
|
|
50
|
+
PaymentProcessor::HANDLER_SAVE_CHANGES => save_payment_transaction,
|
|
51
|
+
PaymentProcessor::HANDLER_STATUS_UPDATE => display_wait_page,
|
|
52
|
+
PaymentProcessor::HANDLER_REDIRECT => redirect_to_response_url,
|
|
53
|
+
PaymentProcessor::HANDLER_SHOW_HTML => display_response_html,
|
|
54
|
+
PaymentProcessor::HANDLER_FINISH_PROCESSING => display_ended_payment
|
|
55
|
+
})
|
|
56
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'util/string'
|
|
2
|
+
require 'callback/callback_prototype'
|
|
3
|
+
|
|
4
|
+
module PaynetEasy::PaynetEasyApi::Callback
|
|
5
|
+
class CallbackFactory
|
|
6
|
+
@@allowed_payneteasy_callback_types =
|
|
7
|
+
[
|
|
8
|
+
'sale',
|
|
9
|
+
'revers al',
|
|
10
|
+
'chargeback'
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
# Get callback processor by callback type
|
|
14
|
+
#
|
|
15
|
+
# @param callback_type [String] Callback type
|
|
16
|
+
#
|
|
17
|
+
# @return [CallbackPrototype] Callback processor
|
|
18
|
+
def callback(callback_type)
|
|
19
|
+
callback_class = "#{callback_type.camelize}Callback"
|
|
20
|
+
callback_file = "callback/#{callback_type}_callback"
|
|
21
|
+
|
|
22
|
+
begin
|
|
23
|
+
instantiate_callback callback_file, callback_class, callback_type
|
|
24
|
+
rescue LoadError => error
|
|
25
|
+
if @@allowed_payneteasy_callback_types.include? callback_type
|
|
26
|
+
instantiate_callback 'callback/paynet_easy_callback', 'PaynetEasyCallback', callback_type
|
|
27
|
+
else
|
|
28
|
+
raise error
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
protected
|
|
34
|
+
|
|
35
|
+
# Load callback class file and return new callback object
|
|
36
|
+
#
|
|
37
|
+
# @param callback_file [String] Callback class file
|
|
38
|
+
# @param callback_class [String] Callback class
|
|
39
|
+
# @param callback_type [String] Callback type
|
|
40
|
+
#
|
|
41
|
+
# @return [CallbackPrototype] Callback object
|
|
42
|
+
def instantiate_callback(callback_file, callback_class, callback_type)
|
|
43
|
+
require callback_file
|
|
44
|
+
PaynetEasy::PaynetEasyApi::Callback.const_get(callback_class).new(callback_type)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
require 'digest/sha1'
|
|
2
|
+
require 'payment_data/payment_transaction'
|
|
3
|
+
require 'transport/callback_response'
|
|
4
|
+
require 'error/validation_error'
|
|
5
|
+
require 'util/property_accessor'
|
|
6
|
+
|
|
7
|
+
module PaynetEasy::PaynetEasyApi::Callback
|
|
8
|
+
class CallbackPrototype
|
|
9
|
+
include PaynetEasy::PaynetEasyApi::PaymentData
|
|
10
|
+
include PaynetEasy::PaynetEasyApi::Transport
|
|
11
|
+
include PaynetEasy::PaynetEasyApi::Error
|
|
12
|
+
include PaynetEasy::PaynetEasyApi::Util
|
|
13
|
+
|
|
14
|
+
# Allowed callback statuses
|
|
15
|
+
@allowed_statuses =
|
|
16
|
+
[
|
|
17
|
+
PaymentTransaction::STATUS_APPROVED,
|
|
18
|
+
PaymentTransaction::STATUS_DECLINED,
|
|
19
|
+
PaymentTransaction::STATUS_FILTERED,
|
|
20
|
+
PaymentTransaction::STATUS_ERROR
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
# Callback fields definition if format:
|
|
24
|
+
# [
|
|
25
|
+
# [<first callback field name>:string, <first payment transaction property path>:string]
|
|
26
|
+
# [<second callback field name>:string, <second payment transaction property path>:string]
|
|
27
|
+
# ...
|
|
28
|
+
# [<last callback field name>:string, <last payment transaction property path>:string]
|
|
29
|
+
# ]
|
|
30
|
+
#
|
|
31
|
+
# If property name present in field definition,
|
|
32
|
+
# callback response field value and payment transaction property value will be compared.
|
|
33
|
+
# If values not equal validation exception will be raised.
|
|
34
|
+
@callback_fields_definition =
|
|
35
|
+
[
|
|
36
|
+
['orderid', 'payment.paynet_id'],
|
|
37
|
+
['merchant_order', 'payment.client_id'],
|
|
38
|
+
['client_orderid', 'payment.client_id'],
|
|
39
|
+
['amount', 'payment.amount'],
|
|
40
|
+
['status', nil],
|
|
41
|
+
['type', nil],
|
|
42
|
+
['control', nil]
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
def initialize(callback_type)
|
|
46
|
+
@callback_type = callback_type
|
|
47
|
+
validate_callback_definition
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Process API gateway Response and update Payment transaction
|
|
51
|
+
#
|
|
52
|
+
# @param payment_transaction [PaymentTransaction] Payment transaction for update
|
|
53
|
+
# @param callback_response [CallbackResponse] PaynetEasy callback
|
|
54
|
+
#
|
|
55
|
+
# @return [CallbackResponse] PaynetEasy callback
|
|
56
|
+
def process_callback(payment_transaction, callback_response)
|
|
57
|
+
begin
|
|
58
|
+
validate_callback payment_transaction, callback_response
|
|
59
|
+
rescue Exception => error
|
|
60
|
+
payment_transaction.add_error error
|
|
61
|
+
payment_transaction.status = PaymentTransaction::STATUS_ERROR
|
|
62
|
+
|
|
63
|
+
raise error
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
update_payment_transaction payment_transaction, callback_response
|
|
67
|
+
|
|
68
|
+
if callback_response.error?
|
|
69
|
+
raise callback_response.error
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
callback_response
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
protected
|
|
76
|
+
|
|
77
|
+
# Validates callback
|
|
78
|
+
#
|
|
79
|
+
# @param payment_transaction [PaymentTransaction] Payment transaction
|
|
80
|
+
# @param callback_response [CallbackResponse] Callback from PaynetEasy
|
|
81
|
+
def validate_callback(payment_transaction, callback_response)
|
|
82
|
+
validate_query_config payment_transaction
|
|
83
|
+
validate_signature payment_transaction, callback_response
|
|
84
|
+
|
|
85
|
+
unless allowed_statuses.include? callback_response.status
|
|
86
|
+
raise ValidationError, "Invalid callback status: '#{callback_response.status}'"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
error_message = ''
|
|
90
|
+
missed_fields = []
|
|
91
|
+
unequal_fields = []
|
|
92
|
+
|
|
93
|
+
callback_fields_definition.each do |field_name, property_path|
|
|
94
|
+
if callback_response.fetch(field_name, nil).nil?
|
|
95
|
+
missed_fields << field_name
|
|
96
|
+
elsif property_path
|
|
97
|
+
property_value = PropertyAccessor.get_value payment_transaction, property_path, false
|
|
98
|
+
callback_value = callback_response.fetch field_name
|
|
99
|
+
|
|
100
|
+
if property_value.to_s != callback_value.to_s
|
|
101
|
+
unequal_fields << "CallbackResponse field '#{field_name}' value '#{callback_value}' does not " +
|
|
102
|
+
"equal PaymentTransaction property '#{property_path}' value '#{property_value}'."
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
unless missed_fields.empty?
|
|
108
|
+
error_message << "Some required fields missed or empty in CallbackResponse: \n#{missed_fields.join(', ')}. \n"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
unless unequal_fields.empty?
|
|
112
|
+
error_message << "Some fields from CallbackResponse unequal properties " +
|
|
113
|
+
"from PaymentTransaction: \n#{unequal_fields.join(" \n")}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
unless error_message.empty?
|
|
117
|
+
raise ValidationError, error_message
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Validates payment transaction query config
|
|
122
|
+
#
|
|
123
|
+
# @param payment_transaction [PaymentTransaction] Payment transaction
|
|
124
|
+
def validate_query_config(payment_transaction)
|
|
125
|
+
unless payment_transaction.query_config.signing_key
|
|
126
|
+
raise ValidationError, "Property 'signing_key' does not defined in PaymentTransaction property 'query_config'"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Validate callback response control code
|
|
131
|
+
#
|
|
132
|
+
# @param payment_transaction [PaymentTransaction] Payment transaction for control code checking
|
|
133
|
+
# @param callback_response [CallbackResponse] Callback for control code checking
|
|
134
|
+
def validate_signature(payment_transaction, callback_response)
|
|
135
|
+
expected_control_code = Digest::SHA1.hexdigest(
|
|
136
|
+
callback_response.status +
|
|
137
|
+
callback_response.payment_paynet_id.to_s +
|
|
138
|
+
callback_response.payment_client_id.to_s +
|
|
139
|
+
payment_transaction.query_config.signing_key
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
if expected_control_code != callback_response.control_code
|
|
143
|
+
raise ValidationError, "Actual control code '#{callback_response.control_code}' does " +
|
|
144
|
+
"not equal expected '#{expected_control_code}'"
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Updates Payment transaction by Callback data
|
|
149
|
+
#
|
|
150
|
+
# @param payment_transaction [PaymentTransaction] Payment transaction for updating
|
|
151
|
+
# @param callback_response [CallbackResponse] Callback for payment transaction updating
|
|
152
|
+
def update_payment_transaction(payment_transaction, callback_response)
|
|
153
|
+
payment_transaction.status = callback_response.status
|
|
154
|
+
payment_transaction.payment.paynet_id = callback_response.payment_paynet_id
|
|
155
|
+
|
|
156
|
+
if callback_response.error? || callback_response.declined?
|
|
157
|
+
payment_transaction.add_error callback_response.error
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Validates callback object definition
|
|
162
|
+
def validate_callback_definition
|
|
163
|
+
raise RuntimeError, 'You must configure @allowed_statuses' if allowed_statuses.empty?
|
|
164
|
+
raise RuntimeError, 'You must configure @callback_fields_definition' if callback_fields_definition.empty?
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
class << self
|
|
168
|
+
# Make instance variables available in child classes
|
|
169
|
+
def inherited(subclass)
|
|
170
|
+
instance_variables.each do |variable_name|
|
|
171
|
+
subclass.instance_variable_set variable_name, instance_variable_get(variable_name)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# @return [Array]
|
|
177
|
+
def allowed_statuses
|
|
178
|
+
self.class.instance_variable_get :@allowed_statuses
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# @return [Array]
|
|
182
|
+
def callback_fields_definition
|
|
183
|
+
self.class.instance_variable_get :@callback_fields_definition
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'callback/callback_prototype'
|
|
2
|
+
|
|
3
|
+
module PaynetEasy::PaynetEasyApi::Callback
|
|
4
|
+
class CustomerReturnCallback < CallbackPrototype
|
|
5
|
+
@callback_fields_definition =
|
|
6
|
+
[
|
|
7
|
+
['orderid', 'payment.paynet_id'],
|
|
8
|
+
['merchant_order', 'payment.client_id'],
|
|
9
|
+
['client_orderid', 'payment.client_id'],
|
|
10
|
+
['status', nil],
|
|
11
|
+
['control', nil]
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
|
|
16
|
+
# Validates callback
|
|
17
|
+
#
|
|
18
|
+
# @param payment_transaction [PaymentTransaction] Payment transaction
|
|
19
|
+
# @param callback_response [CallbackResponse] Callback from PaynetEasy
|
|
20
|
+
def validate_callback(payment_transaction, callback_response)
|
|
21
|
+
unless payment_transaction.processing?
|
|
22
|
+
raise ValidationError, 'Only processing payment transaction can be processed'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
super payment_transaction, callback_response
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'callback/callback_prototype'
|
|
2
|
+
require 'payment_data/payment_transaction'
|
|
3
|
+
|
|
4
|
+
module PaynetEasy::PaynetEasyApi::Callback
|
|
5
|
+
class PaynetEasyCallback < CallbackPrototype
|
|
6
|
+
include PaynetEasy::PaynetEasyApi::PaymentData
|
|
7
|
+
|
|
8
|
+
@callback_fields_definition =
|
|
9
|
+
[
|
|
10
|
+
['orderid', 'payment.paynet_id'],
|
|
11
|
+
['merchant_order', 'payment.client_id'],
|
|
12
|
+
['client_orderid', 'payment.client_id'],
|
|
13
|
+
['amount', 'payment.amount'],
|
|
14
|
+
['status', nil],
|
|
15
|
+
['type', nil],
|
|
16
|
+
['control', nil]
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
# @param payment_transaction [PaymentTransaction] Payment transaction for update
|
|
20
|
+
# @param callback_response [CallbackResponse] PaynetEasy callback
|
|
21
|
+
#
|
|
22
|
+
# @return [CallbackResponse] PaynetEasy callback
|
|
23
|
+
def process_callback(payment_transaction, callback_response)
|
|
24
|
+
payment_transaction.processor_type = PaymentTransaction::PROCESSOR_CALLBACK
|
|
25
|
+
payment_transaction.processor_name = @callback_type
|
|
26
|
+
|
|
27
|
+
super payment_transaction, callback_response
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
protected
|
|
31
|
+
|
|
32
|
+
# Validates callback
|
|
33
|
+
#
|
|
34
|
+
# @param payment_transaction [PaymentTransaction] Payment transaction
|
|
35
|
+
# @param callback_response [CallbackResponse] Callback from PaynetEasy
|
|
36
|
+
def validate_callback(payment_transaction, callback_response)
|
|
37
|
+
unless payment_transaction.new?
|
|
38
|
+
raise ValidationError, 'Only new payment transaction can be processed'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
super payment_transaction, callback_response
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|