Организация взаимодействия

Gate представляет собой программный интерфейс (API) для приёма запросов от веб-сервиса к платёжной платформе ECommPay. Gate отвечает принципам REST API, а также поддерживает обратную совместимость, благодаря которой выпуск каждой новой версии интерфейса не требует изменений программного кода на стороне веб-сервиса.

Gate доступен по адресу https://api.ecommpay.com и обеспечивает приём запросов в заданных конечных точках с использованием протоколов HTTP версии не ниже 1.1 и TLS версии не ниже 1.2. Спецификация интерфейса доступна по адресу https://api-developers.ecommpay.com.

В этом разделе представлена информация о порядке и технических аспектах интеграции через Gate.

Порядок интеграции

Для интеграции с платёжной платформой ECommPay через Gate необходимо:

  1. Решить организационные вопросы, касающиеся взаимодействия с ECommPay:

    1. Если у компании нет идентификатора проекта и секретного ключа для взаимодействия с ECommPay — отправить заявку на подключение по ссылке https://ecommpay.com/ru/apply-now/.
    2. Для проведения платежей с использованием платёжных карт — предоставить курирующему менеджеру ECommPay документ о соответствии требованиям PCI DSS. Это может быть копия сертификата соответствия (при его наличии) или лист самооценки. С вопросами о заполнении листа самооценки можно обращаться к курирующему менеджеру ECommPay.

    3. Согласовать со специалистами технической поддержки ECommPay порядок и сроки интеграции, тестирования и запуска в работу. В рамках согласования порядка тестирования могут быть согласованы возможности проведения тестовых платежей с использованием платёжных карт, а также некоторых из альтернативных методов.
  2. Доработать программный код веб-сервиса для интеграции с платёжной платформой через Gate.
  3. Протестировать и совместно со специалистами технической поддержки ECommPay запустить в работу обновлённый программный код веб-сервиса.

    После тестирования и мониторинга, когда проведение платежей на рабочем трафике корректно, специалисты технической поддержки переводят работу с веб-сервисом в режим штатной поддержки.

При возникновении вопросов о работе с Gate следует обращаться в службу технической поддержки ECommPay support@ecommpay.com.

Схемы взаимодействия

При использовании Gate взаимодействие между веб-сервисом и платёжной платформой ECommPay строится на обмене HTTP-сообщениями по принципу «запрос-ответ» — с отправкой запросов от веб-сервиса и ответов от платформы. При этом предусмотрены две схемы взаимодействия: синхронная для тех запросов, которые могут быть выполнены автономно на стороне платформы, и асинхронная для тех запросов, выполнение которых зависит не только от работы платформы, но и от действий других сторон (например, пользователя или платёжной системы).

Синхронная схема

Синхронная схема взаимодействия используется, когда запрос можно полностью выполнить на стороне платёжной платформы: например, чтобы получить статус платежа в платформе. Такое взаимодействие осуществляется в рамках одного HTTP-сеанса и подразумевает отправку одного ответа на полученный запрос. Это может быть ответ с запрошенной информацией или с информацией об ошибке. Время от получения запроса до отправки ответа, как правило, составляет не более 100 мс.

Асинхронная схема

Асинхронная схема взаимодействия используется, когда выполнение запроса требует участия других сторон помимо веб-сервиса и платёжной платформы: например, чтобы провести оплату с участием пользователя и платёжной системы.

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

Время от получения запроса до отправки начального ответа, как правило, составляет не более 100 мс. Время от приёма запроса до отправки оповещений может варьироваться, поскольку зависит от других сторон, задействованных в выполнении запроса.

Для организации взаимодействия с платёжной платформой по асинхронной схеме на стороне веб-сервиса необходимо обеспечить корректное реагирование на оповещения. Для промежуточных оповещений способы реагирования зависят от переданных сведений, а для итогового оповещения необходимо отправить ответ о его приёме:

  • Если оповещение обработано успешно, необходимо указать код ответа 200 OK, при этом тело ответа может быть пустым.
  • Если при обработке оповещения выявлена ошибка, рекомендуется указать код ответа, соответствующий этой ошибке, из числа доступных в спецификации HTTP.

Оповещения отправляются повторно до получения ответа от веб-сервиса с кодом 200 OK.

Рис.: Ответ на оповещение

HTTP/1.1 200 OK
Date: Fri, 07 Jun 2019 11:38:32 GMT
Content-Type: text/plain;charset=UTF-8
Content-Length: 2
Connection: keep-alive
                    
OK

Порядок работы с запросами

Взаимодействие в рамках любой из схем начинается с отправки запроса к платёжной платформе. При получении запроса в платформе выполняются следующие действия:

  • На этапе приёма запроса обеспечивается синтаксический анализ JSON-строки и проверяется наличие минимального набора параметров.
    • Если из JSON-строки удалось извлечь данные и в этих данных указан минимальный набор параметров, то запрос переводится на этап обработки. В рамках асинхронного взаимодействия в таком случае отправляется ответ о приёме запроса в обработку.
    • Если на этом этапе обнаружены ошибки, то работа с запросом прекращается. В таком случае в рамках любой схемы взаимодействия отправляется ответ с информацией об ошибке.
  • На этапе обработки запроса обеспечивается проверка набора данных на соответствие спецификации Gate, а также проверка семантической согласованности данных и корректности подписи.
    • Если в наборе данных не обнаружены ошибки, то запрос переводится на этап выполнения. Ответ при этом не отправляется. Для запросов на инициирование платежа в платформе регистрируется платёж: создаётся объект payment.
    • Если в наборе данных обнаружены ошибки, то работа с запросом прекращается. В рамках синхронного взаимодействия отправляется ответ с информацией об ошибке, в рамках асинхронного — оповещение.
  • На этапе выполнения запроса обеспечивается выполнение всех необходимых действий для получения и отправки результата, например, сбор запрашиваемой информации в платформе или проведение платежа.
    • Если запрос выполнен, то в рамках синхронного взаимодействия отправляется ответ с запрошенной информацией, а в рамках асинхронного — итоговое оповещение.
    • Если в рамках выполнения запроса возникли ошибки, то работа с запросом прекращается и в рамках синхронного взаимодействия отправляется ответ с информацией об ошибке, а в рамках асинхронного — оповещение.

Как правило, ответ на полученный запрос в любом из описанных случаев отправляется к веб-сервису в течение 100 мс. Если ответ не получен, можно повторить отправку запроса с тем же набором данных (при проведении платежа — с тем же идентификатором платежа). Если в ответе указаны сведения об ошибке, допущенной на стороне веб-сервиса, следует устранить эту ошибку и повторить отправку запроса с учётом правок.

Формат запроса

В рамках взаимодействия с платёжной платформой через Gate все данные от веб-сервиса должны передаваться в запросах — HTTP-сообщениях заданной структуры — с использованием метода POST. Описание общей структуры запросов представлено далее, а описание структур данных для различных случаев — в спецификации интерфейса.

Структура

В каждом запросе к платёжной платформе должны передаваться следующие элементы в указанном порядке:

  • стартовая строка с указанием метода передачи запроса (POST) и конечной точки в интерфейсе Gate (например, /v2/payment/status), протокола и его версии (HTTP/1.1);
  • заголовок с полем Host, содержащим доменное имя для запросов через Gate (api.ecommpay.com);
  • пустая строка — разделитель, отделяющая служебную информацию от тела сообщения;
  • тело сообщения, содержащее JSON-строку в кодировке UTF-8 с набором данных и подписью к ним.

В дополнение к обязательному полю Host в заголовке можно использовать любые другие поля из числа допустимых в HTTP версии 1.1. Далее представлен пример запроса с рекомендуемым набором полей заголовка. Содержимое JSON-строки в этом примере разбито на несколько строк для удобства чтения.

Рис.: Запрос на получение статуса платежа в платформе

POST /v2/payment/status HTTP/1.1
User-Agent: curl/7.29.0
Host: api.ecommpay.com
Accept: */*
Content-Length: 179
Content-Type: application/x-www-form-urlencoded
                    
{
    "general": {
    "project_id": 1,
    "payment_id": "ID_184",
    "signature": "PJkV8ej\/UG0Di8hTng6JvC7vQsaC6tY3T\/pOMeSaRfBa...=="
    }
}                

Параметры адресации

При формировании запросов необходимо указывать базовый и относительный адреса отправки. В качестве базового адреса для запросов через Gate используется доменное имя api.ecommpay.com, а в качестве относительного — указатель конечной точки в интерфейсе Gate в соответствии со спецификацией.

Прим.: Полный адрес в этом случае представляет собой строку вида https://{доменное имя платформы для запросов через Gate}/{указатель конечной точки}. Например, адрес для запроса на получение статуса платежа выглядит как https://api.ecommpay.com/v2/payment/status, но в таком виде при работе с POST-запросами полные адреса не используются.

Тело

В теле сообщения должна содержаться JSON-строка с набором данных в формате "<название параметра>": <значение параметра>. Чтобы предотвратить утечку и подмену данных во время их передачи в платёжную платформу, в составе JSON-строки используется подпись, а на транспортном уровне передачи — протокол TLS 1.2, обеспечивающий шифрование. Подробная информация о формировании подписи представлена в разделе Работа с подписью к данным.

Далее представлен пример JSON-строки c набором данных, обязательных для получения статуса платежа. Сумму и валюту платежа для данного запроса указывать не требуется.

Рис.: Набор данных в объекте JSON

{
"general": {
    "project_id": 2990,    
    "payment_id": payment_id,
    "signature": "PJkV8ej\/UG0Di8hTng6JvC7vQsaC6tajQVVfBaNIipTv+AWoXW\/9MTO8yJA=="
    }
}

Формат ответа

Со стороны платёжной платформы получение запроса подтверждается отправкой ответа — HTTP-сообщения заданной структуры — в рамках того же сеанса. В зависимости от результата обработки запроса и схемы взаимодействия между веб-сервисом и платформой передаваемые в ответе данные включают в себя:

  • запрошенную информацию, если запрос выполнен в рамках синхронной схемы;
  • сведения о приёме запроса, если запрос принят в обработку в рамках асинхронной схемы;
  • расширенное описание ошибки, если запрос не может быть выполнен в рамках синхронной схемы или не может быть принят в обработку в рамках асинхронной.

Далее представлена информация о структуре ответов, а также о кодах и статусах, используемых для передачи информации о состоянии запроса; информация о полном перечне кодов платёжной платформы, используемых в расширенном описании ошибок представлена в разделе Информация о выполнении операций.

Структура

В каждом ответе от платформы содержатся следующие элементы в порядке перечисления:

  • стартовая строка с указанием протокола и его версии (HTTP/1.1), кода ответа и поясняющей фразы к коду (например, 200 OK);
  • поля заголовка;
  • пустая строка — разделитель, отделяющая служебную информацию от тела сообщения;
  • тело сообщения, содержащее JSON-строку в кодировке UTF-8 в с набором данных.

Коды ответа

HTTP-код ответа используется в стартовой строке любого ответа для передачи информации о результате приёма или выполнения запроса либо о причине обнаруженной ошибки. Перечень кодов ответов и пояснительных фраз, используемых в ответах платформы, приведён далее в таблице.

Код с пояснением Описание
200 OK

В рамках синхронной схемы взаимодействия: Запрос успешно выполнен. В теле ответа передана запрошенная информация

В рамках асинхронной схемы взаимодействия: Запрос успешно принят. Можно ожидать промежуточные или итоговое оповещения

400 Bad Request Запрос не может быть принят из-за отсутствия в наборе данных, извлечённых из JSON-строки, обязательного параметра, например, идентификатора проекта
403 Forbidden Запрос не может быть принят из-за отказа в доступе к указанной конечной точке, например, если запрос отправлен с IP-адреса, который не добавлен в список разрешённых
422 Unprocessable Entity Запрос не может быть принят из-за синтаксической ошибки, обнаруженной при извлечении данных из JSON-строки, например, из-за пропущенной запятой
500 Internal Error Запрос не может быть обработан из-за сбоя в платёжной платформе

Статусы запроса

Статус запроса используется для передачи информации о приёме запроса в обработку и указывается в параметре status в теле ответа. Для запроса используется два статуса:

  • success — запрос принят в обработку. Данный статус используется только в рамках взаимодействия по асинхронной схеме в ответах с HTTP-кодом 200.
  • error — запрос не может быть принят в обработку. Данный статус может использоваться в рамках обеих схем взаимодействия в ответах с кодами ошибок 400, 403, 422 и 500.

Ответы с запрошенной информацией

В этом пункте представлены примеры ответа на запрос, обрабатываемый по синхронной схеме. Содержимое JSON-строки в этих примерах разбито на несколько строк для удобства чтения.

Если запрос успешно обработан, то в стартовой строке ответа передаётся код ответа 200, а в теле ответа — запрошенная информация без указания статуса запроса.

Рис.: Ответ с запрошенной информацией

POST /v2/payment/status HTTP/1.1        // Запрос от веб-сервиса на получение статуса платежа в платформе
                    
HTTP/1.1 200 OK                                  // Ответ от платёжной платформы
Server: api.ecommpay.com
Date: Wed, 22 May 2019 10:27:49 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 875
Connection: keep-alive
Keep-Alive: timeout=60
Cache-Control: no-cache
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
X-Powered-By: PHP/7.0.32
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,
X-Requested-With,If-Modified-Since,Cache-Control,Content-Type
Expires: Wed, 22 May 2019 10:27:48 GMT

{
	"project_id":665,
	"payment":{
		"id":"E2E__S02_0.53381200_1558520409",
		"type":"purchase","status":"success",
		"date":"2019-05-22T10:20:20+0000",
		"method":"cup-card",
		"sum":{
			"amount":100,
			"currency":"CNY"
		},
	"description":"Success from PP"
	},
	"account":{
		"number":"628888******8888"
	},
	"customer":{
		"id":"Vally Vasya"
	},
	"operations":[{
		"id":3259141213429,
		"type":"sale",
		"status":"success",
		"date":"2019-05-22T10:20:20+0000",
		"created_date":"2019-05-22T10:20:13+0000",
		"request_id":"e0d69edf1c3aac249e",
		"sum_initial":{
			"amount":100,
			"currency":"CNY"
		},
	"sum_converted":{
		"amount":100,
		"currency":"CNY"
	},
	"provider":{
		"id":1379,
		"payment_id":"1558520414466",
		"date":"2019-05-22T10:20:14+0000",
		"auth_code":""
	},
	"code":"0",
	"message":"Success"
	}],
	"signature":"p6BvZTmzzzUSaN06OVT2SNxTJWvm6\/GEOSEMvUaKgLGzVO5VpKKWt27rq\
	/D1HulyqMGvV0+yN6ixICqSW3oCeA=="
}

Если в запросе обнаружена ошибка, то в стартовой строке ответа указывается код ответа с причиной ошибки (в примере — 422), а в теле — статус error и расширенная информация об ошибке: код ошибки в платёжной платформе (в примере —2003) и описание к нему (в примере — Invalid JSON string).

Рис.: Ответ об ошибке

POST /v2/payment/status HTTP/1.1         // Запрос от веб-сервиса на получение статуса платежа в платформе
                    
HTTP/1.1 422 Unprocessable Entity                 // Ответ от платёжной платформы
Server: nginx/1.14.2
Date: Thu, 30 May 2019 09:44:26 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/7.0.33
Expires: Thu, 30 May 2019 09:44:25 GMT
Cache-Control: no-cache
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,
User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type

{
	"status":"error",
	"code":"2003",
	"message":"Invalid JSON string"
}

Ответы с результатом приёма

В этом пункте представлены примеры ответа на запрос, обрабатываемый по асинхронной схеме. Содержимое JSON-строки в этих примерах разбито на несколько строк для удобства чтения.

Если запрос принят в обработку, то в стартовой строке ответа указывается код ответа200, а в теле — статус success.

Рис.: Ответ о приёме

POST /v2/payment/card/auth HTTP/1.1         // Запрос от веб-сервиса 
                                                    на предварительную блокировку средств
                    
HTTP/1.1 200 OK                                     // Ответ от платёжной платформы
Server: nginx/1.14.2
Date: Thu, 30 May 2019 09:52:16 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/7.0.33
Expires: Thu, 30 May 2019 09:52:15 GMT
Cache-Control: no-cache
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,
X-Requested-With,If-Modified-Since,Cache-Control,Content-Type

{
	"status":"success",
	"request_id":"e7cdefae67068d",
	"project_id":69,
	"payment_id":"ORDER_ID__sendPurchase_dcc_1"
}

Если в запросе обнаружена ошибка, то в стартовой строке ответа указывается код ответа с причиной ошибки (в примере — 400), а в теле — статус error и расширенная информация об ошибке: код ошибки в платёжной платформе (в примере —2004) и описание к нему (в примере — Required field not provided).

Рис.: Ответ об ошибке

POST /v2/payment/card/auth HTTP/1.1     // Запрос от веб-сервиса 
                                                    на предварительную блокировку средств
                    
HTTP/1.1 400 Bad Request                        // Ответ от платёжной платформы
Server: nginx/1.14.2
Date: Thu, 30 May 2019 09:23:23 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/7.0.33

{
	"status":"error",
	"code":"2004",
	"message":"Required field not provided"
}

Формат оповещения

Для передачи промежуточной и итоговой информации о результате обработки и выполнения запроса в рамках асинхронного взаимодействия используются оповещения — HTTP-запросы, отправляемые методом POST от платёжной платформы на согласованные адреса. Общая структура оповещений описана далее, а подробная информация о работе с ними — в разделе Оповещения.

В каждом оповещении от платформы содержатся следующие элементы в порядке перечисления:

  • стартовая строка с указанием метода передачи запроса (POST), URI веб-сервиса для отправки оповещений о результатах (в примере — /notify/success), протокола и его версии (HTTP/1.1);
  • поля заголовка, в том числе поле Host с указанием доменного имени веб-сервиса (в примере — webservice.com);
  • пустая строка — разделитель, отделяющая служебную информацию от тела сообщения;
  • тело сообщения, содержащее JSON-строку в кодировке UTF-8 с набором данных и подписью к ним (структура и последовательность передаваемых объектов и параметров может отличаться).

Далее представлен пример итогового оповещения с информацией о результате проведения платежа. Содержимое JSON-строки в этом примере разбито на несколько строк для удобства чтения.

Рис.: Итоговое оповещение

POST /notify/success HTTP/1.1
Content-Length: 1237
User-Agent: GuzzleHttp/6.3.3 curl/7.47.0 PHP/7.0.32-0ubuntu0.16.04.1
Content-Type: application/json
Host: webservice.com

{
	"account":{
		"number":"421234******1234",
		"token":"1234567890",
		"type":"visa",
		"card_holder":"TEST TEST",
		"id":1234,"expiry_month":"**",
		"expiry_year":"****"
	},
	"customer":{
		"id":"12345",
		"phone":"***********"
	},
	"payment":{
		"date":"2019-06-07T11:38:31+0000",
		"id":"1234567890",
		"method":"card",
		"status":"success",
		"sum":{
			"amount":175000,
			"currency":"RUB"
		},
		"type":"purchase",
		"description":"Deposit to 1234567890"
	},
	"project_id":25,
	"processingDateTime":"2019-06-07T11:38:30+0000",
	"country":"RU",
	"product_name":"Visa",
	"issuer_name":"",
	"operation":{
		"id":1234567890,
		"type":"sale",
		"status":"success",
		"date":"2019-06-07T11:38:32+0000",
		"created_date":"2019-06-07T11:37:56+0000",
		"request_id":"1234567890-1234567890",
		"sum_initial":{
			"amount":175000,
			"currency":"RUB"
		},
		"sum_converted":{
			"amount":175000,
			"currency":"RUB"
		},
		"provider":{
			"id":11,
			"payment_id":"098765432",
			"date":"2019-06-07T11:38:30+0000",
			"auth_code":"","endpoint_id":1
		},
		"code":"0",
		"message":"Success",
		"eci":"05"
	},
	"signature":"qwertyuioiuytrewqwertyuu123434"
}