API FONDYВерсия 1.0

Тестовые реквизиты

ID мерчантаКлюч платежаОписание
1396424testОсновной (технический) мерчант. От имени этого мерчанта будет строиться запрос на API расщепления и формироваться сигнатура
500001Мерчант контрагента 1, на которого необходимо расщепить первую часть суммы
600001Мерчант контрагента 2, на которого необходимо расщепить вторую часть суммы

 

Методы расщепления

АПИ расчетного центра позволяет расщеплять платеж, оплаченый плательщиком, на несколько получателей — контрагентов.

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

Реквизиты всех контрагентов передаются в запросе в параметре receiver и могут собой представлять любую из следующих сущностей: 

Свободные реквизиты счета IBAN

пример:

"receiver":{
       "requisites": {
         "amount": 100,
         "settlement_description": "Назначение платежа для банковского перевода",
         "account": 123456789,
         "okpo": 1234567,
         "jur_name": "ООО Ромашка",
         "fee_partner_amount": 102
       },
       "type": "bank_account"
     }

Реквизиты мерчанта

пример:

"receiver":{
       "requisites": {
         "amount": 200,
         "settlement_description": "Назначение платежа для банковского перевода",
         "merchant_id": 600001,
         "fee_partner_amount": 102
       },
       "type": "merchant"
     }

Токен карты

пример:

"receiver":{
       "requisites": {
         "rectoken": "da82035bc13c78f2eb74df7caf81decc3601061c",
         "amount": 500,
         "fee_partner_amount": 102
       },
       "type": "rectoken"
     }

Номер карты

пример:

"receiver":{
       "requisites": {
         "amount": 500,
         "card_number": 4444555511116666,
         "fee_partner_amount": 102
       },
       "type": "card"
     }

Пошагова инструкция

Шаг 1. Покупка

Покупатель осуществляет покупку любым из методов интеграции.

При этом, платежу присваивается уникальный order_id.

Если сумму нужно только заблокировать, но не списывать с карты, во время осуществления покупки, нужно передать параметр preauth = Y

Сумма, заблокированная с параметром preauth = Y в дальнейшем может быть изменена в меньшую сторону посредством операции capture.

Платеж, осуществленный с параметром preauth = Y не списывается с карты и не зачисляется на счет Fondy до получения запроса на операцию capture.

Платеж, осуществленный с параметром preauth = N или без параметра preauth, списывается с карты и зачисляется на счет Fondy в ожидании инструкции на расщепление.

Шаг 2. Capture (не обязательный)

Если на шаге 1 платеж был осуществлен с параметром preauth = Y, его необходимо завершить операцией capture.

Шаг 3. Расщепление

Послать запрос расщепления на https://pay.fondy.eu/api/settlement передав параметр operation_id идентичный order_id из шага 1 и инструкции расщепления в параметре receiver.

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

Запрос отправляется методом POST в формате JSON на endpoint:

https://pay.fondy.eu/api/settlement

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

{
 "request": {
   "version": 2.0,
   "data": "ewogIm9yZGVyIjogewogICAic2VydmVyX2NhbGxiYWNrX3VybCI6ICJodHRwOi8vc2l0ZS5jb20vY2FsbGJhY2siLAogICAicmVjdG9rZW4iOiAiOTg5YmI5MzRiZTZiMWEwYjRmZDc1YzU5YWRhZTczOTRlNTZmNGM2MCIsIC8vINC00LvRjyDQodGF0LXQvNCwIDIuINCf0L7RgdGA0LXQtNGB0YLQstC+0Lwg0YLQvtC60LXQvdCwCiAgICJjdXJyZW5jeSI6ICJVQUgiLAogICAiYW1vdW50IjogIjE0MDAiLAogICAib3JkZXJfdHlwZSI6ICJzZXR0bGVtZW50IiwKICAgInJlc3BvbnNlX3VybCI6ICJodHRwOi8vc2l0ZS5jb20vdGVzdC9yZXNwb25zZXBhZ2UvIiwKICAgIm9yZGVyX2lkIjogInRlc3QxMjM0NTYxNDY3NDYyMDk5LjE5IiwKICAgIm9wZXJhdGlvbl9pZCI6ICJ0ZXN0MTIzNDU2MTQ2NzQ2MjA5OS4xOSIsCiAgICJvcmRlcl9kZXNjIjogInRlc3Qgb3JkZXIiLAogICAibWVyY2hhbnRfaWQiOiAxMzk2NDI0LAogICAicmVjZWl2ZXIiOiBbCiAgICAgewogICAgICAgInJlcXVpc2l0ZXMiOiB7CiAgICAgICAgICJhbW91bnQiOiAxMDAsCiAgICAgICAgICJzZXR0bGVtZW50X2Rlc2NyaXB0aW9uIjogItCd0LDQt9C90LDRh9C10L3QuNC1INC/0LvQsNGC0LXQttCwINC00LvRjyDQsdCw0L3QutC+0LLRgdC60L7Qs9C+INC/0LXRgNC10LLQvtC00LAiLAogICAgICAgICAibWVyY2hhbnRfaWQiOiA1MDAwMDEKICAgICAgIH0sCiAgICAgICAidHlwZSI6ICJtZXJjaGFudCIKICAgICB9LHsKICAgICAgICJyZXF1aXNpdGVzIjogewogICAgICAgICAiYW1vdW50IjogMjAwLAogICAgICAgICAic2V0dGxlbWVudF9kZXNjcmlwdGlvbiI6ICLQndCw0LfQvdCw0YfQtdC90LjQtSDQv9C70LDRgtC10LbQsCDQtNC70Y8g0LHQsNC90LrQvtCy0YHQutC+0LPQviDQv9C10YDQtdCy0L7QtNCwIiwKICAgICAgICAgIm1lcmNoYW50X2lkIjogNjAwMDAxCiAgICAgICB9LAogICAgICAgInR5cGUiOiAibWVyY2hhbnQiCiAgICAgfSwKICAgICB7CiAgICAgICAicmVxdWlzaXRlcyI6IHsKICAgICAgICAgImFtb3VudCI6IDEwMCwKICAgICAgICAgInNldHRsZW1lbnRfZGVzY3JpcHRpb24iOiAi0J3QsNC30L3QsNGH0LXQvdC40LUg0L/Qu9Cw0YLQtdC20LAg0LTQu9GPINCx0LDQvdC60L7QstGB0LrQvtCz0L4g0L/QtdGA0LXQstC+0LTQsCIsCiAgICAgICAgICJhY2NvdW50IjogMTIzNDU2Nzg5LAogICAgICAgICAibWZvIjogMTIzNDUsCiAgICAgICAgICJva3BvIjogMTIzNDU2Nzg5LAogICAgICAgICAianVyX25hbWUiOiAi0J7QntCeINCg0L7QvNCw0YjQutCwIgogICAgICAgfSwKICAgICAgICJ0eXBlIjogImJhbmtfYWNjb3VudCIKICAgICB9LAogICAgIHsKICAgICAgICJyZXF1aXNpdGVzIjogewogICAgICAgICAicmVjdG9rZW4iOiAiZGE4MjAzNWJjMTNjNzhmMmViNzRkZjdjYWY4MWRlY2MzNjAxMDYxYyIsCiAgICAgICAgICJhbW91bnQiOiA1MDAKICAgICAgIH0sCiAgICAgICAidHlwZSI6ICJyZWN0b2tlbiIKICAgICB9LAogICAgIHsKICAgICAgICJyZXF1aXNpdGVzIjogewogICAgICAgICAiYW1vdW50IjogNTAwLAogICAgICAgICAiY2FyZF9udW1iZXIiOiA0NDQ0NTU1NTExMTE2NjY2CiAgICAgICB9LAogICAgICAgInR5cGUiOiAiY2FyZCIKICAgICB9CiAgIF0KIH0KfQo=",
   "signature": "943571471619207087eb57e2b4ef69affd337b1a"
 }
}

data — это base64 кодированный набор данных формата:

{
 "order": {
   "server_callback_url": "http://site.com/callback",
   "currency": "UAH",
   "amount": "1400",
   "order_type": "settlement",
   "response_url": "http://site.com/test/responsepage/",
   "order_id": "settlement_test1234561467462099.19",
   "operation_id": "test1234561467462099.19",
   "order_desc": "test order",
   "merchant_id": 1396424,
   "receiver": [
     {
       "requisites": {
         "amount": 100,
         "settlement_description": "Назначение платежа для банковского перевода",
         "merchant_id": 500001,
         "fee_partner_amount": 102
       },
       "type": "merchant"
     },{
       "requisites": {
         "amount": 200,
         "settlement_description": "Назначение платежа для банковского перевода",
         "merchant_id": 600001,
         "fee_partner_amount": 90
       },
       "type": "merchant"
     },
     {
       "requisites": {
         "amount": 100,
         "settlement_description": "Назначение платежа для банковского перевода",
         "account": 123456789,
         "okpo": 1234567,
         "jur_name": "ООО Ромашка",
         "fee_partner_amount": 70
       },
       "type": "bank_account"
     },
     {
       "requisites": {
         "rectoken": "da82035bc13c78f2eb74df7caf81decc3601061c",
         "amount": 500,
         "fee_partner_amount": 50
       },
       "type": "rectoken"
     },
     {
       "requisites": {
         "amount": 500,
         "card_number": 4444555511116666,
         "fee_partner_amount": 40
       },
       "type": "card"
     }
   ]
 }
}

Формат финального ответа

Ответ возвращается в формате JSON на server_callback_url и response_url после того, как клиент завершит оплату

Формат финального ответа:

{
 "response": {
   "version": "2.0",
   "data": "ewogICJvcmRlciI6IHsKICAgICJycm4iOiAiIiwKICAgICJtYXNrZWRfY2FyZCI6ICI0NDQ0NTVYWFhYWFg2NjY2IiwKICAgICJzZW5kZXJfY2VsbF9waG9uZSI6ICIiLAogICAgInJlc3BvbnNlX3N0YXR1cyI6ICJzdWNjZXNzIiwKICAgICJzZW5kZXJfYWNjb3VudCI6ICIiLAogICAgImZlZSI6ICIiLAogICAgInJlY3Rva2VuX2xpZmV0aW1lIjogIiIsCiAgICAicmV2ZXJzYWxfYW1vdW50IjogIjAiLAogICAgInNldHRsZW1lbnRfYW1vdW50IjogIjAiLAogICAgImFjdHVhbF9hbW91bnQiOiAiMjAwMCIsCiAgICAib3JkZXJfc3RhdHVzIjogImFwcHJvdmVkIiwKICAgICJyZXNwb25zZV9kZXNjcmlwdGlvbiI6ICIiLAogICAgInZlcmlmaWNhdGlvbl9zdGF0dXMiOiAiIiwKICAgICJvcmRlcl90aW1lIjogIjAyLjA3LjIwMTYgMTU6MjE6MzkiLAogICAgImFjdHVhbF9jdXJyZW5jeSI6ICJVQUgiLAogICAgIm9yZGVyX2lkIjogInRlc3QxMjM0NTYxNDY3NDYyMDk5LjE5IiwKICAgICJwYXJlbnRfb3JkZXJfaWQiOiAiIiwKICAgICJtZXJjaGFudF9kYXRhIjogIiIsCiAgICAidHJhbl90eXBlIjogInB1cmNoYXNlIiwKICAgICJlY2kiOiAiIiwKICAgICJzZXR0bGVtZW50X2RhdGUiOiAiIiwKICAgICJwYXltZW50X3N5c3RlbSI6ICJjYXJkIiwKICAgICJyZWN0b2tlbiI6ICIiLAogICAgImFwcHJvdmFsX2NvZGUiOiAiNDc4NDUwIiwKICAgICJtZXJjaGFudF9pZCI6IDEzOTY0MjQsCiAgICAic2V0dGxlbWVudF9jdXJyZW5jeSI6ICIiLAogICAgInBheW1lbnRfaWQiOiAxNTg2MTkzLAogICAgInRyYW5zYWN0aW9uIjogWwogICAgICB7CiAgICAgICAgInN0YXR1cyI6ICJhcHByb3ZlZCIsCiAgICAgICAgImFtb3VudCI6IDIwLjAsCiAgICAgICAgImZlZSI6IDAuMCwKICAgICAgICAicmV2ZXJzYWxfYW1vdW50IjogMC4wLAogICAgICAgICJwYXJlbnRfdHJhbl9pZCI6IG51bGwsCiAgICAgICAgInJlY2VpdmVyIjoge30sCiAgICAgICAgIm1lcmNoYW50X2lkIjogNjAwMDAxLAogICAgICAgICJ0eXBlIjogInB1cmNoYXNlIiwKICAgICAgICAiaWQiOiAxMDAxNTQzOTYwLAogICAgICAgICJkb2Nfbm8iOiBudWxsCiAgICAgIH0KICAgIF0sCiAgICAicHJvZHVjdF9pZCI6ICIiLAogICAgImN1cnJlbmN5IjogIlVBSCIsCiAgICAiY2FyZF9iaW4iOiA0NDQ0NTUsCiAgICAicmVzcG9uc2VfY29kZSI6ICIiLAogICAgImNhcmRfdHlwZSI6ICJWSVNBIiwKICAgICJhbW91bnQiOiAiMjAwMCIsCiAgICAic2VuZGVyX2VtYWlsIjogImRlbW9AZm9uZHkuZXUiCiAgfQp9",
   "signature": "54aeeadf05b04e2e4097a4aa5907c3a62684d058"
 }
}

где data — это base64 кодированный набор данных, содержащих информацию о всех финансовых операциях и их статусе

{
 "order": {
   "rrn": "",
   "masked_card": "444455XXXXXX6666",
   "sender_cell_phone": "",
   "response_status": "success",
   "sender_account": "",
   "fee": "",
   "rectoken_lifetime": "",
   "reversal_amount": "0",
   "settlement_amount": "0",
   "actual_amount": "2000",
   "order_status": "approved",
   "response_description": "",
   "verification_status": "",
   "order_time": "02.07.2016 15:21:39",
   "actual_currency": "UAH",
   "order_id": "test1234561467462099.19",
   "parent_order_id": "",
   "merchant_data": "",
   "tran_type": "purchase",
   "eci": "",
   "settlement_date": "",
   "payment_system": "card",
   "rectoken": "",
   "approval_code": "478450",
   "merchant_id": 1396424,
   "settlement_currency": "",
   "payment_id": 1586193,
   "transaction": [
     {
       "status": "approved",
       "amount": 20.0,
       "fee": 0.0,
       "reversal_amount": 0.0,
       "parent_tran_id": null,
       "receiver": {},
       "merchant_id": 600001,
       "type": "purchase",
       "id": 1001543960,
       "doc_no": null
     }
   ],
   "product_id": "",
   "currency": "UAH",
   "card_bin": 444455,
   "response_code": "",
   "card_type": "VISA",
   "amount": "2000",
   "sender_email": "demo@fondy.eu"
 }
}

Расчет сигнатуры

Параметр signature рассчитывается как функция sha1(password + ‘|’ +data)

Возврат средств

При возврате средств, в параметрах receiver->requisites-> необходимо указывать, с какого мерчанта какая часть основной суммы должна быть удержана.

Например если основная сумма «amount»: «300», то необходимо в запросе указать receiver->receiver->amount таким образом, чтобы все их значения суммарно равнялись основной сумме.

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

POST: https://pay.fondy.eu/api/reverse/order_id

Пример параметра data:

{
  "order": {
    "order_id": "test1234561467462099.19",
    "currency": "UAH",
    "amount": "300",
    "merchant_id": "1396424",
    "receiver": [
      {
        "requisites": {
          "amount": 100,
          "merchant_id": "500001"
        },
        "type": "merchant"
      },
      {
        "requisites": {
          "amount": 200,
          "merchant_id": "600001"
        },
        "type": "merchant"
      }
    ]
  }
}

где: order_id и merchant_id — идентификаторы оригинального платежа Пример ответа в случае успешного возврата:

{
  "order": {
    "reverse_status": "approved",
    "reversal_amount": "300",
    "order_id": "test1234561467462099.19",
    "response_status": "success",
    "response_code": "",
    "response_description": "",
    "merchant_id": 1396424
  }
}

Пример ответа в случае отказа:

{
  "order": {
    "reverse_status": "declined",
    "reversal_amount": "300",
    "order_id": "test1234561467462099.19",
    "response_status": "success",
    "response_code": "1016",
    "response_description": "Merchant not found",
    "merchant_id": 1396424
  }
}

Получение статуса расщепления

При создании на стороне FONDY платежной инструкции на расщепление, процесс обработки инструкции проходит в три статуса: created -> processing -> approved

created: инструкция получена и поставлена в очередь на расщепление

approved: система СЭП НБУ подтвердила, что средства зачислены получателям

Для получения статуса расщепления, необходимо использовать API Получение списка транзакций. В параметрах order_id и merchant_id необходимо передавать значения того ордера, который содержал инструкцию расщепления в параметре receiver.

При успешном расщеплении в списке транзакций будут транзакции с tran_type=settlement и transaction_status=approved которые соответствуют расщепленным сумам.

Расщепление проходит по регламенту в срок, указанный в договоре между мерчантом и FONDY.

 

Обработка колбека

После получения запроса на расщепление, на server_callback_url, указанный при покупке будет возвращен колбек в формате

{
  "version": "2.0",
  "data": "eyJvcmRl...tZW50X2N1cnJlbmN5IjogIiJ9fQ==",
  "signature": "21fdf2e7938a7c6b7b883b4d7698e55e781b2445"
}

где параметр data содержит структуру:

{
  "order": {
    "payment_id": 248671633,
    "fee": "",
    "order_type": "settlement",
    "reversal_amount": "0",
    "order_id": "1299382-settlement-test1595856030",
    "settlement_amount": "0",
    "merchant_data": "",
    "settlement_date": "",
    "transaction": [
      {
        "status": "approved",
        "odb_ref": null,
        "doc_no": null,
        "currency": "UAH",
        "settlement_response_code": "",
        "merchant_id": 700001,
        "id": 1241093791,
        "settlement_currency": "UAH",
        "settlement_fee": 0.01,
        "fee": 1,
        "reversal_amount": 0,
        "settlement_amount": 0.25,
        "settlement_status": "created",
        "amount": 25,
        "settlement_response_description": "",
        "parent_tran_id": null,
        "receiver": {
          "requisites": {
            "merchant_id": "500001"
          },
          "type": "merchant"
        },
        "payouttime": "28.07.2020 08:00:00",
        "type": "settlement"
      },
      {
        "status": "approved",
        "odb_ref": null,
        "doc_no": null,
        "currency": "UAH",
        "settlement_response_code": "",
        "merchant_id": 700001,
        "id": 1241093793,
        "settlement_currency": "UAH",
        "settlement_fee": 10.38,
        "fee": 1038,
        "reversal_amount": 0,
        "settlement_amount": 374.0,
        "settlement_status": "created",
        "amount": 37400,
        "settlement_response_description": "",
        "parent_tran_id": null,
        "receiver": {
          "requisites": {
            "merchant_id": "600001"
          },
          "type": "merchant"
        },
        "payouttime": "28.07.2020 08:00:00",
        "type": "settlement"
      }
    ],
    "operation_id": "1299382-test",
    "order_status": "approved",
    "response_description": "",
    "merchant_id": 1396424,
    "order_time": "27.07.2020 16:20:30",
    "response_code": "",
    "settlement_currency": ""
  }
}

В колбеке по такому запросу будет возвращен объект order, который содержит тип заказа order_type = settlement.

Парамет order_status указывает на то, обработан ли запрос на расщепление, или отклонен.

order_status объекта order может принимать 2 значения

approved — запрос на расщепление обработан

declined — запрос на расщепление отклонен

Причина и описание отказа при статусе declined возвращается в параметрах response_code и response_description.

Объект order также состоит из массива объектов transaction, содержащий список транзакций, на которые расщепилась покупка. У каждой такой транзакции указан type = settlement.

Параметр status объекта transaction может принимать такие значения:

created — транзакция расщепления еще не обработана

approved — транзакция расщепления успешно обработана и средства поступят на счет получателя

Интеграционные тесты

Перед запуском в боевом режиме, необходимо убедиться, что интеграция проведена в соответствии с документацией.

Для этого необходимо выполнить ряд тестовых операций, и предоставить идентификаторы order_id команде технической поддержки Fondy.

Тестовые операции должны быть выполнены по реальной карте на небольшую сумму, обычно в пределах 1-2 грн.

Тесты:

  1. Покупка
  2. Покупка с preauth = Y и capture на полную сумму — обязательно, если используется двустадийная модель блокировки средств и списания
  3. Покупка с preauth = Y и capture на частичную сумму — обязательно, если используется двустадийная модель блокировки средств и списания
  4. Расщепление на сумму покупки из теста 1
  5. Расщепление на сумму полного capture из теста 2 — обязательно, если используется preauth = Y 
  6. Расщепление на сумму частичного capture из теста 3- обязательно, если используется preauth = Y 
  7. Расщепление на некорректную сумму (получение status = declined)
  8. Повторное расщепление уже расщепленного order_id (получение status = declined)
  9. Обработка колбека по успешному расщеплению из теста 4 (статус HTTP 200 OK на server_callback_url)
  10. Обработка колбека по не успешному расщеплению из теста 7 (статус HTTP 200 OK на server_callback_url)

Просмотр отчетов о расщеплении в Мерчант Портале

Для мониторинга платежей и финансовых отчетов, используйте отчеты в личном кабинете Мерчант-портала. Для этого залогиньтесь в Мерчант-портал и перейдите в меню Отчеты -> Пользовательские отчеты. В данном меню вам будут доступны два основных отчета:

  • Нерасщепленные платежи — список всех, не расщепленных по разным причинам платежей.
  • Расщепления — список всех расщепленных платежей, и информацию о получателях и статусах получения средств.

Нерасщепленные платежи

Как правило, основными причинами, по которым платежи не расщепляются, являются

  • отсутствие запроса на расщепление. Когда покупка плательщиком осуществлена, но запроса на https://pay.fondy.eu/api/settlement не был отправлен
  • запрос на расщепление пришел с некорректной суммой. Это либо сумма всех расщеплений на получателей не равна сумме покупки, либо не равна сумме capture
  • в запросе на расщепление в параметре receiver указан merchant_id, который еще не активирован на стороне Fondy

Расщепления

Отчет по расщепления отображает детальную информацию о том, куда поступили средства, в каком объеме, в какие даты.

Данный отчет можно использовать как в ручном режиме, так и для автоматизированных финансовых сверок через API отчетов. Для этого в отчете нужно использовать report_id = 595

Хочу принимать платежи со всего мира!