3.1.2. Посібник з Merchant API#
3.1.2.1. Вступ#
3.1.2.1.1. Про GNU Taler#
GNU Taler - це відкритий протокол для електронної платіжної системи з безкоштовним програмним забезпеченням. GNU Taler пропонує безпечну, швидку та просту обробку платежів за допомогою добре зрозумілих криптографічних методів. GNU Taler дозволяє клієнтам залишатися анонімними, водночас гарантуючи, що продавці можуть бути притягнуті до відповідальності урядами. Таким чином, GNU Taler сумісний з правилами протидії відмиванню грошей (AML) та «знай свого клієнта» (KYC), а також з правилами захисту даних (наприклад, GDPR).
3.1.2.1.2. Про цей підручник#
У цьому підручнику описано, як обробляти платежі за допомогою внутрішнього інтерфейсу GNU Taler. Аудиторією цього підручника є розробники торговельних підприємств (наприклад, веб-магазинів), які працюють над інтеграцією GNU Taler з інтерфейсом користувача і бек-офісом, що працює з персоналом.
У цьому розділі пояснюються деякі базові поняття. У другому розділі ви дізнаєтеся, як здійснювати основні платежі.
Ця версія підручника містить приклади для Python3. Вона використовує бібліотеку requests
для HTTP-запитів. Також доступні версії для інших мов/середовищ.
Якщо ви хочете подивитися на прості, працюючі приклади, перегляньте ці:
Торговець есеями <https://git.taler.net/taler-merchant-demos.git/tree/talermerchantdemos/blog>, який продає окремі розділи книги.
Сторінка пожертви, яка приймає пожертви на програмні проекти та видає квитанції про пожертви.
Плагін WooCommerce, який є комплексною інтеграцією у веб-магазин, включаючи бізнес-процес повернення коштів.
3.1.2.1.3. Огляд архітектури#
Стек програмного забезпечення Taler для торговця складається з таких основних компонентів:
Фронтенд, який взаємодіє з браузером клієнта. Фронтенд дозволяє клієнту створити кошик і оформити замовлення. Після оплати він запускає відповідну бізнес-логіку для виконання замовлення. Цей компонент не входить до складу Taler, але передбачається, що він існує у продавця. Цей підручник описує, як розробити фронтенд для Taler.
Платіжний бекенд, специфічний для Талера, який полегшує фронтенду обробку фінансових транзакцій з Талером. У цьому посібнику ви будете використовувати загальнодоступний бекенд у пісочниці. Для промислового використання ви повинні або створити власний бекенд, або попросити когось зробити це за вас.
Наступне зображення ілюструє різні взаємодії цих ключових компонентів:

Бекенд забезпечує підтримку криптографічного протоколу, зберігає специфічну для Талера фінансову інформацію та взаємодіє з біржею GNU Taler через Інтернет. Фронтенд отримує доступ до бекенду через RESTful API. В результаті, фронтенд ніколи не повинен безпосередньо спілкуватися з біржею, а також не має справи з конфіденційними даними. Зокрема, ключі підпису продавця та інформація про банківські рахунки інкапсульовані в бекенді Taler.
Деяка функціональність бекенду («публічний інтерфейс») доступна безпосередньо браузеру клієнта. У HTTP API всі приватні кінцеві точки (для бек-офісу) мають префікс /private/
. Цей підручник зосереджується на кінцевих точках /private/
. Публічний інтерфейс використовується безпосередньо гаманцем і не має відношення до продавця (за винятком того, що API має бути відкритим).
3.1.2.1.4. Бекенд публічної пісочниці та автентифікація#
Те, як фронтенд аутентифікується в бекенді Taler, залежить від конфігурації. Дивіться Руководство оператора бекенда торговельного терміналу.
Бекенд публічної пісочниці https://backend.demo.taler.net/instances/sandbox/ використовує ключ API в заголовку Authorization
. Значення цього заголовка має бути Bearer secret-token:sandbox
для публічного бекенду пісочниці.
>>> import requests
>>> requests.get("https://backend.demo.taler.net/instances/sandbox/private/orders",
... headers={"Authorization": "Bearer secret-token:sandbox"})
<Response [200]>
Якщо повертається код статусу HTTP, відмінний від 200, це означає, що щось пішло не так. Вам слід з’ясувати, в чому проблема, перш ніж продовжувати роботу з цим підручником.
Бекенд пісочниці https://backend.demo.taler.net/instances/sandbox/ використовує KUDOS
як уявну валюту. Монети, деноміновані в KUDOS
, можна виводити з https://bank.demo.taler.net/.
3.1.2.1.5. Торговельні екземпляри#
Один сервер внутрішнього інтерфейсу продавця Taler може використовуватися декількома продавцями, які є окремими бізнес-суб’єктами. Кожному з цих окремих суб’єктів господарювання призначається екземпляр продавця, який ідентифікується за допомогою алфавітно-цифрового ідентифікатора екземпляра. Якщо ідентифікатор екземпляра не вказано, буде використано ідентифікатор admin
.
На сайті https://backend.demo.taler.net/ налаштовані наступні екземпляри мерчантів:
GNUnet
(проект GNUnet), доступний за адресою https://backend.demo.taler.net/instances/gnunet/.FSF
(The Free Software Foundation), доступний за адресою https://backend.demo.taler.net/instances/fsf/.Tor
(The Tor Project), доступний за адресою https://backend.demo.taler.net/instances/tor/.admin
(Kudos Inc.), доступний за адресою https://backend.demo.taler.net/.пісочниця
(для тестування), доступна за адресою https://backend.demo.taler.net/instances/sandbox/.
Примітка
Це вигадані торговці, які використовуються для наших демонстрацій і не пов’язані з відповідними проектами і не схвалені ними офіційно.
Всі кінцеві точки для екземплярів пропонують однаковий API. Таким чином, екземпляр, який буде використовуватися, просто включається в базову URL-адресу бекенду продавця.
3.1.2.2. Обробка торгових платежів#
3.1.2.2.1. Створення замовлення на платіж#
Платежі в Taler базуються на замовленні, яке є машинозчитуваним описом бізнес-транзакції, за яку має бути здійснений платіж. Перед тим, як прийняти платіж в Талер як продавець, ви повинні створити таке замовлення.
Це робиться шляхом POST’у JSON-об’єкта до кінцевої точки API бекенда /private/orders
. У полі order
повинні бути вказані принаймні наступні поля:
сума
: Сума до сплати, як рядок у форматіCURRENCY:DECIMAL_VALUE
, наприкладEUR:10
для 10 євро абоKUDOS:1.5
для 1.5 KUDOS.суть
: Короткий, зрозумілий для людини опис того, за що здійснюється платіж. Резюме має бути достатньо коротким, щоб вписатися в заголовок, хоча жорстких обмежень не існує.fulfillment_url
: URL-адреса, яка буде відображена після завершення оплати. Для цифрових товарів це має бути сторінка, яка відображає товар, що був придбаний. Після успішної оплати гаманець автоматично додаєorder_id
як параметр запиту, а такожsession_sig
для сесійних платежів (описано нижче).
Замовлення можуть мати набагато більше полів, див. Формат замовлення Taler. Під час відправлення замовлення ви також можете вказати додаткові деталі, такі як перевизначення тривалості відшкодування та інструкції з управління запасами. Вони рідко потрібні і не розглядаються в цьому підручнику; будь ласка, зверніться до довідкового посібника для отримання детальної інформації.
Мінімальний фрагмент Python для створення замовлення виглядатиме так:
>>> import requests
>>> body = dict(order=dict(amount="KUDOS:10",
... summary="Donation",
... fulfillment_url="https://example.com/thanks.html"),
... create_token=False)
>>> response = requests.post("https://backend.demo.taler.net/instances/sandbox/private/orders",
... json=body,
... headers={"Authorization": "Bearer secret-token:sandbox"})
<Response [200]>
Бекенд заповнить деякі деталі, яких не вистачає в замовленні, наприклад, адресу екземпляра продавця. Повна інформація називається умовами контракту.
Примітка
Вищевказаний запит вимикає використання токенів претензій, встановлюючи опцію create_token
у значення false
. Якщо вам потрібні токени претензії, ви повинні скоригувати код, щоб сконструювати URI taler://pay/
, наведений нижче, щоб включити токен претензії.
Після успішного POST
на /private/orders
буде повернуто JSON з одним полем order_id
, яке містить рядок, що представляє ідентифікатор замовлення. Якщо ви також отримали токен претензії, будь ласка, перевірте, чи використовували ви запит, як описано вище.
Разом з «екземпляром» продавця ідентифікатор замовлення однозначно ідентифікує замовлення в бекенді продавця. Використовуючи ідентифікатор замовлення, ви можете тривіально сконструювати відповідний taler://pay/
URI, який має бути наданий гаманцю. Нехай example.com
буде доменним ім’ям, з якого доступні публічні кінцеві точки екземпляра. Тоді URI для оплати в Taler буде просто taler://pay/example.com/$ORDER_ID/
, де $ORDER_ID
потрібно замінити на ідентифікатор замовлення, яке було повернуто.
Ви можете вказати URI taler://
як ціль посилання для відкриття гаманця Taler за схемою taler://
або помістити його в QR-код. Однак для веб-магазину найпростіший спосіб - просто перенаправити браузер на https://example.com/orders/$ORDER_ID
. Ця сторінка запустить гаманець Taler. Тут бекенд генерує правильну логіку для запуску гаманця, підтримуючи різні типи існуючих гаманців Taler. Замість того, щоб створювати наведену вище URL-адресу вручну, її також можна отримати, перевіривши статус платежу, як описано в наступному розділі.
При ручному конструюванні цієї URL-адреси обов’язково додайте токен claim (якщо він не був відключений) і якщо бекенд працює без TLS, використовуйте taler+http://
(зверніть увагу, що останнє підтримується тільки гаманцями, що працюють в режимі налагодження).
Примітка
Тривіальний спосіб отримати правильний payment_redirect_url
- перевірити статус платежу (див. нижче). Тож якщо ви все ще не знаєте, як його створити, ви можете просто попросити бекенд зробити це за вас. Однак у виробництві вам, ймовірно, варто створити його вручну і уникнути зайвих запитів до бекенду.
3.1.2.2.2. Перевірка статусу платежу та запит на оплату#
Знаючи ідентифікатор замовлення, статус платежу можна перевірити за допомогою кінцевої точки /private/orders/$ORDER_ID
. Якщо платіж ще не завершено клієнтом, /private/orders/$ORDER_ID
надасть фронтенду URL-адресу (під назвою payment_redirect_url
), яка запустить гаманець клієнта для виконання платежу. По суті, це URL-адреса https://example.com/orders/$ORDER_ID
, яку ми обговорювали вище.
>>> import requests
>>> r = requests.get("https://backend.demo.taler.net/instances/sandbox/private/orders/" + order_id,
... headers={"Authorization": "Bearer secret-token:sandbox"})
>>> print(r.json())
Якщо поле order_status
у відповіді має значення paid
, ви не отримаєте payment_redirect_url
, а натомість отримаєте інформацію про статус платежу, включно зі статусом оплати:
contract_terms
: Повні умови контракту замовлення.«Відшкодовано»: «істина», якщо за цю покупку було надано (можливо, часткове) відшкодування.
повернута_сума
: Сума, яка була повернута
Після того, як фронтенд підтвердив, що платіж пройшов успішно, він, як правило, повинен запустити бізнес-логіку для виконання продавцем своїх зобов’язань за договором.
Примітка
Вам не потрібно продовжувати запити, щоб помітити зміни в статусі транзакції замовлення. Кінцеві точки підтримують довгі опитування, просто вкажіть параметр запиту timeout_ms
з максимальним часом очікування зміни статусу замовлення на оплачено
.
3.1.2.3. Повернення коштів#
Повернення коштів у GNU Taler - це спосіб «скасувати» платіж. Це має бути дозволено продавцем. Відшкодування може становити будь-яку частину від початкової суми, але воно не може перевищувати початковий платіж. Повернення коштів обмежене в часі і може відбуватися тільки до тих пір, поки біржа утримує кошти для конкретного платежу на ескроу. Час, протягом якого можливе відшкодування, можна контролювати, встановивши термін_відшкодування
в ордері. Значення за замовчуванням для цього терміну відшкодування вказується в конфігурації бекенду продавця.
Фронт-енд може доручити бекенду продавця авторизувати відшкодування за допомогою POST
на кінцеву точку /private/orders/$ORDER_ID/refund
.
JSON-об’єкт запиту на повернення коштів має лише два поля:
«Відшкодування»: Сума, що підлягає поверненню. Якщо для цього замовлення вже було дозволено попереднє відшкодування, нова сума повинна бути більшою, інакше операція не матиме ефекту. Значення вказує на загальну суму до відшкодування, а не на збільшення суми відшкодування.
«Причина»: Обґрунтування повернення коштів, зрозуміле для людини. Причина використовується тільки бек-офісом і не показується клієнту.
Якщо запит виконано успішно (про що свідчить код статусу HTTP 200), відповідь містить taler_refund_uri
. Фронтенд повинен перенаправити браузер клієнта на цю URL-адресу, щоб дозволити гаманцю обробити відшкодування.
Цей фрагмент коду ілюструє повернення коштів:
>>> import requests
>>> refund_req = dict(refund="KUDOS:10",
... reason="Customer did not like the product")
>>> requests.post("https://backend.demo.taler.net/instances/sandbox/private/orders/"
... + order_id + "/refund", json=refund_req,
... headers={"Authorization": "Bearer secret-token:sandbox"})
<Response [200]>
Примітка
Після надання відшкодування публічна кінцева точка https://example.com/orders/$ORDER_ID
змінить взаємодію з гаманцем з запиту на оплату на пропозицію відшкодування. Таким чином, фронтенди можуть знову перенаправляти браузери на цю кінцеву точку. Однак для цього необхідно додати поле h_contract
(?h_contract=$H_CONTRACT
), оскільки публічна кінцева точка вимагає його для аутентифікації клієнта. Необхідне значення $H_CONTRACT
повертається у відповіді на повернення коштів у полі h_contract
.
3.1.2.4. URL-адреси для виявлення та виконання зворотного викупу#
Можлива проблема для продавців, які продають доступ до цифрових статей, полягає в тому, що клієнт може заплатити за статтю на одному пристрої, але потім захотіти прочитати її на іншому пристрої, можливо, на якому навіть не встановлений гаманець Taler.
Звичайно, на цьому етапі покупцеві спочатку все одно буде запропоновано оплатити статтю ще раз. Якщо клієнт відкриє посилання taler://
у гаманці, за допомогою якого він раніше оплачував товар (наприклад, відсканувавши QR-код на робочому столі за допомогою програми для Android), гаманець затребує контракт, виявить, що URL-адреса виконання ідентична тій, за якою він вже здійснював оплату в минулому, і ініціює перенаправлення на повторний викуп: Тут гаманець зв’яжеться з продавцем і відтворить попередній платіж, але цього разу з використанням (поточного) ідентифікатора сеансу браузера (він дізнається ідентифікатор сеансу з QR-коду).
Потім бекенд продавця оновлює ідентифікатор сесії існуючого замовлення до поточного ідентифікатора сесії браузера. Коли перевіряється статус оплати «нового» неоплаченого замовлення (або замовлення, яке вже знаходиться в довгій черзі), бекенд виявляє, що для ідентифікатора сеансу і адреси виконання браузера існує оплачений контракт. Потім він повідомляє браузеру, щоб той негайно перенаправив його на URL-адресу виконання, де вже доступна оплачена стаття.
Щоб цей механізм працював належним чином, продавці повинні переконатися, що вони не використовують одну й ту саму URL-адресу для різних товарів або для фізичних товарів, якщо очікується, що клієнти купуватимуть товар неодноразово. Так само важливо, щоб продавці постійно використовували одну й ту саму URL-адресу для одного й того самого цифрового продукту, якщо потрібне виявлення зворотного викупу.
Зверніть увагу, що зміна ідентифікатора сесії на іншому пристрої вимагає залучення гаманця, з якого було здійснено платіж, що розумно обмежує можливість широкого обміну цифровими покупками. Виявлення викупу також здійснюється лише для URL-адрес виконання HTTP(S). Зокрема, це означає, що URL-адреси виконання, такі як taler://fulfillment-success/$MESSAGE
, не вважаються ідентифікатором ресурсу, за який ви можете заплатити, а отже, не повинні бути унікальними.
3.1.2.5. Розширені теми#
3.1.2.5.1. Сесійні платежі#
Іноді недостатньо просто перевірити, чи оплачено замовлення. Наприклад, продаючи доступ до онлайн-медіа, видавець може захотіти, щоб кожен покупець заплатив за один і той самий продукт. Taler підтримує цю модель, дозволяючи продавцю перевірити, чи доступна «квитанція про оплату» на поточному пристрої користувача. Це заважає користувачам легко ділитися доступом до медіа, передаючи посилання на сторінку виконання замовлення. Звичайно, досвідчені користувачі можуть ділитися квитанціями про оплату, але це не так просто, як поділитися посиланням, і в цьому випадку вони, швидше за все, просто поділяться медіа безпосередньо.
Щоб скористатися цією функцією, продавець повинен спочатку присвоїти поточному браузеру користувача ефемерний «ідентифікатор сеансу», як правило, за допомогою сесійного файлу cookie. При виконанні або повторному відтворенні платежу гаманець отримує додатковий підпис (сесія_sig
). Цей підпис засвідчує, що гаманець показав квитанцію про оплату відповідного замовлення в поточній сесії.
Прив’язані до сесії платежі запускаються шляхом передачі параметра session_id
кінцевій точці /check-payment
. Після цього гаманець буде перенаправлений на сторінку виконання, але з додатковим параметром session_sig
. Фронтенд може запитувати /check-payment
з обома параметрами `` session_id`` і `` session_sig``, щоб перевірити правильність підпису.
Ідентифікатор останньої сесії, який було успішно використано для підтвердження того, що квитанція про оплату знаходиться в гаманці користувача, також доступний як last_session_id
у відповіді на запит /check-payment
.
3.1.2.5.2. Ідентифікація продукту#
У деяких ситуаціях користувач може заплатити за якийсь цифровий товар, але фронтенд не знає точного ідентифікатора замовлення, а отже, не може наказати гаманцю показати наявну квитанцію про оплату. Це характерно для простих магазинів без системи входу в систему. У цьому випадку користувачеві буде запропоновано здійснити оплату ще раз, навіть якщо він вже придбав товар.
Щоб гаманець міг знайти існуючу квитанцію про оплату, магазин повинен використовувати унікальну URL-адресу виконання для кожного товару. Тоді фронтенд повинен додати додатковий параметр resource_url
до /check-payment
. Він повинен ідентифікувати цю унікальну URL-адресу виконання для продукту. Після цього гаманець перевірить, чи оплачував він контракт з такою ж resource_url
раніше, і якщо так, то відтворить попередній платіж.
3.1.2.5.3. Формат замовлення Taler#
У замовленні Taler можна вказати багато деталей про платіж. У цьому розділі детально описано кожне з полів.
Фінансові суми завжди вказуються у вигляді рядка у форматі "CURRENTY:DECIMAL_VALUE"
.
- кількість
Вказує загальну суму, яку покупець має сплатити продавцю.
- max_fee
Це максимальна загальна сума комісійних, яку готовий сплатити продавець. Якщо комісія за зберігання монет перевищує цю суму, клієнт повинен включити її в загальну суму платежу. Комісія вказується в тому ж форматі, що і
сума
.
- max_wire_fee
Максимальна комісія за переказ, яку приймає продавець (частка клієнта, яка ділиться на коефіцієнт
wire_fee_amortization
, і ще більше зменшується, якщо комісія за депозит нижча заmax_fee
). За замовчуванням, якщо відсутнє, дорівнює нулю.
- амортизація_плати_за_передачу
За скільки клієнтських транзакцій продавець очікує в середньому амортизувати комісію за переказ? Якщо комісія за переказ перевищує
max_wire_fee
, різниця ділиться на це число, щоб обчислити очікуваний внесок клієнта в комісію за переказ. Внесок клієнта може бути додатково зменшений на різницю міжmax_fee
і сумою фактичних комісій за депозит. Необов’язкове, значення за замовчуванням, якщо відсутнє - 1. Нульові та від’ємні значення є недійсними і також інтерпретуються як 1.
- pay_url
На яку URL-адресу приймати платежі. Це адреса, на яку гаманець буде відправляти монети.
- адреса_виконання
На яку URL-адресу повинен перейти гаманець, щоб отримати виконання, наприклад, HTML або PDF статті, яку було куплено, або систему відстеження замовлень для відправлень, або просту веб-сторінку, яка читається людиною і вказує на статус контракту.
- order_id
Буквено-цифровий ідентифікатор, який вільно визначається продавцем. Використовується продавцем для унікальної ідентифікації транзакції.
- резюме
Короткий, зрозумілий для людини підсумок договору. Використовується для відображення договору в одному рядку, наприклад, в історії транзакцій клієнта.
- мітка часу
Час, в який було згенеровано пропозицію.
- pay_deadline
Мітка часу, до якого продавець хоче, щоб біржа остаточно перевела гроші, належні за цим контрактом. Після закінчення цього терміну біржа об’єднає всі депозити, контракти за якими закінчилися після
терміну_повернення_коштів
, і виконає для них один великий банківський платіж. Суми будуть округлені до одиниці банківського переказу; якщо загальна сума все ще буде меншою за одиницю банківського переказу, вона не буде виплачена.
- refund_deadline
Мітка часу, до якої продавець бажає (і може) відшкодувати кошти за контрактом з використанням Taler. Зверніть увагу, що біржа Taler буде утримувати платіж в ескроу принаймні до цього терміну. До цього часу продавець зможе підписати повідомлення, щоб ініціювати повернення коштів покупцеві. Після цього часу повернути кошти покупцеві буде вже неможливо. Має бути меншим за
pay_deadline
.
- продукти
Масив товарів, які продаються клієнту. Кожен запис містить кортеж з наступними значеннями:
- опис
Опис продукту.
- кількість
Кількість товарів, що відправляються. Можна вказати одиницю виміру (наприклад,
1 кг
) або просто кількість.- ціна
Ціна за
кількість
одиниць цього товару, що доставляється до вказаногомісця_поставки
. Зауважте, що зазвичай сума всіх цін повинна складати загальну суму контракту, але вона може відрізнятися через знижки або через те, що окремі ціни недоступні.- product_id
Унікальний ідентифікатор товару в каталозі продавця. Загалом може бути обраний довільно, оскільки має значення лише для продавця, але має бути числом у діапазоні
.
- податки
Карта застосовних податків, які має сплатити продавець. Мітка - це назва податку, тобто ПДВ, податок з продажу або податок на прибуток, а значення - це сума податку, що підлягає сплаті. Зауважте, що дозволяється використовувати довільні позначки, якщо вони використовуються для ідентифікації застосовного податкового режиму. Деталі можуть бути визначені регулятором. Ця інформація використовується для того, щоб повідомити покупцеві, які податки продавець має намір сплатити, і може бути використана покупцем як квитанція. Ця інформація також може бути використана під час податкових перевірок продавця.
- дата_поставки
Час, до якого товар має бути доставлений до
місця_доставки
.- місце_доставки
Це повинно призвести до появи мітки на мапі
локації
, яка вказує, куди буде доставлено товар.
Значення можна не вказувати, якщо вони не застосовуються. Наприклад, якщо покупка стосується набору продуктів, які не мають індивідуальних цін або ідентифікаторів продуктів,
product_id
абоprice
можуть не вказуватися в договорі. Аналогічно, для віртуальних продуктів, що доставляються безпосередньо через URI виконання, не вказуєтьсямісце_доставки
.- купець
- адреса
Це повинно призвести до появи мітки на карті
місцезнаходження
, яка вказує, де знаходиться продавець.- ім’я
Це повинно дати зрозумілу назву для бізнесу торговця.
- юрисдикція
Це повинно призвести до появи позначки на карті «місцезнаходження» із зазначенням юрисдикції, відповідно до якої цей контракт має розглядатися в арбітражному суді.
- локації
Асоціативна карта локацій, що використовуються в договорі. Позначки для місцезнаходжень на цій карті можна вільно вибирати і використовувати, коли місцезнаходження потрібне в інших частинах договору. Таким чином, якщо одне й те саме місцезнаходження вимагається багато разів (наприклад, бізнес-адреса замовника або продавця), його потрібно вказати (і передати) лише один раз, а в інших випадках на нього можна посилатися за допомогою мітки. Нижче наведено неповний перелік атрибутів місцезнаходження:
- ім’я
Ім’я одержувача для доставки, або ім’я компанії, або ім’я фізичної особи.
- країна
Назва країни доставки, вказана на поштовому пакеті, наприклад, «Франція».
- стан
Назва штату для доставки, як зазначено на поштовому пакеті, наприклад, «NY».
- регіон
Назва регіону доставки, вказана на поштовому пакеті.
- провінції
Назва області для доставки, як зазначено на поштовому пакеті.
- місто
Назва міста доставки, вказана на поштовому пакеті.
- zip_code
Поштовий індекс для доставки, вказаний на поштовому пакеті.
- вулиця
Назва вулиці для доставки, вказана на поштовому пакеті.
- номер_вулиці
Номер вулиці (номер будинку) для доставки, вказаний на поштовому пакеті.
Примітка
Локації не зобов’язані вказувати всі ці поля, і вони також можуть мати додаткові поля. Рендери, що працюють за контрактом, повинні відображати принаймні перелічені вище поля, а поля, які вони не розуміють, повинні відображати у вигляді списку ключ-значення.