NAV
HTTP cURL

Introduction

Hokodo provides a set of API endpoints to facilitate Deferred Payments, also known as credit terms, or "Buy Now, Pay Later" (BNPL) for B2B platforms, such as marketplaces or e-commerce sites.

This reference documentation details how developers may use Hokodo to implement credit terms into their customer journey, from checking whether a customer can be eligible for credit terms, to submitting a customer's orders to Hokodo. Hokodo APIs are organized around REST, with predictable, resource-oriented URLs, and use HTTP response codes to indicate API errors.

Our API expects incoming data to be valid JSON objects with requests containing the header Content-Type: application/json, unless explicitly stated otherwise.

All responses of the API, including errors, are in JSON, except for some endpoints returning PDF documents, Excel files or CSV files, that will be clearly indicated as such.

You can view request/response examples in the dark area to the right, and you can switch between raw representation and curl command with tabs in the top right.

The base URL of the API in the sandbox (see environments) is https://api-sandbox.hokodo.co/

 API Guide

This API reference is a comprehensive description of the technical behaviour of Hokodo's BNPL API.

It is intended to be read alongside our API Guide, which should be your primary resource for integrating Hokodo's BNPL solution.

Glossary

In the document, we will use the following terms, with a specific meaning:

Organisations and Users

Because Hokodo focuses on B2B sales, the buyers on your platform will consist of Companies, who have employees, and those employees may be organised into teams or departments. Hokodo deals with this complexity through the concept of Organisations and Users.

A User is an individual employee at a company.
An Organisation is a group of Users who are all able to see or take action on that company's orders on your platform. Each Organisation must be associated with a Company.

In many cases the company will just have a single Organisation, and any employees of the company (Users) will be members of that Organisation. In this case, any one of those Users will be able to see or take actions on any of the company's orders on your platform. For example, if a member of the Organisation has set up a direct debit mandate, then any other member of that Organisation can make purchases using the mandate.

In other cases (for larger companies), there may be several Organisations - perhaps one associated to each department in the company. In this case, Users can only see the orders associated with their Organisation.

Authorization

To authentify pass the correct header with each request:

GET /v1/me HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
  --url https://api-sandbox.hokodo.co/v1/me/ \
  --header "Authorization: Token <your_api_key>"

Make sure to replace <your_api_key> with your API key from https://sandbox.hokodo.co.

Use your secret key in your API requests. You can manage your keys in your Developer dashboard. Be sure to keep your key secure and do not share it in publicly-accessible areas, such as GitHub, in your client-side Javascript code, etc.

Authorization to the API is done by providing the key in Authorization header preceded by Token keyword. The API key can also be provided as user with no password through HTTP Basic Auth.

All API requests must be made over HTTPS. Calls made over plain HTTP or without proper authentication will fail.

Testing the API

Please make sure to test your integration thoroughly in our sandbox before going live. After registering, you will be given your test API keys. Those are safe to use for development. When you are ready, make sure to replace those keys with live ones.

While testing, the API will not return real credit approvals and limits. If you want to simulate how well we can cover your clients, please do not hesitate to get in touch with our team at support@hokodo.co.

API versioning

The BNPL API is in version v1. Your feedback is most appreciated for any improvement.

Backwards compatible changes are made regularly to improve the API. You can find the changelog in the partner dashboard.

Pagination

For example to get 10 orders starting with the 51st order:

GET /v1/payment/orders/?limit=10&offset=50 HTTP/1.1
curl --request GET \
  --url https://api-sandbox.hokodo.co/v1/payment/orders/?limit=10&offset=50 \
  --header "Authorization: Token <your_api_key>"

The answer is a JSON looking like this:

{
    "count": 95,  # Total number of orders
    "next": "http://api-sandbox.hokodo.co/v1/payment/orders/?limit=10&offset=60",
    "previous": null,
    "results": [
        {
            ... # 51st order in the list
        },
        {
            ... # 52nd order in the list
        },
        ...
    ]
}

The API returns paginated results, for list endpoints where the response might contain many items in a large list. By default, the number of items returned is 25.

You can control the page size and position by using the query parameters limit and offset. limit controls the number of items displayed, offset the index of the first item of the list, starting from 0. The defaults if no value is passed are thus offset=0 and limit=25.

See examples on the right.

Expansion

For example let's consider the following request:

GET /v1/payment/offers/offer-kEFDnwu8cnkETeagWAcqF4 HTTP/1.1
curl --request GET \
  --url https://api-sandbox.hokodo.co/v1/payment/offers/offer-kEFDnwu8cnkETeagWAcqF4 \
  --header "Authorization: Token <your_api_key>"

It's returning the following JSON response (compacted for the example):

{
    "url": "http://api-sandbox.hokodo.co/v1/payment/offers/offer-kEFDnwu8cnkETeagWAcqF4",
    "id": "offer-kEFDnwu8cnkETeagWAcqF4",
    "order": "order-TiehJCGZmFRkKoL8NsM3d6",
    "status": "accepted",
    ...  # Other payment offer fields
}

We can use ?expand=order for example:

GET /v1/payment/offers/offer-kEFDnwu8cnkETeagWAcqF4?expand=order HTTP/1.1
curl --request GET \
  --url https://api-sandbox.hokodo.co/v1/payment/offers/offer-kEFDnwu8cnkETeagWAcqF4?expand=order \
  --header "Authorization: Token <your_api_key>"

As a response we get:

{
    "url": "http://api-sandbox.hokodo.co/v1/payment/offers/offer-kEFDnwu8cnkETeagWAcqF4",
    "id": "quo-kEFDnwu8cnkETeagWAcqF4",
    "order": {
        "id": "order-TiehJCGZmFRkKoL8NsM3d6",
        ...  # Other order fields
    },
    "status": "accepted",
    ...  # Other payment offer fields
}

The API returns some items as API identifiers. The designated resource can be expanded, meaning that the identifier is replaced in the response with a dictionary representing the resource itself. You can control which field is expanded using the query parameter expand. Expected value is a comma separated list of field names, for example ?expand=order,payment.

Note: At the moment, only read requests can use expansion. You can't use resource expansion for requests where you create and modify resources.

See examples on the right.

Environments

Test environment (aka Sandbox)

Register at: https://sandbox.hokodo.co
API base URL: https://api-sandbox.hokodo.co/

This is the test environment for our API clients, where you can integrate your own software with our API without consequences. It will always run the same version(s), expect the same request format and return the same response format as the production environment.

Data such as credit scores or payment offers will not be real however, and no payment is provided. Non-sensitive data, such as companies search, will be as close as possible to the production data.

Production

Apply at: https://www.hokodo.co/contact
API base URL: https://api.hokodo.co/

This is the live, production environment, where:

Data formats

Countries

Requests

  • buyer countries
GET /v1/countries/debtor HTTP/1.1
curl --request GET \
    --url https://api-sandbox.hokodo.co/v1/countries/debtor

Response

200 Ok
Content-Type: application/json
[
  {
    "code": "GB",
    "name": "United Kingdom"
  },
  {
    "code": "FR",
    "name": "France"
  }
]

Where a country input field is required by the API, you can use either the ISO 3166-1 alpha-2 code or the country's name. See below on how to obtain a full list of accepted countries.

Obtain a list of valid countries for a buyer/customer.

Dates and times

When a date, or date and time field is required by the API, it is expected in ISO 8601 notation, for example:

Type Format Example
Date yyyy-mm-dd 2018-10-31
Datetime yyyy-mm-ddThh:mm:ss.ffffff 2018-10-31T16:53:00.12345
Datetime UTC yyyy-mm-ddThh:mm:ss.ffffffZ 2018-10-31T16:53:00.12345Z

For order issue and due dates for example, there is no time associated and the API expects only a date, no time nor timezone. Be careful if you are internally converting a datetime with timezone to a date, e.g. 2018-10-31T00:00:00+02:00 could become 2018-10-30T22:00:00Z when converted to UTC and then 2018-10-30 in the request to the API, which wouldn't fit the user input.

Currencies

When a currency field is used by the API, it is an ISO 4217 code, such as GBP, EUR or USD.

Amounts

When a money amount is expected or returned by the API, it is always in minor units, ie cents. For example:

Companies

Companies represent the legal entities associated with your customers. To be able to provide accurate credit approval and limits, and payment plans, we need to properly identify the companies.

If you already store a unique company identifier such as a Companies House number (UK) or SIREN (France) then you can use our Companies endpoint to obtain the Hokodo ID for the company.

More commonly, however, merchants simply store a free text name for their customers' companies. Because there can often be many companies with similar sounding names (including different subsidiaries of the same parent), we typically recommend adopting the following process to make sure you are supplying the correct company identifiers:

  1. presenting your user with text box(es), where they can enter their company's name, and/or address, and/or registration number,
  2. using that information in our company search API, to obtain a list of companies which are potential matches to the text you supplied.
  3. asking the user to pick among the choices our company search API has returned.

Companies endpoints

Company object

{
  "url": "https://api-sandbox.hokodo.co/v1/companies/co-bqRyKAGaFrEEN8JMjWJiqk",
  "id": "co-bqRyKAGaFrEEN8JMjWJiqk",
  "name": "Hokodo Ltd",
  "creation_date": "2018-02-20",
  "status": "Active",
  "legal_form": "Private limited with share capital",
  "country": "GB",
  "address": "35 Kingsland Road, London, E2 8AA",
  "city": "London",
  "postcode": "E2 8AA",
  "email": "",
  "phone": "",
  "sectors": [
    {
      "system": "SIC2007",
      "code": "64999"
    },
    {
      "system": "SIC2007",
      "code": "62012"
    },
    {
      "system": "SIC2007",
      "code": "66220"
    }
  ],
  "identifiers": [
    {
      "idtype": "reg_number",
      "country": "GB",
      "value": "11215527"
    }
  ]
}
field type description
url string API endpoint to access the company
id string(uuid) API unique identifier for the company
name string Company name
creation_date date Date of inception of the company
status string Current status of the company. You are generally interested about Active or ACT companies
legal_form string Legal form of the company. The list of possible legal forms varies from country to country.
country country Registered address: country code
address string Registered address: full postal address
city string Registered address: city name
postcode string Registered address: postcode
email string Contact email address for the company
phone string Contact phone number for the company
sectors list The list of sectors the company operate in.
sectors[*][system] string The system of reference to interpret the code (SIC2007 in UK, NAF_2008 in FR)
sectors[*][code] string Sector code in the given system
identifiers list The list of official identifiers know for this company, e.g. Companies House registration number, VAT number, etc.
identifiers[*][id_type] string The type of identifier (reg_number for a registration number, lei for an identifier of the Global LEI System, vat_number for a tax identifier)
identifiers[*][country] country Country in which the identifier is relevant when it applies. Can be blank.
identifiers[*][value] string Identifier

Request

POST /v1/companies/search HTTP/1.1
Content-Type: application/json

{
  "name": "Hokodo Ltd",
  "country": "GB"
}
curl --request POST \
  --url https://api-sandbox.hokodo.co/v1/companies/search \
  --header "Content-Type: application/json" \
  --data-binary '{
    "name": "Hokodo Ltd",
    "country": "GB"
}'

Responses

  • regular response
200 OK
Content-Type: application/json
{
  "matches": [
    {
      "url": "https://api-sandbox.hokodo.co/v1/companies/co-EWzoaRqbvsdq8FW7dB6evL",
      "id": "co-EWzoaRqbvsdq8FW7dB6evL",
      "country": "GB",
      "name": "HOKODO LTD",
      "address": "35 Kingsland Road, London, United Kingdom, E2 8AA",
      "city": "London",
      "postcode": "E2 8AA",
      "legal_form": "",
      "sectors": [],
      "creation_date": "2018-02-20",
      "identifiers": [
        {
          "idtype": "reg_number",
          "country": "GB",
          "value": "11215527"
        }
      ],
      "email": "",
      "phone": "",
      "status": "Undefined",
      "confidence": null
    },
    {
      "url": "https://api-sandbox.hokodo.co/v1/companies/co-JbTDrzejAhRafYrKSFEGi4",
      "id": "co-JbTDrzejAhRafYrKSFEGi4",
      "country": "GB",
      "name": "Hokodo Services Ltd",
      "address": "35 Kingsland Road, London, E2 8AA",
      "city": "London",
      "postcode": "E2 8AA",
      "legal_form": "Private limited with share capital",
      "sectors": [],
      "creation_date": "2018-05-09",
      "identifiers": [
        {
          "idtype": "reg_number",
          "country": "GB",
          "value": "11351988"
        }
      ],
      "email": "",
      "phone": "",
      "status": "Active",
      "confidence": null
    }
  ]
}
  • no results
200 OK
Content-Type: application/json
{
  "matches": []
}
  • error response (country field missing)
{
  "country": [
    "This field is required."
  ]
}
  • error response (name and reg_number fields missing)
400 Bad Request
Content-Type: application/json
{
  "non_field_errors": [
    "Not enough information to identify company. Provide at least country and either name or registration number."
  ]
}

Search for a company by country, name, registration number if available. Country is mandatory, and one of name or registration number must be provided. The API will try to find the best match and return a list of potential matches.

field description requirement
country Country the company is registered in required
name Name of the company required *
reg_number Registration number in country required *
address Address of the company optional

(at least one of fields, marked with * is required)

Errors:

code description
400 a required field is missing

View Company

Request

GET /v1/companies/{company_id} HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request POST \
  --url https://api-sandbox.hokodo.co/v1/companies/{company_id} \
  --header "Authorization: Token <your_api_key>" \
  --header "Content-Type: application/json"

Responses

  • regular response
200 OK
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/companies/co-EWzoaRqbvsdq8FW7dB6evL",
  "id": "co-EWzoaRqbvsdq8FW7dB6evL",
  "country": "GB",
  "name": "HOKODO LTD",
  "address": "35 Kingsland Road, London, United Kingdom, E2 8AA",
  "city": "London",
  "postcode": "E2 8AA",
  "legal_form": "",
  "sectors": [],
  "creation_date": "2018-02-20",
  "identifiers": [
    {
      "idtype": "reg_number",
      "country": "GB",
      "value": "11215527"
    }
  ],
  "email": "",
  "phone": "",
  "status": "Undefined",
}
  • not found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}

Look up a previously found company.

Errors:

code description
404 the company_id is probably invalid, and the company has not been found

Sole traders

Sole Traders represent unregistered entities associated with your customers. To be able to provide accurate credit approval, limits, and payment plans, we need to properly identify the company and the sole trader (proprietor).

Commonly, merchants store a free text name for their customers' sole trading businesses. Because there can often be many sole traders with similar sounding names, and, as unregistered businesses sole traders will generally not have a government issued unique identifier (registered companies will have a registration number for instance) we typically recommend adopting the following process to make sure you are supplying the correct information for sole traders:

  1. presenting your user with text box(es), where they can enter their owner / proprietor's name and address
  2. presenting your user with text boxes where they can enter their company's name and address
  3. using that information to create a SoleTrader on the Hokodo platform

Hokodo require both company and proprietor data to provide servers for the sole trader, without complete data Hokodo will not be able to accurately credit score the company.

By default, only certain types of companies can be offered Buy Now Pay Later by Hokodo. If a significant portion of your users are sole traders, get in touch with us to enable that function for you.

You will be able to create SoleTrader objects, which are an extension of the Company objects.

Sole trader endpoints

SoleTrader object

{
    "id": "co-YuNEQ4nqA6Yto9QQUBnopW",
    "soletrader_id": "st-eE4un8TnDNjx9Uac2DVa6N",
    "owner": "user-sVr7a58Smbfqbo8cVpjEV6",
    "unique_id": "0d201ab1-46df-4274-8c90-256eaa66c135"
    "vat_number": "15141312",
    "trading_name": "The Dogfather 21",
    "trading_address": "123 Commercial St, Shoreditch",
    "trading_address_city": "London",
    "trading_address_postcode": "EC2A 8AB",
    "trading_address_country": "GB",
    "proprietor_name": "John John",
    "proprietor_address_line1": "Flat 5",
    "proprietor_address_line2": "10 Residential Street",
    "proprietor_address_line3": "Hackney",
    "proprietor_address_city": "London",
    "proprietor_address_postcode": "EC2 8AA",
    "proprietor_address_country": "GB",
    "date_of_birth": "1969-12-31"
}
field type flags description
id string(uuid) read-only Unique company identifier for the object. To be used where a Company identifier is required, such as creditor in a transaction.
soletrader_id string(uuid) read-only Unique identifier for the object. To be used where a SoleTrader identifier is required.
owner string(uuid) required Unique identifier of the user associated to the sole trader.
unique_id string required Unique identifier of the sole trader at your platform
vat_number string optional VAT number of the sole trader if available.
trading_name string required Company's name
trading_address string required Company's full address
trading_address_city string required Company's city
trading_address_postcode string required Company's postcode
trading_address_country country required Company's country
proprietor_name string required Proprietor's name
proprietor_address_line1 string required Proprietor's address including house number
proprietor_address_line2 string required Proprietor's address
proprietor_address_line3 string optional Proprietor's address
proprietor_address_city string required Proprietor's city
proprietor_address_postcode string required Proprietor's postcode
proprietor_address_country country required Proprietor's country
date_of_birth date required Proprietor's date of birth (e.g. 1969-12-31). Accepted format: YYYY-MM-DD.

Create a sole trader

Request

POST /v1/soletraders HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "owner": "user-KZcuB2oT6BPTjmQJiHm7ha",
  "trading_name": "The Dogfather",
  "trading_address": "123 Commercial St, Shoreditch",
  "trading_address_city": "London",
  "trading_address_postcode": "EC2A 8AB",
  "trading_address_country": "GB",
  "proprietor_name": "John John",
  "proprietor_address_line1": "Flat 5",
  "proprietor_address_line2": "10 Residential Street",
  "proprietor_address_line3": "Hackney",
  "proprietor_address_city": "London",
  "proprietor_address_postcode": "EC2 8AA",
  "proprietor_address_country": "GB",
  "vat_number": "15141312",
  "unique_id": "0d201ab1-46df-4274-8c90-256eaa66c136",
  "date_of_birth": "1969-12-31"     
}
curl --request POST
  --url https://api-sandbox.hokodo.co/v1/soletraders \
  --header "Authorization: Token <your_api_key>" \
  --header 'Content-Type: application/json' \
  --data-binary "{
    \"owner\": \"user-KZcuB2oT6BPTjmQJiHm7ha\",
    \"trading_name\": \"The Dogfather\",
    \"trading_address\": \"123 Commercial St, Shoreditch\",
    \"trading_address_city\": \"London\",
    \"trading_address_postcode\": \"EC2A 8AB\",
    \"trading_address_country\": \"GB\",
    \"proprietor_name\": \"John John\",
    \"proprietor_address_line1\": \"Flat 5\",
    \"proprietor_address_line2\": \"10 Residential Street\",
    \"proprietor_address_line3\": \"Hackney\",
    \"proprietor_address_city\": \"London\",
    \"proprietor_address_postcode\": \"EC2 8AA\",
    \"proprietor_address_country\": \"GB\",
    \"vat_number\": \"15141312\",
    \"unique_id\": \"0d201ab1-46df-4274-8c90-256eaa66c136\",
    \"date_of_birth\": \"1969-12-31\"
}"

Responses

  • regular response
201 Created
Content-Type: application/json
{
  "id": "co-5oh3SJKQBaKMov9PYR7BkA",
  "owner": "user-mECT3e5n9i7gVGrbn2Pd38",
  "soletrader_id": "st-Vdrisa6GZnSp49ZaqMDssR",
  "trading_name": "The Dogfather",
  "trading_address": "123 Commercial St, Shoreditch",
  "trading_address_city": "London",
  "trading_address_postcode": "EC2A 8AB",
  "trading_address_country": "GB",
  "proprietor_name": "John John",
  "proprietor_address_line1": "Flat 5",
  "proprietor_address_line2": "10 Residential Street",
  "proprietor_address_line3": "Hackney",
  "proprietor_address_city": "London",
  "proprietor_address_postcode": "EC2 8AA",
  "proprietor_address_country": "GB",
  "vat_number": "15141312",
  "unique_id": "0d201ab1-46df-4274-8c90-256eaa66c136",
  "date_of_birth": "1969-12-31"
}
  • error response (example)
400 Bad Request
Content-Type: application/json
{
  "owner": [
    "Invalid pk \"user-KZcuB2oT6BPTjmQJiHm7hb\" - object does not exist."
  ],
  "unique_id": [
    "sole trader with this Unique identifier on platform already exists."
  ]
}

To create a sole trader, you create a SoleTrader object.

Errors

errors description
400 a required field is missing or some fields have incorrect values

List sole traders

Request

POST /v1/soletraders HTTP/1.1
Authorization: Token <your_api_key>
curl --request POST
  --url https://api-sandbox.hokodo.co/v1/soletraders \
  --header "Authorization: Token <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "co-5oh3SJKQBaKMov9PYR7BkA",
      "owner": "user-mECT3e5n9i7gVGrbn2Pd38",
      "soletrader_id": "st-Vdrisa6GZnSp49ZaqMDssR",
      "trading_name": "The Dogfather",
      "trading_address": "123 Commercial St, Shoreditch",
      "trading_address_city": "London",
      "trading_address_postcode": "EC2A 8AB",
      "trading_address_country": "GB",
      "proprietor_name": "John John",
      "proprietor_address_line1": "Flat 5",
      "proprietor_address_line2": "10 Residential Street",
      "proprietor_address_line3": "Hackney",
      "proprietor_address_city": "London",
      "proprietor_address_postcode": "EC2 8AA",
      "proprietor_address_country": "GB",
      "vat_number": "15141312",
      "unique_id": "0d201ab1-46df-4274-8c90-256eaa66c136",
      "date_of_birth": "1969-12-31"
    }
  ]
}

List all sole traders, created by your platform

View sole trader

Request

POST /v1/soletraders/<soletrader_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request POST
  --url https://api-sandbox.hokodo.co/v1/soletraders/co-5oh3SJKQBaKMov9PYR7BkA \
  --header "Authorization: Token <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "id": "co-5oh3SJKQBaKMov9PYR7BkA",
  "owner": "user-mECT3e5n9i7gVGrbn2Pd38",
  "soletrader_id": "st-Vdrisa6GZnSp49ZaqMDssR",
  "trading_name": "The Dogfather",
  "trading_address": "123 Commercial St, Shoreditch",
  "trading_address_city": "London",
  "trading_address_postcode": "EC2A 8AB",
  "trading_address_country": "GB",
  "proprietor_name": "John John",
  "proprietor_address_line1": "Flat 5",
  "proprietor_address_line2": "10 Residential Street",
  "proprietor_address_line3": "Hackney",
  "proprietor_address_city": "London",
  "proprietor_address_postcode": "EC2 8AA",
  "proprietor_address_country": "GB",
  "vat_number": "15141312",
  "unique_id": "0d201ab1-46df-4274-8c90-256eaa66c136",
  "date_of_birth": "1969-12-31"
}

Retrieve a single sole trader, created by your platform

Errors

errors description
404 the soletrader_id is probably invalid, the sole trader has not been found

Modify sole trader

Request

PATCH /v1/soletraders/<soletrader_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "trading_name": "The Catfather",
  "proprietor_name": "Johnny John"
}
curl --request PATCH
  --url https://api-sandbox.hokodo.co/v1/soletraders/co-5oh3SJKQBaKMov9PYR7BkA \
  --header "Authorization: Token <your_api_key>" \
  --header 'Content-Type: application/json' \
  --data-binary "{
    \"trading_name\": \"The Catfather\",
    \"proprietor_name\": \"Johnny John\"
}"

Response

200 Ok
Content-Type: application/json
{
  "id": "co-5oh3SJKQBaKMov9PYR7BkA",
  "owner": "user-mECT3e5n9i7gVGrbn2Pd38",
  "soletrader_id": "st-Vdrisa6GZnSp49ZaqMDssR",
  "trading_name": "The Catfather",
  "trading_address": "123 Commercial St, Shoreditch",
  "trading_address_city": "London",
  "trading_address_postcode": "EC2A 8AB",
  "trading_address_country": "GB",
  "proprietor_name": "Johnny John",
  "proprietor_address_line1": "Flat 5",
  "proprietor_address_line2": "10 Residential Street",
  "proprietor_address_line3": "Hackney",
  "proprietor_address_city": "London",
  "proprietor_address_postcode": "EC2 8AA",
  "proprietor_address_country": "GB",
  "vat_number": "15141312",
  "unique_id": "0d201ab1-46df-4274-8c90-256eaa66c136",
  "date_of_birth": "1969-12-31"  
}

Modify previously created sole trader

Errors

errors description
404 the soletrader_id is probably invalid, the sole trader has not been found
400 a required field is missing or some fields have incorrect values

Organisations

Because Hokodo focuses on B2B sales, the buyers on your platform will consist of Companies, who have employees, and those employees may be organised into teams or departments. Hokodo deals with this complexity through the concept of Organisations and Users. A User is an individual employee at a company. An Organisation is a group of Users who are all able to see or take action on that company's orders on your platform. Each Organisation must be associated with a Company.

User roles within organisations

Users can have one of the following roles in an organisation:

Organisation endpoints

Organisation object

{
  "id": "org-9RxFsXTgnWqwjK4apxBAn8",
  "unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
  "registered": "2017-06-01T14:37:12Z",
  "company": null,
  "users": []
}
field type flags description
id string(uuid) read-only API unique identifier for the organisation
unique_id string required Unique identifier of the organisation on your platform
registered datetime required When the organisation registered on your platform
company string optional Hokodo unique identifier of the company
users list read-only List of users attached to the organisation

Note that registered is the organisation's registration date on your platform, not with Hokodo.

Create an organisation

Request

POST /v1/organisations HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
  "registered": "2017-06-01T14:37:12Z",
  "company": "co-bqRyKAGaFrEEN8JMjWJiqk"
}
curl --request POST
  --url https://api-sandbox.hokodo.co/v1/organisations \
  --header "Authorization: Token <your_api_key>" \
  --header "Content-Type: application/json" \
  --data-binary "{
    \"unique_id\": \"c105b862-f1ba-4197-9d97-57db63196b00\",
    \"registered\": \"2017-06-01T14:37:12Z"\,
    \"company\": \"co-bqRyKAGaFrEEN8JMjWJiqk\"
}"

Responses

  • organisation created successfully
201 Created
Content-Type: application/json
{
  "id": "org-pHr6VCyzQJALUsePkatPBo",
  "unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
  "registered": "2017-06-01T14:37:12Z",
  "company": "co-bqRyKAGaFrEEN8JMjWJiqk",
  "users": []
}
  • organisation already exists (identified by unique_id), it is updated
200 Ok
Content-Type: application/json
{
  "id": "org-pHr6VCyzQJALUsePkatPBo",
  "unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
  "registered": "2017-06-01T14:37:12Z",
  "company": "co-bqRyKAGaFrEEN8JMjWJiqk",
  "users": []
}

To create an organisation, you create an Organisation object.

Errors

errors description
400 a required field is missing or a field has incorrect format

List organisations

Request

GET /v1/organisations HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
  --url https://api-sandbox.hokodo.co/v1/organisations \
  --header "Authorization: Token <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "org-pHr6VCyzQJALUsePkatPBo",
      "unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
      "registered": "2017-06-01T14:37:12Z",
      "company": "co-bqRyKAGaFrEEN8JMjWJiqk",
      "users": []
    }
  ]
}

List organisations created by your platform

View organisation

Request

GET /v1/organisations/<organisation_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
  --url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo \
  --header "Authorization: Token <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "org-pHr6VCyzQJALUsePkatPBo",
      "unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
      "registered": "2017-06-01T14:37:12Z",
      "company": "co-bqRyKAGaFrEEN8JMjWJiqk",
      "users": []
    }
  ]
}

Retrieve an organisation created by your platform

Errors

errors description
404 the organisation_id is probably invalid, the organisation has not been found

Modify organisation

Request

PATCH /v1/organisations/<organisation_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "unique_id": "c105b862-f1ba-4197-9d97-57db63196b01",
  "registered": "2018-06-01T14:37:12Z",
  "company": "co-bqRyKAGaFrEEN8JMjWJiqk"
}
curl --request PATCH
  --url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo \
  --header "Authorization: Token <your_api_key>" \
  --header "Content-Type: application/json" \
  --data-binary "{
    \"unique_id\": \"c105b862-f1ba-4197-9d97-57db63196b01\",
    \"registered\": \"2018-06-01T14:37:12Z"\,
    \"company\": \"co-bqRyKAGaFrEEN8JMjWJiqk\"
}"

Response

200 Ok
Content-Type: application/json
{
  "id": "org-pHr6VCyzQJALUsePkatPBo",
  "unique_id": "c105b862-f1ba-4197-9d97-57db63196b01",
  "registered": "2018-06-01T14:37:12Z",
  "company": "co-bqRyKAGaFrEEN8JMjWJiqk",
  "users": []
}

Modify an organisation created by your platform

Errors

errors description
404 the organisation_id is probably invalid, the organisation has not been found
400 a required field is missing or a field has incorrect format

Delete an organisation

Request

DELETE /v1/organisations/<organisation_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE
  --url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo \
  --header "Authorization: Token <your_api_key>"

Responses

  • regular response
204 No Content
  • can not delete organisation, it has objects attached
409 Conflict
Content-Type: application/json
{
  "detail": "Organisation has undeletable objects attached, it cannot be deleted."
}

Delete an organisation created by your platform. Please note, that you can not delete an organisation that has payment-related objects attached to it (such as deferred payments or offers, etc.)

Errors

errors description
404 the organisation_id is probably invalid, the organisation has not been found
409 an organisation can not be deleted because it has objects attached to it

Manage users in organisation

Our API provides two alternative endpoint collections to manage relation between users and organisations. Below is the list of methods from the perspective of an organisation. For the list of methods from the perspective of a user, please refer to section Manage organisations of user

Organisation users endpoints

Organisation user object

{
  "id": "user-mECT3e5n9i7gVGrbn2Pd38",
  "email": "johnny@hokodo.co",
  "role": "admin"
}
field type flags description
id string(uuid) required API unique identifier for the user
email string read-only Email of the user
role role required Role of the user in the organisation

Add user to organisation

Request

POST /v1/organisations/<organisation_id>/users HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "id": "user-mECT3e5n9i7gVGrbn2Pd38",
  "role": "admin"
}
curl --request POST
  --url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo/users \
  --header "Authorization: Token <your_api_key>" \
  --header "Content-Type: application/json" \
  --data-binary "{
    \"id\": \"user-mECT3e5n9i7gVGrbn2Pd38\",
    \"role\": \"admin"\
}"

Responses

  • regular response
201 Created
Content-Type: application/json
{
  "id": "user-mECT3e5n9i7gVGrbn2Pd38",
  "email": "johnny@hokodo.co",
  "role": "admin"
}
  • user already added to the organisation
200 Ok
Content-Type: application/json
{
  "id": "user-mECT3e5n9i7gVGrbn2Pd38",
  "email": "johnny@hokodo.co",
  "role": "admin"
}
  • error (user not found and/or incorrect user role)
400 Bad Request
Content-Type: application/json
{
  "id": [
    "Invalid pk \"user-mECT3e5n9i7gVGrbn2Pd39\" - object does not exist."
  ],
  "role": [
    "\"reader\" is not a valid choice."
  ]
}

Attach previously created user to the organisation. When a user is already added to the organisation, but a different role is provided in the request, his existing role will be updated.

Users can have one of the following roles in an organisation:

To create a user, see the relevant section.

Errors

errors description
400 a required field is missing or a field has incorrect format

View users of organisation

Request

GET /v1/organisations/<organisation_id>/users HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
  --url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo/users \
  --header "Authorization: Token <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "user-mECT3e5n9i7gVGrbn2Pd38",
      "email": "johnny@hokodo.co",
      "role": "admin"
    }
  ]
}

List all current users of an organisation

View individual user of organisation

Request

GET /v1/organisations/<organisation_id>/users/<user_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
  --url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo/users/user-mECT3e5n9i7gVGrbn2Pd38 \
  --header "Authorization: Token <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "id": "user-mECT3e5n9i7gVGrbn2Pd38",
  "email": "johnny@hokodo.co",
  "role": "admin"
}

Retrieve one specific user of an organisation

Errors

errors description
404 the user_id is probably invalid, the user has not been found

Modify user role in organisation

Request

PATCH /v1/organisations/<organisation_id>/users/<user_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "role": "member"
}
curl --request POST
  --url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo/users/user-mECT3e5n9i7gVGrbn2Pd38 \
  --header "Authorization: Token <your_api_key>" \
  --header "Content-Type: application/json" \
  --data-binary "{
    \"role\": \"member"\
}"

Responses

  • regular response
200 Ok
Content-Type: application/json
{
  "id": "user-mECT3e5n9i7gVGrbn2Pd38",
  "email": "johnny@hokodo.co",
  "role": "member"
}
  • error (incorrect user role)
400 Bad Request
Content-Type: application/json
{
  "role": [
    "\"reader\" is not a valid choice."
  ]
}

Modify the role of a specific user in an organisation

Errors

errors description
400 the role field is missing or has incorrect value

Remove user from organisation

Request

DELETE /v1/organisations/<organisation_id>/users/<user_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE
  --url https://api-sandbox.hokodo.co/v1/organisations/org-pHr6VCyzQJALUsePkatPBo/users/user-mECT3e5n9i7gVGrbn2Pd38 \
  --header "Authorization: Token <your_api_key>"

Response

204 No Content

Remove one specific user from the organisation

Errors

errors description
404 the user_id is probably invalid, the user has not been found

Users

Users represent the individual customers on your platform. They are associated to one or multiple organisations, which themselves represent the company of these customers. A user can have different roles and permissions in each organisation.

Users not linked to an organisation cannot access orders, payment offers or deferred payments. Therefore, we suggest creating the organisation first, then create users linked to the organisation with the proper role.

User endpoints

User object

{
  "id": "user-VG4i93EPLRamVFK6oXpvt9",
  "email": "johnny@hokodo.co",
  "unique_id": "",
  "name": "John",
  "phone": "",
  "registered": "2017-06-01T14:37:12Z",
  "organisations": [
    {
      "id": "org-FEjrdMsmhdNp34HxaZ6n63",
      "role": "member"
    }
  ]
}
field type flags description
id string(uuid) read-only API unique identifier for the user
email string required Email of the user
unique_id string optional Unique identifier of the user on your platform (currently we don't validate its uniqueness and store it for your reference only)
name string required Full name of the user
phone string optional Phone number of the user
registered datetime required Date of user registration on your platform
organisations list optional List of organisations to which the user is linked (can be empty)
organisations[*][id] string(uuid) required API identifier of the organisation
organisations[*][role] role required Role of the user in the organisation

Note that registered is the user's registration date on your platform, not with Hokodo.

Create a user

Request

POST /v1/users HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "name": "John",
  "email": "johnny@hokodo.co",
  "registered": "2017-06-01T14:37:12Z",
  "organisations": [
    {
      "id": "org-FEjrdMsmhdNp34HxaZ6n63",
      "role": "member"
    }
  ]
}
curl --request POST \
  --url https://api-sandbox.hokodo.co/v1/users \
  --header "Authorization: Token <your_api_key>"
  --header "Content-Type: application/json"
  --data-binary="{
    \"name\": \"John\",
    \"email\": \"johnny@hokodo.co\",
    \"registered\": \"2017-06-01T14:37:12Z\",
    \"organisations\": [
      {
        \"id\": \"org-FEjrdMsmhdNp34HxaZ6n63\",
        \"role\": \"member\"
      }
    ]
}"

Response

  • regular response
201 Created
Content-Type: application/json
{
  "id": "user-VG4i93EPLRamVFK6oXpvt9",
  "email": "johnny@hokodo.co",
  "unique_id": "",
  "name": "John",
  "phone": "",
  "registered": "2017-06-01T14:37:12Z",
  "organisations": [
    {
      "id": "org-FEjrdMsmhdNp34HxaZ6n63",
      "role": "member"
    }
  ]
}
  • error response
400 Bad Request
Content-Type: application/json
{
  "email": [
    "This field is required."
  ],
  "name": [
    "This field is required."
  ],
  "registered": [
    "This field is required."
  ]
}

To create a user, you create a User object.

Note: Repeated POST requests with user information that contains the same email address will trigger partial updates on the existing user. Any organisations in this list will be appended to the list of organisations the user is already a member of. If the list includes an organisation the user is currently a member of, but with a different role, the user's role will be updated to the latest received.

errors description
400 a required field is missing

List users

Request

GET /v1/users HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
  --url https://api-sandbox.hokodo.co/v1/users \
  --header "Authorization: Token <your_api_key>"

Response

200 OK
Content-Type: application/json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "user-mECT3e5n9i7gVGrbn2Pd38",
      "email": "johnny@hokodo.co",
      "unique_id": "",
      "name": "John",
      "phone": "",
      "registered": "2017-06-01T14:37:12Z",
      "organisations": [
        {
          "id": "org-FEjrdMsmhdNp34HxaZ6n63",
          "role": "member"
        }
      ]
    }
  ]
}

List all users associated with your platform.

Get user

Request

GET /v1/users/<user_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
  --url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38 \
  --header "Authorization: Token <your_api_key>"

Response

  • regular response
200 OK
Content-Type: application/json
{
  "id": "user-mECT3e5n9i7gVGrbn2Pd38",
  "email": "johnny@hokodo.co",
  "unique_id": "",
  "name": "John",
  "phone": "",
  "registered": "2017-06-01T14:37:12Z",
  "organisations": [
    {
      "id": "org-FEjrdMsmhdNp34HxaZ6n63",
      "role": "member"
    }
  ]
}
  • user not found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}

Look up a previously created user.

errors description
404 the user_id is probably invalid, the user has not been found

Modify user

Request

PATCH /v1/users/<user_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "id": "user-mECT3e5n9i7gVGrbn2Pd38",
  "email": "johnny@hokodo.co",
  "unique_id": "some-unique-id",
  "name": "Johnny",
  "phone": "+1234567890",
  "registered": "2018-06-01T14:37:10Z"
}

Response

200 OK
Content-Type: application/json
{
  "id": "user-mECT3e5n9i7gVGrbn2Pd38",
  "email": "johnny@hokodo.co",
  "unique_id": "some-unique-id",
  "name": "Johnny",
  "phone": "+1234567890",
  "registered": "2018-06-01T14:37:10Z",
  "organisations": [
    {
      "id": "org-FEjrdMsmhdNp34HxaZ6n63",
      "role": "member"
    }
  ]
}

Update a previously created user.

Please note that the organisations list appends to the user's existing organisations list. Supplying an existing organisation in the list will update the user's role on that organisation.

errors description
404 the user_id is probably invalid, the user has not been found
400 updating a user failed or some of the fields have incorrect format

Delete user

Request

DELETE /v1/users/<user_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE \
  --url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38 \
  --header "Authorization: Token <your_api_key>"

Response

  • regular response
204 No Content
  • user not found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}

Delete a previously created user.

Errors

errors description
404 the user_id is probably invalid, the user has not been found

Manage organisations of user

You can manage users' memberships and roles in various organisations. Please refer to section Organisations regarding creating and managing organisations.

Our API provides two alternative endpoint collections to manage relations between users and organisations. Below is the list of methods from the perspective of a user. For the list of methods from the perspective of an organisation, please refer to section Manage users in organisation

User organisations endpoints

User organisation object

{
  "id": "org-pHr6VCyzQJALUsePkatPBo",
  "role": "admin"
}
field type flags description
id string(uuid) required API unique identifier for the organisation
role role required Role of the user in the organisation

Add user to organisation

Request

POST /v1/users/<user_id>/organisations HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "id": "org-pHr6VCyzQJALUsePkatPBo",
  "role": "admin"
}
curl --request POST
  --url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38/organisations \
  --header "Authorization: Token <your_api_key>" \
  --header "Content-Type: application/json" \
  --data-binary "{
    \"id\": \"org-pHr6VCyzQJALUsePkatPBo\",
    \"role\": \"admin"\
}"

Responses

  • regular response
201 Created
Content-Type: application/json
{
  "id": "org-pHr6VCyzQJALUsePkatPBo",
  "role": "admin"
}
  • user already added to the organisation
200 Ok
Content-Type: application/json
{
  "id": "org-pHr6VCyzQJALUsePkatPBo",
  "role": "admin"
}
  • error (organisation not found and/or incorrect user role)
400 Bad Request
Content-Type: application/json
{
  "id": [
    "Invalid pk \"org-mECT3e5n9i7gVGrbn2Pd39\" - object does not exist."
  ],
  "role": [
    "\"reader\" is not a valid choice."
  ]
}

Attach existing user to a previously created organisation. When a user is already added to the organisation, but a different role is provided in the request, his existing role will be updated.

To create a user, see the relevant section.

Errors

errors description
400 a required field is missing or a field has incorrect format

View organisations of a user

Request

GET /v1/users/<user_id>/organisations HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
  --url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38/organisations \
  --header "Authorization: Token <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "org-pHr6VCyzQJALUsePkatPBo",
      "role": "admin"
    }
  ]
}

List all organisations of a user

View individual organisation of user

Request

GET /v1/users/<user_id>/organisations/<organisation_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET
  --url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38/organisations/org-pHr6VCyzQJALUsePkatPBo \
  --header "Authorization: Token <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "id": "org-pHr6VCyzQJALUsePkatPBo",
  "role": "admin"
}

Retrieve one specific organisation of a user

Errors

errors description
404 the organisation_id is probably invalid, the organisation has not been found

Modify user role in organisation

Request

PATCH /v1/users/<user_id>/organisations/<organisation_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "role": "member"
}
curl --request POST
  --url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38/organisations/org-pHr6VCyzQJALUsePkatPBo \
  --header "Authorization: Token <your_api_key>" \
  --header "Content-Type: application/json" \
  --data-binary "{
    \"role\": \"member"\
}"

Responses

  • regular response
200 Ok
Content-Type: application/json
{
  "id": "org-pHr6VCyzQJALUsePkatPBo",
  "role": "member"
}
  • error (incorrect user role)
400 Bad Request
Content-Type: application/json
{
  "role": [
    "\"reader\" is not a valid choice."
  ]
}

Modify the role of the user in a specific organisation

Errors

errors description
400 the role field is missing or has incorrect value

Remove user from organisation

Request

DELETE /v1/users/<user_id>/organisations/<organisation_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE
  --url https://api-sandbox.hokodo.co/v1/users/user-mECT3e5n9i7gVGrbn2Pd38/organisations/org-pHr6VCyzQJALUsePkatPBo \
  --header "Authorization: Token <your_api_key>"

Response

204 No Content

Remove the user from a specific organisation

Errors

errors description
404 the organisation_id is probably invalid, the organisation has not been found

Credit Limits

Depending on the customer's company, the history of their orders and repayments, Hokodo can offer them deferred payments.

There are two situations where you might want to check whether one of your customers can obtain credit.

  1. Your customer is at the checkout, and you want to check if that particular purchase is eligible for deferred payment. To do that, you use the Orders endpoint to inform Hokodo about the purchase, and the Payment Offers endpoint to check eligibility of the Order.

  2. Your customer has not decided what they want to purchase, but you may wish to proactively inform them that they will be eligible for Deferred Payment. For example, you could display a banner at the top of the page with their credit limit or perhaps add a credit limit section to their "My Account" page. The CreditLimit endpoint is designed for this second situation.

To find out your customer's credit limit, please use the following endpoint, with the associated customer Company in the URL.

POST /v1/payment/credit_limits/company/<company_id>

You will get one of the two possible responses:

Credit limits endpoint

Credit limit object

{
    "company": "co-74cgmhG9U79oTWGEW4jeDW",
    "status": "eligible",
    "rejection_reason": null,
    "credit_limit": {
        "currency": "GBP",
        "amount_available": "987654",
        "amount_in_use": "123456",
        "amount": "1111110",
    }
}
field type description
company string(uuid) API unique identifier for the company
status string Current credit approval status (eligible or declined)
rejection_reason dictionary If status is declined, details about why, otherwise null
credit_limit dictionary Current credit limit if approved
credit_limit[currency] currency ISO 4217 currency code (e.g. GBP, EUR)
credit_limit[amount_available] int Credit limit currently available
credit_limit[amount_in_use] int Credit limit currently in use
credit_limit[amount] int Total credit limit

Please note that in general the amount will equal amount_available plus amount_in_use.

Therefore, it’s better to only share amount_available and amount_in_use with the customer.

Request company credit limit

Requests

POST /v1/payment/credit_limits/company/co-74cgmhG9U79oTWGEW4jeDW/ HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "currency": "GBP"
}
curl --request POST \
  --url https://api-sandbox.hokodo.co/v1/payment/credit_limits/company/co-74cgmhG9U79oTWGEW4jeDW/ \
  --header "Authorization: Token <your_api_key>" \
  --header "Content-Type: application/json" \
  --data-binary '{
  "currency": "GBP"
}'

Responses

  • eligible
200 OK
Content-Type: application/json
{
    "company": "co-74cgmhG9U79oTWGEW4jeDW",
    "status": "eligible",
    "rejection_reason": null,
    "credit_limit": {
        "currency": "GBP",
        "amount_available": "987654",
        "amount_in_use": "123456",
        "amount": "1111110",
    }
}
  • declined
200 OK
Content-Type: application/json
{
    "company": "co-74cgmhG9U79oTWGEW4jeDW",
    "status": "declined",
    "rejection_reason": {
      "code": "buyer-country",
      "detail": "We're currently unable to provide payment plans to Buyers domiciled in {debtor_country}.",
      "params": {
        "debtor_country": "Ireland",
      }
    },
    "credit_limit": {
        "currency": "GBP",
        "amount_available": null,
        "amount_in_use": "123456",
        "amount": null,
    }
}

The currency is optional in the request, and defaults to EUR if not provided.

It is advisable to request the credit limit in the currency used by the company in question. For example, use "currency": "GBP" when requesting the credit limit of a UK company.

field description requirement
currency currency Desired currency for the credit limit, as a ISO 4217 currency code (e.g. GBP, EUR)

Errors

errors description
400 A field is not in the expected format

Credit Limits (Legacy)

Depending on the customer's company, the history of their orders and repayments, Hokodo can offer them deferred payments.

There are two situations where you might want to check whether one of your customers can obtain credit.

  1. Your customer is at the checkout, and you want to check if that particular purchase is eligible for deferred payment. To do that, you use the Orders endpoint to inform Hokodo about the purchase, and the Payment Offers endpoint to check eligibility of the Order.

  2. Your customer has not decided what they want to purchase, but you may wish to proactively inform them that they will be eligible for Deferred Payment. For example, you could display a banner at the top of the page with their credit limit or perhaps add a credit limit section to their "My Account" page. The CreditLimit endpoint is designed for this second situation.

To find out your customer's credit limit, please use the following endpoint, with the associated customer Company in the URL.

GET /v1/payment/credit_limits/company/<company_id>

You will get one of the two possible responses:

CreditLimit endpoints

CreditLimit object

{
    "company": "co-74cgmhG9U79oTWGEW4jeDW",
    "status": "eligible",
    "current_credit_limit": {
        "currency": "GBP",
        "amount": 200000,
        "amount_in_use": 99700,
        "amount_available": 100300,
    },
    "credit_limit_history": [
        {
            "valid_from": "2020-07-16T08:44:49.059Z",
            "valid_to": null,
            "currency": "GBP",
            "amount": 200000
        },
        {
            "valid_from": "2020-06-02T09:12:34.059Z",
            "valid_to": "2020-07-16T08:44:49.059Z",
            "currency": "GBP",
            "amount": 150000
        },
        {
            "valid_from": "2020-05-18T18:18:18.059Z",
            "valid_to": "2020-06-02T09:12:34.059Z",
            "currency": "GBP",
            "amount": 100000
        }
    ]
}
field type flags description
company string(uuid) required API unique identifier of the associated company
status string read-only Current credit approval status (eligible or declined)
current_credit_limit dictionary read-only Current credit limit if approved
current_credit_limit[currency] string read-only ISO 4217 currency code (e.g. GBP, EUR)
current_credit_limit[amount] int read-only Total credit limit available, in cents
current_credit_limit[amount_in_use] int read-only Credit limit currently in use by deferred payments, in cents
current_credit_limit[amount_available] int read-only Credit limit currently available, in cents
credit_limit_history list read-only Current credit limit if approved
credit_limit_history[*][currency] string read-only ISO 4217 currency code (e.g. GBP, EUR)
credit_limit_history[*][amount] int read-only Total credit limit available, in cents
credit_limit_history[*][valid_from] date read-only From when the historical credit limit was valid
credit_limit_history[*][valid_to] date read-only Until when the historical credit limit was valid

Request a new Credit approval and limit

Request

GET /v1/payment/credit_limits/company/{company_id} HTTP/1.1
Content-Type: application/json
curl --request GET \
  --url https://api-sandbox.hokodo.co/v1/payment/credit_limits/company/{company_id} \
  --header "Content-Type: application/json"

Responses

  • Customer rejected
200 OK
Content-Type: application/json
{
    "company": "co-74cgmhG9U79oTWGEW4jeDW",
    "status": "declined",
    "current_credit_limit": null,
    "credit_limit_history": []
}
  • Customer accepted
200 OK
Content-Type: application/json
{
    "company": "co-74cgmhG9U79oTWGEW4jeDW",
    "status": "eligible",
    "current_credit_limit": {
        "currency": "GBP",
        "amount": 200000,
        "amount_in_use": 99700,
        "amount_available": 100300,
    },
    "credit_limit_history": [
        {
            "valid_from": "2020-07-16T08:44:49.059Z",
            "valid_to": null,
            "currency": "GBP",
            "amount": 200000
        },
        {
            "valid_from": "2020-06-02T09:12:34.059Z",
            "valid_to": "2020-07-16T08:44:49.059Z",
            "currency": "GBP",
            "amount": 150000
        },
        {
            "valid_from": "2020-05-18T18:18:18.059Z",
            "valid_to": "2020-06-02T09:12:34.059Z",
            "currency": "GBP",
            "amount": 100000
        }
    ]
}

This endpoint is used to query credit approval and credit limits for your customer. The only required field is company, in the URL.

It returns:

field type flags description
company string(uuid) required API unique identifier of the customer company queried

Orders

An order describes an instance of buying or selling something on your platform. An order consists of a basket of order items, plus details about the company making the purchase. Orders can be paid for at the time of the order or benefit from credit terms.

Orders serve two purposes in an integration with Hokodo:

a) Orders can be used to inform Hokodo about purchases the customer has made on your platform which Hokodo was not involved in. For example, you may have given the customer trade credit in the past, which has been successfully settled. Or the customer may have made purchases which were settled upfront (e.g. paid by card). Both of these are indicators which enhance our confidence that this is a genuine client and are favourable risk indicators. So providing Hokodo with data on these orders helps us to assess the customer's creditworthiness and to set the right credit limits for them.

b) You will also create an order when a customer shops on your platform so that you can obtain Deferred Payment Offers from Hokodo.

As we explain below, there are some commonalities between use cases a) and b) – for example in both cases we need to know who the buyer was, the value of the order, the date of the order etc. But there are also some differences. For example when you inform us about historical orders, you would tell us what payment terms were involved, whereas when you create an order for the purposes of getting deferred payment offers, Hokodo will be determining the payment terms via the offers we return.

Having more of the orders of the customers allows us to provide finer and higher credit limits, as well as reduce fraud.

Order endpoints

Order Documents

There are also post-sale order endpoints described in a dedicated section:

Order object

{
  "url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "organisation": "org-...",
    "user": "user-...",
    "type": "registered" / "guest"
    "delivery_address": {
      "name": "John Smith",
      "company_name": "",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "address_line3": "",
      "city": "London",
      "region": "",
      "postcode": "SE11 6NQ",
      "country": "GB",
      "phone": "",
      "email": ""
    },
     "invoice_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "city": "London",
      "postcode": "SE11 6NQ",
      "country": "GB"
    },
  },
  "status": "pending",
  "pay_method": "directdebit",
  "currency": "GBP",
  "total_amount": 12000,  # total amount including tax
  "tax_amount": 2000,  # tax amount
  "order_date": "2018-04-25",
  "invoice_date": "2018-04-25",
  "due_date": "2018-05-25",
  "paid_date": "2018-05-27",
  "items": [
    {
      "item_id": "1",
      "type": "product",  # or discount, shipping, etc.
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "supplier_name": "Cool chair wholesaler",
      "quantity": "10.000",
      "unit_price": 1000,  # includes tax
      "tax_rate": "20.00",
      "total_amount": 10000,
      "tax_amount": 2000,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 400,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    }
  ],
  "metadata": {}  # store key-values for your internal references
  "po_number": "P-45612",
  "payment_offer": null,
  "deferred_payment": null,
}

The Order object contains many fields that are optional for historical orders. See below for an example of a minimal historical order.

field type flags description
url string read-only API endpoint to access the order
id string(uuid) read-only API unique identifier for the order
unique_id string required Unique identifier of the order in your platform
customer dictionary required Customer making the order (see guest/registered users)
customer[type] string required "registered" or "guest"
customer[organisation] string(uuid) required API unique identifier of the organisation of the customer (if registered) (can be expanded to a full Organisation object)
customer[user] string(uuid) required API unique identifier of the user of the customer (if registered) (can be expanded to a full User object)
customer[delivery_address] dictionary required Delivery/shipping address for this order. See Addresses for a description of the fields
customer[invoice_address] dictionary required Invoice (or Billing) address for this order. See Addresses for a description of the fields
status string required Order status
pay_method string optional Used to supply the Payment method, only if the order has already been paid without Hokodo
currency currency required Currency of order amounts
tax_amount int required Total amount of the taxes, in minor units (cents)
total_amount int required Total amount including tax, in minor units (cents)
order_date date required Date of the order
invoice_date date optional Date of issuance of the invoice, if different from order date
due_date date optional Date due of the order (assuming the customer was given credit terms – if no credit terms were offered, then this would simply be the order_date)
paid_date date optional Date when the order was paid in full (assuming credit terms were offered – otherwise this would simply be the order_date)
items list required The list of items that constitute the order
items[*][item_id] string required Your identifier for this line of the order, e.g. 1, 2, 3...
items[*][type] string required Type of the item. Can be one of the following: product, service, digital, shipping, fee, discount
items[*][description] string required Description of the item
items[*][metadata] dictionary optional Key-value pairs attached to the item, for example describing the color, variant, specific options, to help identify the item post-sale
items[*][reference] string optional Item reference number, SKU, etc.
items[*][category] string optional Category of the item, as per owner's internal classification
items[*][supplier_id] string optional An id of the supplier of the items (if applicable), can be your internal identifier of the supplier, for example "152"
items[*][supplier_name] string optional The name of the supplier of the items (if applicable)
items[*][quantity] decimal required Number of items in the order
items[*][unit_price] int required Price of a single unit, including tax, in minor units (cents)
items[*][tax_rate] decimal required Tax rate on this item, in percent (e.g. "19.50" for 19.5%)
items[*][tax_amount] int required Amount of the tax for this item, in minor units (cents)
items[*][total_amount] int required Total amount for this item, including tax, in minor units (cents)
items[*][fulfilled_quantity] decimal read-only Number of items fulfilled
items[*][fulfillment_info] list read-only Information about shipping of the items (see section Fulfillment)
items[*][fulfillment_info][*][quantity] decimal read-only Number of items in the shipment
items[*][fulfillment_info][*][shipping_id] string read-only Tracking id when the item has shipped (add when shipped)
items[*][fulfillment_info][*][shipping_provider] string read-only Name of the shipping provider (add when shipped)
items[*][cancelled_quantity] decimal read-only Number of items cancelled
items[*][cancelled_info] list read-only Information about cancellation of the items (see section Cancellation)
items[*][cancelled_info][*][quantity] decimal read-only Quantity of items cancelled
items[*][cancelled_info][*][total_amount] string read-only Total value of items cancelled
items[*][cancelled_info][*][tax_amount] string read-only Total tax amount of items cancelled
items[*][returned_quantity] decimal read-only Number of items returned
items[*][returned_info] list read-only Information about items returned (see section Returns)
items[*][returned_info][*][quantity] decimal read-only Number of items returned
items[*][returned_info][*][total_amount] string read-only Total value of items returned
items[*][returned_info][*][tax_amount] string read-only Total tax amount of items returned
metadata dictionary optional Set of key-value pairs you can attach to the object. You can use this to store your custom data in the object and read it back later.
po_number string optional Purchase order number from the customer (for their benefit, as reference)
payment_offer string(uuid) read-only API unique identifier for the deferred payment offer (if created, can be expanded to a full Payment Offer object)
deferred_payment string(uuid) read-only API unique identifier for the deferred payment in place (if created, can be expanded to a full Deferred payment object)

Order status

The order status must be one of:

On draft orders

Draft order status can be used for orders that the user has not yet committed to, e.g. they put something in their cart but did not yet complete the checkout. If the customer goes on to pay via a payment method other than Hokodo Deferred Payment (e.g. they pay by card) then you should amend the order status to paid. In this case the paid order becomes part of the payment history that Hokodo can take into account when assessing this customer for Deferred Payment in the future.

If the customer abandons the checkout and so never completes the purchase, then the order will remain in draft status, and so we will know not to include it in any analysis of the customer's historical payment behaviour.

If the customer ends up completing the purchase using a Hokodo Deferred Payment, then we will automatically move the status to unpaid, and ultimately to paid.

Payment method

The payment_method must be one of:

Please contact us to add more payment methods for purchases not made via Hokodo, to match closely your platform. This information helps us to provide finer and higher credit limits.

Guest users / registered users

Hokodo needs to identify the customer and their company to be able to provide deferred payments, whether they are a registered and logged-in user on your platform, or they are a guest user making a single purchase.

Both cases require a User and Organisation. For registered users, this will be a one-time creation. For guests users, you can re-use a User and Organisation you have already created, or create a fresh one each time.

This flow will work the same for both guest users and registered users:

  1. Create User with the email address of the user (which may be an unverified email address for guest customers)

  2. User uniqueness on Hokodo's side is based on email address. If we detect that they have already been registered as a User on your platform, Hokodo API will return the existing user and identifier, complete with links to Organisation and Company saved before.

  3. If no organisation was linked to the user, or they wish to link a different one, search and identify the company via company search.

  4. Create the Organisation linked to that Company.

  5. Attach the User to the Organisation.

Registered user

If the customer is a registered user on your platform, you should create or have created an Organisation (to represent their team / company), and a User (to represent the individuals within that team / company). Then, use that organisation and user in the customer field of the Order.

Registered user

  "customer": {
    "organisation": "...",
    "user": "...",
    "type": "registered",
    "delivery_address": {
      ...
    }
  }

Guest user

If the customer is a guest user, and has not registered on your platform, you should collect some information to help us identify the customer, and create a User and Organisation in the same way as for registered user. When you create the User object, Hokodo may return an existing User object, if you had previously created a User with the same email address. In that case, it may also have the correct Organisation filled in already.

Guest user

  "customer": {
    "organisation": "...",
    "user": "...",
    "type": "guest",
    "delivery_address": {
      ...
    }
  }

Addresses

{
  "name": "John Smith",
  "company_name": "",
  "address_line1": "1 Station Street",
  "address_line2": "Flat B",
  "address_line3": "",
  "city": "London",
  "region": "",
  "postcode": "SE11 6NQ",
  "country": "GB",
  "phone": "",
  "email": ""
}

The fields used in addresses are:

field type flags description
name string required Full name
company_name string optional (for delivery) Name of the company for delivery if it differs from the legal entity's name
address_line1 string required Line 1 of the address
address_line2 string optional Line 2 of the address
address_line3 string optional Line 3 of the address
city string required City
region string optional State or Region
postcode string required Postal/ZIP code
country country required Country code
phone string optional Phone number associated to the address (eg to handle delivery)
email string optional Email associated to the address (eg to handle delivery notifications)

Create order

Requests

  • minimal historical order of a registered user
POST /v1/payment/orders HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "registered",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "city": "London",
      "postcode": "SE11 6NQ",
      "country": "GB"
    },
    "invoice_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "city": "London",
      "postcode": "SE11 6NQ",
      "country": "GB"
    },
  },
  "status": "paid",
  "currency": "GBP",
  "total_amount": 12000,
  "tax_amount": 2000,
  "order_date": "2018-04-25",
  "invoice_date": "2018-04-25",
  "due_date": "2018-05-25",
  "paid_date": "2018-06-10",
  "pay_method": "directdebit"
}
curl --request POST \
     --url https://api-sandbox.hokodo.co/v1/payment/orders \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>" \
     --data-binary '{
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "registered",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "city": "London",
      "postcode": "SE11 6NQ",
      "country": "GB"
    },
     "invoice_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "city": "London",
      "postcode": "SE11 6NQ",
      "country": "GB"
    },
  },
  "status": "paid",
  "currency": "GBP",
  "total_amount": 12000,
  "tax_amount": 2000,
  "order_date": "2018-04-25",
  "invoice_date": "2018-04-25",
  "due_date": "2018-05-25",
  "paid_date": "2018-06-10",
  "pay_method": "directdebit"
}'
  • new order of a registered user
POST /v1/payment/orders HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "registered",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "city": "London",
      "postcode": "SE11 6NQ",
      "country": "GB"
    },
  },
  "status": "draft",
  "currency": "GBP",
  "total_amount": 12000,
  "tax_amount": 2000,
  "order_date": "2018-04-25",
  "items": [
    {
      "item_id": "1",
      "type": "product",
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "quantity": "10.000",
      "unit_price": 1000,
      "tax_rate": "20.00",
      "total_amount": 10000,
      "tax_amount": 2000,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 400,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    }
  ],
  "metadata": {
    "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
    "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
  }
}
curl --request POST \
     --url https://api-sandbox.hokodo.co/v1/payment/orders \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>" \
     --data-binary '{
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "registered",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "city": "London",
      "postcode": "SE11 6NQ",
      "country": "GB"
    },
  },
  "status": "draft",
  "currency": "GBP",
  "total_amount": 12000,
  "tax_amount": 2000,
  "order_date": "2018-04-25",
  "items": [
    {
      "item_id": "1",
      "type": "product",
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "quantity": "10.000",
      "unit_price": 1000,
      "tax_rate": "20.00",
      "total_amount": 10000,
      "tax_amount": 1667
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 333
    }
  ],
  "metadata": {
    "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
    "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
  }
}'
  • new order of a guest user
POST /v1/payment/orders HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "guest",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "city": "London",
      "postcode": "SE11 6NQ",
      "country": "GB"
    },
  },
  "status": "draft",
  "currency": "GBP",
  "total_amount": 12000,
  "tax_amount": 2000,
  "order_date": "2018-04-25",
  "items": [
    {
      "item_id": "1",
      "type": "product",
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "quantity": "10.000",
      "unit_price": 1000,
      "tax_rate": "20.00",
      "total_amount": 10000,
      "tax_amount": 2000,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 400,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    }
  ],
  "metadata": {
    "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
    "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
  }
}
curl --request POST \
     --url https://api-sandbox.hokodo.co/v1/payment/orders \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>" \
     --data-binary '{
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "registered",
    "company": "org-QdKZ5mdD8BrG5CKxGok2Q4",
    "email": "john@example.com",
    "name": "John Smith",
    "phone": "+44 123 456 7890",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "city": "London",
      "postcode": "SE11 6NQ",
      "country": "GB"
    },
  },
  "status": "draft",
  "currency": "GBP",
  "total_amount": 12000,
  "tax_amount": 2000,
  "order_date": "2018-04-25",
  "items": [
    {
      "item_id": "1",
      "type": "product",
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "quantity": "10.000",
      "unit_price": 1000,
      "tax_rate": "20.00",
      "total_amount": 10000,
      "tax_amount": 1667
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 333
    }
  ],
  "metadata": {
    "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
    "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
  }
}'

Responses

  • success response
201 Created
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "unique_id": "48b0ce9a-f8a3-4dff-be56-26af747b3d98",
  "customer": {
    "type": "registered",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "address_line3": "",
      "city": "London",
      "region": "",
      "postcode": "SE11 6NQ",
      "country": "GB",
      "phone": "",
      "email": ""
    },
  },
  "status": "draft",
  "currency": "GBP",
  "pay_method": "",
  "total_amount": 12000,
  "tax_amount": 2000,
  "order_date": "2018-04-25",
  "invoice_date": null,
  "due_date": null,
  "paid_date": null,
  "items": [
    {
      "item_id": "1",
      "type": "product",
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "supplier_name": "",
      "quantity": "10.000",
      "unit_price": 1000,
      "tax_rate": "20.00",
      "total_amount": 10000,
      "tax_amount": 2000,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null,
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "metadata": {},
      "reference": "",
      "category": "",
      "supplier_id": "",
      "supplier_name": "",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 400,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null,
    }
  ],
  "metadata": {
    "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
    "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
  },
  "payment_offer": null,
  "deferred_payment": null
}
  • error response (example)
400 Bad Request
Content-Type: application/json
{
  "organisation": [
    "Invalid pk \"org-AgBGknk7D8KixY2ntbJtmA\" - object does not exist."
  ],
  "user": [
    "Bad prefix. Expected a UUID prefixed by \"user\", but got xyz."
  ],
  "items": [
    {
      "total_amount": "Item 1 unit_price [1084] and quantity [10.000] does not match total_amount [13010]."
    }
  ]
}

To create an order, you create an Order object.

Many fields are optional. However, to obtain a Deferred Payment Offer later the system must be provided with the following information at least:

The more information is provided at order creation, the more accurate the Payment Offer Hokodo can provide, and the less friction there will be for your customer later on to complete the purchase.

Errors

errors description
400 a required field is missing or some of the fields have incorrect value

List orders

Request

GET /v1/payment/orders HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/orders \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-yQKxbtCg9aTS5JYnsRVA9B",
      "id": "order-yQKxbtCg9aTS5JYnsRVA9B",
      "unique_id": "48b0ce9a-f8a3-4dff-be56-26af747b3d98",
      "customer": {
        "type": "registered",
        "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
        "user": "user-nNqgg5AFymQMumaU7EdrLa",
        "delivery_address": {
          "name": "John Smith",
          "address_line1": "1 Station Street",
          "address_line2": "Flat B",
          "address_line3": "",
          "city": "London",
          "region": "",
          "postcode": "SE11 6NQ",
          "country": "GB",
          "phone": "",
          "email": ""
        },
      },
      "status": "draft",
      "currency": "GBP",
      "pay_method": "",
      "total_amount": 12000,
      "tax_amount": 2000,
      "order_date": "2018-04-25",
      "invoice_date": null,
      "due_date": null,
      "paid_date": null,
      "items": [
        {
          "item_id": "1",
          "type": "product",
          "description": "Super ergonomic chair",
          "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
          "reference": "702.611.50",
          "category": "Furniture > Chairs",
          "supplier_id": "7363",
          "supplier_name": "",
          "quantity": "10.000",
          "unit_price": 1000,
          "tax_rate": "20.00",
          "total_amount": 10000,
          "tax_amount": 2000,
          "fulfilled_quantity": 0,
          "fulfillment_info": null,
          "cancelled_quantity": 0,
          "cancelled_info": null,
          "returned_quantity": 0,
          "returned_info": null
        },
        {
          "item_id": "2",
          "type": "shipping",
          "description": "Delivery fee",
          "metadata": {},
          "reference": "",
          "category": "",
          "supplier_id": "",
          "supplier_name": "",
          "quantity": "1.000",
          "unit_price": 2000,
          "tax_rate": "20.00",
          "total_amount": 2000,
          "tax_amount": 400,
          "fulfilled_quantity": 0,
          "fulfillment_info": null,
          "cancelled_quantity": 0,
          "cancelled_info": null,
          "returned_quantity": 0,
          "returned_info": null
        }
      ],
      "metadata": {
        "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
        "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
      },
      "payment_offer": null,
      "deferred_payment": null
    },
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-LitFGLodQh9qQHTFcjUvfm",
      "id": "order-LitFGLodQh9qQHTFcjUvfm",
      "unique_id": "8751729d-7e96-4d38-87bc-fe241ca1d4d7",
      "customer": {
        "type": "registered",
        "organisation": "org-dLWYumjHaqChNggScx5inV",
        "user": "user-czNtrBwLY63rJkqmgyQaEF",
        "delivery_address": {
          "name": "John Smith",
          "address_line1": "1 Station Street",
          "address_line2": "Flat B",
          "address_line3": "",
          "city": "London",
          "region": "",
          "postcode": "SE11 6NQ",
          "country": "GB",
          "phone": "",
          "email": ""
        },
      },
      "status": "draft",
      "currency": "GBP",
      "pay_method": "",
      "total_amount": 12000,
      "tax_amount": 2000,
      "order_date": "2018-04-25",
      "invoice_date": null,
      "due_date": null,
      "paid_date": null,
      "items": [
        {
          "item_id": "1",
          "type": "product",
          "description": "Super ergonomic chair",
          "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
          "reference": "702.611.50",
          "category": "Furniture > Chairs",
          "supplier_id": "7363",
          "supplier_name": "",
          "quantity": "10.000",
          "unit_price": 1000,
          "tax_rate": "20.00",
          "total_amount": 10000,
          "tax_amount": 2000,
          "fulfilled_quantity": 0,
          "fulfillment_info": null,
          "cancelled_quantity": 0,
          "cancelled_info": null,
          "returned_quantity": 0,
          "returned_info": null
        },
        {
          "item_id": "2",
          "type": "shipping",
          "description": "Delivery fee",
          "metadata": {},
          "reference": "",
          "category": "",
          "supplier_id": "",
          "supplier_name": "",
          "quantity": "1.000",
          "unit_price": 2000,
          "tax_rate": "20.00",
          "total_amount": 2000,
          "tax_amount": 400,
          "fulfilled_quantity": 0,
          "fulfillment_info": null,
          "cancelled_quantity": 0,
          "cancelled_info": null,
          "returned_quantity": 0,
          "returned_info": null
        }
      ],
      "metadata": {
        "customer_id": "584eaf27-250c-4b83-826f-909cbaa1f54a",
        "checkout_id": "59e278cd-305a-4bbe-a275-f038f9319b1c"
      },
      "payment_offer": null,
      "deferred_payment": null
    }
  ]
}

List orders created by your platform

View order

Requests

  • without expanding referenced objects
GET /v1/payment/orders/<order_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/orders/<order_id> \
     --header "Authorization: <your_api_key>"
  • with expanding referenced organisation, payment_offer
GET /v1/payment/orders/<order_id>?expand=organisation,payment_offer HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/orders/<order_id>?extend=organisation,payment_offer \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>"

Responses

  • regular response (with optional expansion)
200 Ok
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "unique_id": "48b0ce9a-f8a3-4dff-be56-26af747b3d98",
  "customer": {
    "type": "registered",
    "organisation": {
      "id": "org-ypTaHiLv5kgqSn4TzCr7xb",
      "unique_id": "c105b862-f1ba-4197-9d97-57db63196b00",
      "registered": "2017-06-01T14:37:12Z",
      "company": "co-bqRyKAGaFrEEN8JMjWJiqk",
      "users": ["user-nNqgg5AFymQMumaU7EdrLa"]
    }
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "address_line3": "",
      "city": "London",
      "region": "",
      "postcode": "SE11 6NQ",
      "country": "GB",
      "phone": "",
      "email": ""
    },
  },
  "status": "draft",
  "currency": "GBP",
  "pay_method": "",
  "total_amount": 12000,
  "tax_amount": 2000,
  "order_date": "2018-04-25",
  "invoice_date": null,
  "due_date": null,
  "paid_date": null,
  "items": [
    {
      "item_id": "1",
      "type": "product",
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "supplier_name": "",
      "quantity": "10.000",
      "unit_price": 1000,
      "tax_rate": "20.00",
      "total_amount": 10000,
      "tax_amount": 2000,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "metadata": {},
      "reference": "",
      "category": "",
      "supplier_id": "",
      "supplier_name": "",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 400,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    }
  ],
  "metadata": {
    "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
    "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
  },
  "payment_offer": {
    "url": "https://api-sandbox.hokodo.co/v1/payment/offers/offer-EzH6BixNSHvaByEpXcFW5h",
    "id": "offer-bqRyHAGaFrDEN8JNjXJirp",
    "order": "order-dTHo9Q2idffT7CMPCVjztA",
    "status": "eligible",
    "offered_payment_plans": [
      {
          "id": "pln-bqRyHAGaFrDEN8JNjXJirp",
          "name": "net30",
          "currency": "GBP",
          "scheduled_payments": [
            {
              "date": "2020-10-16",
              "amount": 100000,
              "allowed_payment_methods": [
                {"type": "card"},
                {"type": "direct_debit"},
                {"type": "invoice"}
              ]
            }
          ],
          "merchant_fee": {
            "currency": "GBP",
            "amount": 1000
          },
          "customer_fee": {
            "currency": "GBP",
            "amount": 0
          },
          "price": {
            "amount": 100000,
            "currency": "GBP"
          },
          "valid_until": "2020-09-16T12:44:49.059Z",
          "payment_url": "https://payment.app.hokodo.co/plans/pln-bqRyHAGaFrDEN8JNjXJirp"
          "status": "active"
      },
      {
          "id": "pln-gJdDHAGaFrDLDvJNXJird",
          "name": "4x",
          "currency": "GBP",
          "scheduled_payments": [
            {
              "date": "2020-09-16",
              "amount": 25100,
              "allowed_payment_methods": [
                {"type": "card"}
              ]
            },
            {
              "date": "2020-10-16",
              "amount": 25100,
              "allowed_payment_methods": [
                {"type": "card"}
              ]
            },
            {
              "date": "2020-11-16",
              "amount": 25100,
              "allowed_payment_methods": [
                {"type": "card"}
              ]
            },
            {
              "date": "2020-12-16",
              "amount": 25100,
              "allowed_payment_methods": [
                {"type": "card"}
              ]
            }
          ],
          "merchant_fee": {
            "currency": "GBP",
            "amount": 2000
          },
          "customer_fee": {
            "currency": "GBP",
            "amount": 400
          },
          "price": {
            "amount": 100000,
            "currency": "GBP"
          },
          "valid_until": "2020-09-16T12:44:49.059Z",
          "payment_url": "https://payment.app.hokodo.co/plans/pln-gJdDHAGaFrDLDvJNXJird"
          "status": "active"
      },
    ],
    "rejection_reason": null,
    "urls": {
      "success": "https://merchant.com/payment/ok",
      "failure": "https://merchant.com/checkout",
      "cancel": "https://merchant.com/checkout",
      "notification": "https://backend.merchant.com/payment/notifications",
      "merchant_terms": "https://merchant.com/terms"
    },
    "locale": "en-gb",
    "metadata": {}
  },
  "deferred_payment": null
}
  • order not found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}

Look up a previously created order.

Errors

errors description
404 the order_id is probably invalid, the order has not been found

Modify order

Modify a previously created order.

Historic Orders

When you supply information on Orders for the purposes of informing Hokodo about a customer's payment history, you are able to amend those orders freely, or even delete them using the Delete Order endpoint.

Orders with a PaymentOffer

Once you request a PaymentOffer for an Order, any subsequent changes made to the Order will automatically expire the PaymentOffer.

Note: You can still amend the following fields unique_id, metadata, po_number as they don't affect the terms of the PaymentOffer.

Orders with a DeferredPayment

Once the customer purchases a DeferredPayment, the underlying Order can no longer be amended using the Order's endpoint, with the following exception: unique_id. Instead, you must use the dedicated endpoints for dealing with Cancellations, Refunds/Discounts and Returns, which are described in the post-sale Order actions section.

Request (e.g. update when an invoice has been paid)

PATCH /v1/payment/orders/<order_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "status": "paid",
  "paid_date": "2018-06-10",
  "pay_method": "bank"
}
curl --request PATCH \
     --url https://api-sandbox.hokodo.co/v1/payment/orders/<order_id> \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>" \
     --data-binary '{
  "status": "paid",
  "paid_date": "2018-06-10",
  "pay_method": "bank"
}'

Response

200 Ok
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "registered",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "address_line3": "",
      "city": "London",
      "region": "",
      "postcode": "SE11 6NQ",
      "country": "GB",
      "phone": "",
      "email": ""
    },
  },
  "status": "paid",
  "currency": "GBP",
  "pay_method": "",
  "total_amount": 12000,
  "tax_amount": 2000,
  "order_date": "2018-04-25",
  "invoice_date": "2018-04-25",
  "due_date": "2018-05-25",
  "paid_date": "2018-06-10",
  "pay_method": "bank",
  "items": [],
  "metadata": null,
  "payment_offer": null,
  "deferred_payment": null
}

Errors

errors description
400 a required field is missing or some of the fields have incorrect value
409 the order is already insured, modification is not allowed

Delete order

Request

DELETE /v1/payment/orders/<order_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE \
     --url https://api-sandbox.hokodo.co/v1/payment/orders/<order_id> \
     --header "Authorization: <your_api_key>"

Responses

  • regular response
204 No Content
  • order not found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}
  • order can not be deleted
409 Conflict
Content-Type: application/json

Delete a previously created order.

Errors

errors description
404 the order_id is probably invalid, the order has not been found
409 the order can not be deleted

Order Documents

OrderDocuments are documents such as an invoice, credit note, or a shipping document associated with a particular order.

Invoices

Invoices are normally sent by the merchant to the customer at the time of delivery. Hokodo need these invoices to support the collections process, because it is very common for customers to ask for the invoice to be re-sent to them before they make payment. Therefore, once the merchant generates the invoice, it should also be shared with Hokodo using this endpoint.

Credit Notes

Credit notes are sent by the merchant to the customer whenever a post-sale action such as a discount or return is applied to an order. If you issue credit notes when processing discounts or returns, you can save your operations team a significant amount of time by uploading the credit note to Hokodo using this endpoint at the time they are raised. This allows Hokodo to respond to the customer and resolve any queries without the need to liaise with your operations team.

Shipping documents

Shipping documents are documents associated with delivery, such as a copy of the delivery confirmation signed by the recipient. These documents are useful should there be any disputes about whether delivery occurred. If merchants are routinely capturing delivery confirmation documents, then systematically sharing these with Hokodo using this endpoint will save on operational hassle for Hokodo and the merchant if/when they are ever needed.

Other

Other can be used for any other documents that the merchant wishes to share with Hokodo

OrderDocument Object

{
    "id": "odoc-afapG98cKaCL5VRjVfQQ2S",
    "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
    "doc_type": "invoice",
    "description": "Invoice sent to customer",
    "amount": 10000,
    "metadata": {"unique_id": "some_unique_id"}
    "file": "https://hokodo-sandbox-clientdocuments.s3.amazonaws.com/media/order_documents/..."
}
field type description
id string(uuid) API unique identifier of the order document
order string(uuid) API identifier of the linked order
doc_type string Type of document, see below
description string Description of the document
amount int Value of the document in minor units (e.g. a credit note worth £100, will have amount=10000)
metadata dict Set of key-value pairs you can attach to the object. You can use this to store your custom data in the object and read it back later.
file string(uri) Link to the document

OrderDocument type

Possible order document types are:

Create OrderDocument

POST /v1/payment/orders/<order_id>/documents HTTP/1.1
Host: api-sandbox.hokodo.co
Content-Type: multipart/form-data; boundary=X-CLIENT-BOUNDARY
Authorization: Token <your_api_key>
Accept: */*
Content-Length: <some_length>
curl --request POST \
  --url https://api-sandbox.hokodo.co/v1/payment/orders/<order_id>/documents \
  --header 'Authorization: Token <your_api_key>' \
  --form doc_type=invoice \
  --form description=invoice_description \
  --form amount=invoice_amount \
  --form metadata=invoice_metadata \
  --form file=@/path/to/file

To create an OrderDocument, you'll need to make a post request with the Content-Type set to multipart form data. In the request body please include the file you wish to upload.

You can optionally include doc_type, description, amount, and metadata.

field type flags description
file file required Content of the document
doc_type string optional Type of document, see above
description string optional Description of the document
amount int optional Value of the document in minor units (e.g. a credit note worth £100, will have amount=10000)
metadata dict optional Set of key-value pairs you can attach to the object. You can use this to store your custom data in the object and read it back later.

Errors

errors description
400 a required field is missing

View order document

Requests

GET /v1/payment/orders/<order_id>/documents/<document_id> HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/orders/<order_id>/documents/<document_id> \
     --header "Authorization: <your_api_key>"

Responses

200 Ok
Content-Type: application/json
{
    "id": "odoc-afapG98cKaCL5VRjVfQQ2S",
    "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
    "doc_type": "invoice",
    "description": "Invoice Description",
    "amount": 10000,
    "metadata": {"unique_id": "some_unique_id"},
    "file": "https://hokodo-sandbox-clientdocuments.s3.amazonaws.com/media/order_documents/..."
}
  • order document not found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}

Look up a previously created order document.

Errors

errors description
404 the order_document_id is probably invalid, the order document has not been found

Payment Offers

The Offer API is used to create a set of payment plans for your customer. Simply provide an order id and Hokodo will return a list of payment plans that you can share with your customer at checkout, or over email or text message.

Offer Endpoints

Offer Object

{
  "url": "https://api-sandbox.hokodo.co/v1/payment/offers/offer-bqRyHAGaFrDEN8JNjXJirp",
  "id": "offer-bqRyHAGaFrDEN8JNjXJirp",
  "order": "order-dTHo9Q2idffT7CMPCVjztA",
  "offered_payment_plans": [
    {
      "id": "pln-bqRyHAGaFrDEN8JNjXJirp",
      "name": "net30",
      "currency": "GBP",
      "scheduled_payments": [
        {
          "date": "2020-10-16",
          "amount": 100000,
          "allowed_payment_methods": [
            {"type": "card"},
            {"type": "direct_debit"},
            {"type": "invoice"}
          ],
          "payment_method": {"type": "card"},
          "due_date_config": {
            "due_after_nb_days": 30, 
            "due_end_of_nb_months": null,
            "amount_percentage": "100.0"
          }
        }
      ],
      "payment_terms_relative_to": "order_creation",
      "merchant_fee": {
        "currency": "GBP",
        "amount": 1000
      },
      "customer_fee": {
        "currency": "GBP",
        "amount": 0
      },
      "valid_until": "2020-09-16T12:44:49.841Z",
      "payment_url": "https://payment.app.hokodo.co/plans/pln-bqRyHAGaFrDEN8JNjXJirp"
      "status": "offered",
      "rejection_reason": null
    }
  ],
  "urls": {
    "success": "https://merchant.com/payment/ok",
    "failure": "https://merchant.com/checkout",
    "cancel": "https://merchant.com/checkout",
    "notification": "https://backend.merchant.com/payment/notifications",
    "merchant_terms": "https://merchant.com/terms"
  },
  "locale": "en-gb",
  "metadata": {}
}
field type description
url string API endpoint to access the Offer
id string(uuid) API identifier for the Offer
order string(uuid) API identifier for the attached Transaction
offered_payment_plans list List of payment plans you can offer to your customer
legals dictionary An internal field which is subject to change
urls dictionary Redirection and callback URLs
urls[merchant_terms] string(url) URL for the terms and conditions of your platform, to display to the user
urls[success] string(url) URL to redirect the customer to if the deferred payment application is a success
urls[failure] string(url) URL to redirect the customer to if the deferred payment application is rejected. For example the checkout page to finish with another payment method
urls[cancel] string(url) URL to redirect the customer to if they cancel the application before completing it. For example the checkout page to finish with another payment method
urls[notification] string(url) Callback URL to receive notifications about the deferred payment application
locale string Language and region of the customer (RFC 1766), for example "en-gb" or "fr-fr"
metadata dictionary Set of key-value pairs to store additional information about the Offer

Payment Plan Object

field type description
id string(uuid) API identifier for the Payment Plan
name string Payment plan name (e.g. Pay in 30 days, Pay in 3 installments)
template string Hokodo identifier of the template from which the payment plan data object was created
currency string string
scheduled_payments list The re-payment schedule for the plan (e.g. your customer will pay £x amount on YYYY-MM-DD date)
scheduled_payments[date] string Date when the payment is due (e.g. 2020-09-16). If you offer your buyers payment terms upon fulfillment/capture (e.g. payment_terms_relative_to=first_capture), when order fulfillment/capture occurs, then this date may be recalculated and updated
scheduled_payments[amount] int Amount your customer will pay on this date in pence/cents
scheduled_payments[allowed_payment_methods] list List of payment method types allowed to make a payment with
scheduled_payments[payment_method] string Payment method assigned to use. This gets assigned when the Deferred Payment is created (null if there is no DeferredPayment)
scheduled_payments[due_date_config] dictionary A Scheduled Payment Due Date Config object. The settings that determine how your buyers scheduled_payments will be generated
payment_terms_relative_to string An event in the lifecycle of an order. Your buyers scheduled payment dates will be calculated relative to the date of this event. Either order_creation, when your buyer is checking-out. Or first_capture, when you mark any part of the order as fulfilled/captured
merchant_fee dictionary Amount and currency of the fees for you for this payment plan
customer_fee dictionary Amount and currency of the fees for the customer for this payment plan (included in the scheduled payments)
valid_until date Time when payment plan offer expires. After this date, your customer cannot avail of this plan
payment_url string Link where your customer can apply for the payment plan
status string Current status of the payment plan (e.g. offered, accepted, declined, expired, cancelled)
rejection_reason dictionary Rejection reason if Offer is declined, see rejection reasons
rejection_reason[code] string A text label identifying the reason
rejection_reason[detail] string A detailed explanation of why the Offer was declined. This can be shared with your customer
rejection_reason[params] dictionary A dictionary of dynamic key-value pairs which can be used to customize the rejection reason

Note: When your customer clicks on the Payment plan's payment_url a Deferred Payment object will be created automatically.

Scheduled Payment Due Date Config Object

field type description
due_after_nb_days int A rule for deciding how the scheduled_payments.date will be calculated. It will be relative to the event specified in the payment plan payment_terms_relative_to. This will be null if due_end_of_nb_months has been specified instead
due_end_of_nb_months int A rule for deciding how the scheduled_payments.date will be calculated. The payment will be due on the last day of a month. The month it will be due on, is the current month, plus the value of this field. This is relative to the event specified in the payment plan payment_terms_relative_to. A value of 0 means it will be due at the end of the current month. 1 means at the end of next month. This will be null if due_end_of_nb_days has been specified instead
amount_percentage decimal The amount your buyer will pay at this time, as a percentage of the total order value. This value may be null for old/historical payment offers.

Request a New Offer

Request

POST /v1/payment/offers HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "order": "order-dTHo9Q2idffT7CMPCVjztA",
  "urls": {
    "success": "https://merchant.com/payment/ok",
    "failure": "https://merchant.com/checkout",
    "cancel": "https://merchant.com/checkout",
    "notification": "https://backend.merchant.com/payment/notifications",
    "merchant_terms": "https://merchant.com/terms"
  },
  "locale": "en-gb",
  "metadata": {}
}
curl --request POST \
     --url https://api-sandbox.hokodo.co/v1/payment/offers \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>" \
     --data-binary '{
  "order": "order-dTHo9Q2idffT7CMPCVjztA",
  "urls": {
    "success": "https://merchant.com/payment/ok",
    "failure": "https://merchant.com/checkout",
    "cancel": "https://merchant.com/checkout",
    "notification": "https://backend.merchant.com/payment/notifications",
    "merchant_terms": "https://merchant.com/terms"
  },
  "locale": "en-gb",
  "metadata": {}
}'

Responses

  • Offer Offered
201 Created
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/offers/offer-EzH6BixNSHvaByEpXcFW5h",
  "id": "offer-bqRyHAGaFrDEN8JNjXJirp",
  "order": "order-dTHo9Q2idffT7CMPCVjztA",
  "offered_payment_plans": [
    {
      "id": "pln-gJdDHAGaFrDLDvJNXJird",
      "name": "4xEOM",
      "currency": "GBP",
      "scheduled_payments": [
        {
          "date": "2020-09-30",
          "amount": 25100,
          "allowed_payment_methods": [
            {"type": "card"}
          ],
          "payment_method": null,
          "due_date_config": {
            "due_after_nb_days": null, 
            "due_end_of_nb_months": 0, 
            "amount_percentage": "25.0"
          }
        },
        {
          "date": "2020-10-31",
          "amount": 25100,
          "allowed_payment_methods": [
            {"type": "card"}
          ],
          "payment_method": null,
          "due_date_config": {
            "due_after_nb_days": null, 
            "due_end_of_nb_months": 1, 
            "amount_percentage": "25.0"
          }
        },
        {
          "date": "2020-11-30",
          "amount": 25100,
          "allowed_payment_methods": [
            {"type": "card"}
          ],
          "payment_method": null,
          "due_date_config": {
            "due_after_nb_days": null, 
            "due_end_of_nb_months": 2, 
            "amount_percentage": "25.0"
          }
        },
        {
          "date": "2020-12-31",
          "amount": 25100,
          "allowed_payment_methods": [
            {"type": "card"}
          ],
          "payment_method": null,
          "due_date_config": {
            "due_after_nb_days": null, 
            "due_end_of_nb_months": 3, 
            "amount_percentage": "25.0"
          }
        }
      },
      "payment_terms_relative_to": "order_creation",
      "merchant_fee": {
        "currency": "GBP",
        "amount": 2000
      },
      "customer_fee": {
        "currency": "GBP",
        "amount": 400
      },
      "valid_until": "2020-09-16T12:44:49.841Z",
      "payment_url": "https://payment.app.hokodo.co/plans/pln-gJdDHAGaFrDLDvJNXJird"
      "status": "offered",
      "rejection_reason": null
    }
  ],
  "urls": {
    "success": "https://merchant.com/payment/ok",
    "failure": "https://merchant.com/checkout",
    "cancel": "https://merchant.com/checkout",
    "notification": "https://backend.merchant.com/payment/notifications",
    "merchant_terms": "https://merchant.com/terms"
  },
  "locale": "en-gb",
  "metadata": {}
}
  • Offer Rejected
201 Created
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/offers/offer-3VezfMFGKX6U247jRhXAkQ",
  "id": "offer-3VezfMFGKX6U247jRhXAkQ",
  "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "offered_payment_plans": [
    {
      "id": "pln-bqRyHAGaFrDEN8JNjXJirp",
      "name": "net30",
      "currency": "GBP",
      "scheduled_payments": [
        {
          "date": "2020-10-16",
          "amount": 100000,
          "allowed_payment_methods": [
            {"type": "card"},
            {"type": "direct_debit"},
            {"type": "invoice"}
          ],
          "payment_method": {"type": "card"},
          "due_date_config": {
            "due_after_nb_days": 30, 
            "due_end_of_nb_months": null, 
            "amount_percentage": "100.0"
          }
        }
      ],
      "payment_terms_relative_to": "order_creation",
      "merchant_fee": {
        "currency": "GBP",
        "amount": 1000
      },
      "customer_fee": {
        "currency": "GBP",
        "amount": 0
      },
      "valid_until": "2020-09-16T12:44:49.841Z",
      "payment_url": "https://payment.app.hokodo.co/plans/pln-bqRyHAGaFrDEN8JNjXJirp"
      "status": "declined",
      "rejection_reason": {
        "code": "buyer-country",
        "detail": "We're currently unable to provide payment plans to Buyers domiciled in {debtor_country}.",
        "params": {
          "debtor_country": "Ireland",
        }
      },
    }
  ],
  "urls": {
    "success": "https://merchant.com/payment/ok",
    "failure": "https://merchant.com/checkout",
    "cancel": "https://merchant.com/checkout",
    "notification": "https://backend.merchant.com/payment/notifications",
    "merchant_terms": "https://merchant.com/terms"
  },
  "locale": "en-gb",
  "metadata": {}
}

This endpoint is used to create a list of payment options for your customer. The required fields are

You can optionally include a metadata object to store additional information about the Offer.

field type flags description
order string(uuid) required API unique identifier of the order
urls dictionary required Redirection and callback URLs
urls[merchant_terms] string(url) required URL for the terms and conditions of your platform, to display to the user
urls[success] string(url) required URL to redirect the customer to if the deferred payment application is a success
urls[failure] string(url) required URL to redirect the customer to if the deferred payment application is rejected. For example the checkout page to finish with another payment method
urls[cancel] string(url) required URL to redirect the customer to if they cancel the application before completing it. For example the checkout page to finish with another payment method
urls[notification] string(url) required Callback URL to receive notifications about the deferred payment application
locale string optional Language and region of the customer (RFC 1766), for example "en-gb" or "fr-fr"
metadata dictionary optional Set of key-value pairs to store additional information about the Offer.

Errors

errors description
400 a required field is missing
409 can't obtain an offer as order has already been paid

List Offers

Request

GET /v1/payment/offers HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/offers \
     --header "Authorization: <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/offers/offer-EzH6BixNSHvaByEpXcFW5h",
      "id": "offer-bqRyHAGaFrDEN8JNjXJirp",
      "order": "order-dTHo9Q2idffT7CMPCVjztA",
      "offered_payment_plans": [
        {
          "id": "pln-bqRyHAGaFrDEN8JNjXJirp",
          "name": "net30",
          "currency": "GBP",
          "scheduled_payments": [
            {
              "date": "2020-10-16",
              "amount": 100000,
              "allowed_payment_methods": [
                {"type": "card"},
                {"type": "direct_debit"},
                {"type": "invoice"}
              ],
              "payment_method": {"type": "card"},
              "due_date_config": {
                "due_after_nb_days": 30, 
                "due_end_of_nb_months": null, 
                "amount_percentage": "100.0"
              }
            }
          ],
          "payment_terms_relative_to": "order_creation",
          "merchant_fee": {
            "currency": "GBP",
            "amount": 1000
          },
          "customer_fee": {
            "currency": "GBP",
            "amount": 0
          },
          "valid_until": "2020-09-16T12:44:49.841Z",
          "payment_url": "https://payment.app.hokodo.co/plans/pln-bqRyHAGaFrDEN8JNjXJirp"
          "status": "offered",
          "rejection_reason": null
        }
      ],
      "urls": {
        "success": "https://merchant.com/payment/ok",
        "failure": "https://merchant.com/checkout",
        "cancel": "https://merchant.com/checkout",
        "notification": "https://backend.merchant.com/payment/notifications",
        "merchant_terms": "https://merchant.com/terms"
      },
      "locale": "en-gb",
      "metadata": {}
    },
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/offers/offer-3VezfMFGKX6U247jRhXAkQ",
      "id": "offer-3VezfMFGKX6U247jRhXAkQ",
      "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
      "offered_payment_plans": [
        {
          "id": "pln-bqRyHAGaFrDEN8JNjXJirp",
          "name": "net30",
          "currency": "GBP",
          "scheduled_payments": [
            {
              "date": "2020-10-16",
              "amount": 100000,
              "allowed_payment_methods": [
                {"type": "card"},
                {"type": "direct_debit"},
                {"type": "invoice"}
              ],
              "payment_method": {"type": "card"},
              "due_date_config": {
                "due_after_nb_days": 30, 
                "due_end_of_nb_months": null, 
                "amount_percentage": "100.0"
              }
            }
          ],
          "payment_terms_relative_to": "order_creation",
          "merchant_fee": {
            "currency": "GBP",
            "amount": 1000
          },
          "customer_fee": {
            "currency": "GBP",
            "amount": 0
          },
          "valid_until": "2020-09-16T12:44:49.841Z",
          "payment_url": "https://payment.app.hokodo.co/plans/pln-bqRyHAGaFrDEN8JNjXJirp"
          "status": "declined",
          "rejection_reason": {
            "code": "buyer-country",
            "detail": "We're currently unable to provide payment plans to Buyers domiciled in {debtor_country}.",
            "params": {
              "debtor_country": "Ireland",
            }
          },
        }
      ],
      "urls": {
        "success": "https://merchant.com/payment/ok",
        "failure": "https://merchant.com/checkout",
        "cancel": "https://merchant.com/checkout",
        "notification": "https://backend.merchant.com/payment/notifications",
        "merchant_terms": "https://merchant.com/terms"
      },
      "locale": "en-gb",
      "metadata": {}
    }
  ]
}

List all previously requested Offers

View Offer

Request

GET /v1/payment/offers/<offer_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/offers/<offer_id> \
     --header "Authorization: <your_api_key>"

Responses

  • Regular Response
200 Ok
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/offers/offer-EzH6BixNSHvaByEpXcFW5h",
  "id": "offer-bqRyHAGaFrDEN8JNjXJirp",
  "order": "order-dTHo9Q2idffT7CMPCVjztA",
  "offered_payment_plans": [
    {
    "id": "pln-bqRyHAGaFrDEN8JNjXJirp",
    "name": "net30",
    "currency": "GBP",
    "scheduled_payments": [
      {
        "date": "2020-10-16",
        "amount": 100000,
        "allowed_payment_methods": [
          {"type": "card"},
          {"type": "direct_debit"},
          {"type": "invoice"}
        ],
        "payment_method": {"type": "card"},
        "due_date_config": {
          "due_after_nb_days": 30, 
          "due_end_of_nb_months": null, 
          "amount_percentage": "100.0"
        }
      }
    ],
    "payment_terms_relative_to": "order_creation",
    "merchant_fee": {
      "currency": "GBP",
      "amount": 1000
    },
    "customer_fee": {
      "currency": "GBP",
      "amount": 0
    },
    "valid_until": "2020-09-16T12:44:49.841Z",
    "payment_url": "https://payment.app.hokodo.co/plans/pln-bqRyHAGaFrDEN8JNjXJirp"
    "status": "offered",
    "rejection_reason": null
    }
  ],
  "urls": {
    "success": "https://merchant.com/payment/ok",
    "failure": "https://merchant.com/checkout",
    "cancel": "https://merchant.com/checkout",
    "notification": "https://backend.merchant.com/payment/notifications",
    "merchant_terms": "https://merchant.com/terms"
  },
  "locale": "en-gb",
  "metadata": {}
}
  • Not Found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}

Retrieve a Previously Requested Offer

Errors

Errors Description
404 The Offer id is probably incorrect, a Offer has not been found

Delete Offer

Request

DELETE /v1/payment/offers/<offer_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request DELETE \
     --url https://api-sandbox.hokodo.co/v1/payment/offers/<offer_id> \
     --header "Authorization: <your_api_key>"

Responses

  • Regular Response
204 No Content
  • Not Found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}
  • Unable to Delete Accepted Offer
409 Conflict
Content-Type: application/json

Delete a Previously Requested Offer

Errors

errors description
404 The Offer id is probably incorrect, a Offer has not been found
409 Can't delete the Offer, probably because it's already been accepted

Mail offer to customer

Request

PUT /v1/payment/payment_plans/pln-bqRyHAGaFrDEN8JNjXJirp/send_offer_email HTTP/1.1
Authorization: Token <your_api_key>
curl --request PUT \
     --url https://api-sandbox.hokodo.co/v1/payment/payment_plans/pln-bqRyHAGaFrDEN8JNjXJirp/send_offer_email \
     --header "Authorization: <your_api_key>"

Responses

  • Offer sent to customer by email
200 OK
Content-Type: application/json
{
    "detail": "Payment plan email sent."
}

You can use this endpoint to have Hokodo send an email to the customer, with a link to a specific payment plan.

Errors

errors description
400 Payment Plan invalid (for example declined)

Post-sale Order actions

After a PaymentOffer has been accepted by the customer, you will need to use the following endpoints to make modifications to the Order.

These will not all be necessary for every order. The base flow would be:

  1. Create the Order.
  2. Request the PaymentOffer.
  3. The customer accepts one of the payment plans and confirms the order.
  4. You mark the order as fulfilled as you ship it.
  5. Hokodo sends you the money immediately.
  6. The customer pays Hokodo later.

Post-sale Order endpoints

Fulfillment

Request

PUT /v1/payment/orders/<order_id>/fulfill HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "items": [
    {
      "item_id": "1",
      "quantity": "10.000",
      "total_amount": 10000,
      "tax_amount": 2000,
      "shipping_id": "DX49581904385",
      "shipping_provider": "Postal service"
    },
    {
      "item_id": "2",
      "quantity": "1.000",
      "total_amount": 2000,
      "tax_amount": 400,
      "shipping_id": "DX49581904385",
      "shipping_provider": "Postal service"
    }
  ]
}
curl --request PATCH \
     --url https://api-sandbox.hokodo.co/v1/payment/orders/<order_id>/fulfill \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>" \
     --data-binary '{
  "items": [
    {
      "item_id": "1",
      "quantity": "10.000",
      "total_amount": 10000,
      "tax_amount": 1667,
      "shipping_id": "DX49581904385",
      "shipping_provider": "Postal service"
    },
    {
      "item_id": "2",
      "quantity": "1.000",
      "total_amount": 2000,
      "tax_amount": 333,
      "shipping_id": "DX49581904385",
      "shipping_provider": "Postal service"
    }
  ]
}'

Response

200 Ok
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "registered",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "address_line3": "",
      "city": "London",
      "region": "",
      "postcode": "SE11 6NQ",
      "country": "GB",
      "phone": "",
      "email": ""
    },
  },
  "status": "pending",
  "currency": "GBP",
  "pay_method": "",
  "total_amount": 12000,
  "tax_amount": 2000,
  "order_date": "2018-04-25",
  "invoice_date": "2018-04-25",
  "due_date": "2018-06-25",
  "paid_date": null,
  "items": [
    {
      "item_id": "1",
      "type": "product",
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "supplier_name": "",
      "quantity": "10.000",
      "unit_price": 1000,
      "tax_rate": "20.00",
      "total_amount": 10000,
      "tax_amount": 2000,
      "fulfilled_quantity": 10,
      "fulfillment_info": [
        {
          "quantity": "10.000",
          "total_amount": 10000,
          "tax_amount": 2000,
          "shipping_id": "DX49581904385",
          "shipping_provider": "Postal service",
          "shipping_date": "2018-04-26"
        }
      ],
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "metadata": {},
      "reference": "",
      "category": "",
      "supplier_id": "",
      "supplier_name": "",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 400,
      "fulfilled_quantity": 1,
      "fulfillment_info": [
        {
          "quantity": "1.000",
          "total_amount": 2000,
          "tax_amount": 400,
          "shipping_id": "DX49581904385",
          "shipping_provider": "Postal service",
          "shipping_date": "2018-04-26"
        }
      ],
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    }
  ],
  "metadata": {
    "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
    "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
  },
  "payment_offer": "offer-cqfxJVUwXBrkyZHRQaknJS",
  "deferred_payment": "defpay-7PiKMX2gEpJmasb8Du65zn"
}

Fulfillment refers to the process of shipping the goods to the customer, or providing them with the service they have purchased. It is important that you notify Hokodo when fulfillment occurs since this is the trigger for our payment to you. This endpoint is usually called when the package has been handed over to the logistics carrier. Hint: Make sure that your fulfillment department (or external partner) has access to the API. Often, this requires some planning ahead.

Fulfillment information must include date and all items that have actually been delivered to the customer in the format similar to the list of items in the Order.

You can either ship the full order or only parts of the order. In case you initially only ship parts of the order:

field type flags description
items list required The list of items that got shipped, each with the fields described below
item_id string required Your identifier for this line of the order, e.g. 1, 2, 3...
quantity decimal required Number of items shipped
total_amount int required Total amount including tax of the items that shipped, in minor units (cents)
tax_amount int required Total amount of the taxes of the items that shipped, in minor units (cents)
shipping_id string optional Tracking id of the shipping provider
shipping_provider string optional Name of the shipping provider

Errors

errors description
404 the order_id is probably invalid, the order has not been found
400 a required field is missing or some of the fields have incorrect value

Cancellation

Request

  • partial cancellation of half the items in the Order
PUT /v1/payment/orders/<order_id>/cancel HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "items": [
    {
      "item_id": "2",
      "quantity": "1",
      "total_amount": 2000,
      "tax_amount": 400
    }
  ]
}
curl --request PATCH \
     --url https://api-sandbox.hokodo.co/v1/payment/orders/<order_id>/cancel \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>" \
     --data-binary '{
  "items": [
    {
      "item_id": "2",
      "quantity": "1",
      "total_amount": 2000,
      "tax_amount": 400
    }
  ]
}'

Response

200 Ok
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "registered",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "address_line3": "",
      "city": "London",
      "region": "",
      "postcode": "SE11 6NQ",
      "country": "GB",
      "phone": "",
      "email": ""
    },
  },
  "status": "pending",
  "currency": "GBP",
  "pay_method": "",
  "total_amount": 7000,
  "tax_amount": 1166,
  "order_date": "2018-04-25",
  "invoice_date": "2018-04-25",
  "due_date": "2018-06-25",
  "paid_date": null,
  "items": [
    {
      "item_id": "1",
      "type": "product",
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "supplier_name": "",
      "quantity": "5.000",
      "unit_price": 1000,
      "tax_rate": "20.00",
      "total_amount": 5000,
      "tax_amount": 1000,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "metadata": {},
      "reference": "",
      "category": "",
      "supplier_id": "",
      "supplier_name": "",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 400,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 1,
      "cancelled_info": [
        {
          "quantity": "1.000",
          "total_amount": 2000,
          "tax_amount": 400,
        }
      ],
      "returned_quantity": 0,
      "returned_info": null
    }
  ],
  "metadata": {
    "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
    "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
  },
  "payment_offer": "offer-cqfxJVUwXBrkyZHRQaknJS",
  "deferred_payment": "defpay-7PiKMX2gEpJmasb8Du65zn"
}

If an order or individual items from an order are being cancelled by the customer before shipping, you need to notify us of the cancellation.

You can either cancel the full order or only parts of the order. In case you only cancel parts of the order:

Returns

Request

  • partial return of half the items in the Order
PUT /v1/payment/orders/<order_id>/return HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "items": [
    {
      "item_id": "2",
      "quantity": "1",
      "total_amount": 2000,
      "tax_amount": 400
    }
  ]
}
curl --request PATCH \
     --url https://api-sandbox.hokodo.co/v1/payment/orders/<order_id>/return \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>" \
     --data-binary '{
  "items": [
    {
      "item_id": "2",
      "quantity": "1",
      "total_amount": 2000,
      "tax_amount": 400
    }
  ]
}'

Response

200 Ok
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "registered",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "address_line3": "",
      "city": "London",
      "region": "",
      "postcode": "SE11 6NQ",
      "country": "GB",
      "phone": "",
      "email": ""
    },
  },
  "status": "pending",
  "currency": "GBP",
  "pay_method": "",
  "total_amount": 7000,
  "tax_amount": 1166,
  "order_date": "2018-04-25",
  "invoice_date": "2018-04-25",
  "due_date": "2018-06-25",
  "paid_date": null,
  "items": [
    {
      "item_id": "1",
      "type": "product",
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "supplier_name": "",
      "quantity": "5.000",
      "unit_price": 1000,
      "tax_rate": "20.00",
      "total_amount": 5000,
      "tax_amount": 1000,
      "fulfilled_quantity": 5,
      "fulfillment_info": [
        {
          "quantity": "5.000",
          "total_amount": 5000,
          "tax_amount": 1000,
          "shipping_id": "DX49581904385",
          "shipping_provider": "Postal service",
          "shipping_date": "2018-04-26"
        }
      ],
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "metadata": {},
      "reference": "",
      "category": "",
      "supplier_id": "",
      "supplier_name": "",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 400,
      "fulfilled_quantity": 1,
      "fulfillment_info": [
        {
          "quantity": "1.000",
          "total_amount": 2000,
          "tax_amount": 400,
          "shipping_id": "DX49581904385",
          "shipping_provider": "Postal service",
          "shipping_date": "2018-04-26"
        }
      ],
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 1,
      "returned_info": [
        {
          "quantity": "1.000",
          "total_amount": 2000,
          "tax_amount": 400,
        }
      ]
    }
  ],
  "metadata": {
    "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
    "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
  },
  "payment_offer": "offer-cqfxJVUwXBrkyZHRQaknJS",
  "deferred_payment": "defpay-7PiKMX2gEpJmasb8Du65zn"
}

If a shipped order (or individual items from an order) are being returned by the customer after shipping, you need to notify us of the return.

You can either return the full order or only parts of the order. In case you only return parts of the order:

Refunds / discounts

Request

PUT /v1/payment/orders/<order_id>/discount HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>

{
  "items": [
    {
      "item_id": "99",
      "description": "Discount following our email conversation",
      "quantity": "1.000",
      "unit_price": -120,
      "tax_rate": "20.00",
      "total_amount": -120,
      "tax_amount": -20
    }
  ]
}
curl --request PATCH \
     --url https://api-sandbox.hokodo.co/v1/payment/orders/<order_id>/discount \
     --header "Content-Type: application/json" \
     --header "Authorization: <your_api_key>" \
     --data-binary '{
  "items": [
    {
      "item_id": "99",
      "description": "Discount following our email conversation",
      "quantity": "1.000",
      "unit_price": -120,
      "tax_rate": "20.00",
      "total_amount": -120,
      "tax_amount": -20
    }
  ]
}'

Response

200 Ok
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "unique_id": "876987-987uinjojna-I8UH98Jnj",
  "customer": {
    "type": "registered",
    "organisation": "org-ypTaHiLv5kgqSn4TzCr7xb",
    "user": "user-nNqgg5AFymQMumaU7EdrLa",
    "delivery_address": {
      "name": "John Smith",
      "address_line1": "1 Station Street",
      "address_line2": "Flat B",
      "address_line3": "",
      "city": "London",
      "region": "",
      "postcode": "SE11 6NQ",
      "country": "GB",
      "phone": "",
      "email": ""
    },
  },
  "status": "pending",
  "currency": "GBP",
  "pay_method": "",
  "total_amount": 11880,
  "tax_amount": 1980,
  "order_date": "2018-04-25",
  "invoice_date": "2018-04-25",
  "due_date": "2018-06-25",
  "paid_date": null,
  "items": [
    {
      "item_id": "1",
      "type": "product",
      "description": "Super ergonomic chair",
      "metadata": {"color": "black", "name": "Karmus", "variant": "M"},
      "reference": "702.611.50",
      "category": "Furniture > Chairs",
      "supplier_id": "7363",
      "supplier_name": "",
      "quantity": "10.000",
      "unit_price": 1000,
      "tax_rate": "20.00",
      "total_amount": 10000,
      "tax_amount": 2000,
      "fulfillment_info": [
        {
          "quantity": "10.000",
          "total_amount": 10000,
          "tax_amount": 2000,
          "shipping_id": "DX49581904385",
          "shipping_provider": "Postal service",
          "shipping_date": "2018-04-26"
        }
      ]
    },
    {
      "item_id": "2",
      "type": "shipping",
      "description": "Delivery fee",
      "metadata": {},
      "reference": "",
      "category": "",
      "supplier_id": "",
      "supplier_name": "",
      "quantity": "1.000",
      "unit_price": 2000,
      "tax_rate": "20.00",
      "total_amount": 2000,
      "tax_amount": 400,
      "fulfilled_quantity": 1,
      "fulfillment_info": [
        {
          "quantity": "1.000",
          "total_amount": 2000,
          "tax_amount": 400,
          "shipping_id": "DX49581904385",
          "shipping_provider": "Postal service",
          "shipping_date": "2018-04-26"
        }
      ],
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    },
    {
      "item_id": "99",
      "type": "discount",
      "description": "Discount following our email conversation",
      "metadata": {},
      "reference": "",
      "category": "",
      "supplier_id": "",
      "supplier_name": "",
      "quantity": "1.000",
      "unit_price": -120,
      "tax_rate": "20.00",
      "total_amount": -120,
      "tax_amount": -20,
      "fulfilled_quantity": 0,
      "fulfillment_info": null,
      "cancelled_quantity": 0,
      "cancelled_info": null,
      "returned_quantity": 0,
      "returned_info": null
    }
  ],
  "metadata": {
    "customer_id": "2055b445-3d95-4d2f-bd80-3e336217905f",
    "checkout_id": "c0185e68-89aa-42d5-93e9-476d01d4c97f"
  },
  "payment_offer": "offer-cqfxJVUwXBrkyZHRQaknJS",
  "deferred_payment": "defpay-7PiKMX2gEpJmasb8Du65zn"
}

If a customer files a complaint, but does not return any items, and you want to refund some of the money, you can send us an unspecified refund or discount.

This refund or discount becomes a new line of the Order.

Disputes

If a customer files a complaint on a shipped order, and you can’t settle the dispute in a timely manner, we need to make sure, that we don’t debit the customer before the dispute is resolved. For that reason you need to send us a dispute notification, that then needs to be lifted once the dispute has been resolved.

As a result of an accepted dispute notification Hokodo will refrain from debiting the customer until the dispute has been actively resolved.

Note: If we already paid you, we will hold back the disputed sum from your next merchant payment until the dispute is resolved.

This endpoint is not available yet.

Deferred Payments

A Deferred Payment object is created when your customer completes the process to pay with Hokodo.

Deferred Payment Endpoints

Deferred Payment Object

{
  "url": "https://api-sandbox.hokodo.co/v1/payment/deferred_payments/defpay-bqRyGIGaORKiK8bhMVPirp",
  "id": "defpay-bqRyGIGaORKiK8bhMVPirp",
  "number": "P-7WR2-PR0S",  
  "payment_plan": "pln-gJdDHAGaFrDLDvJNXJird",
  "order": "order-dTHo9Q2idffT7CMPCVjztA",
  "status": "pending_review"
}
field type description
url string API endpoint to access the Deferred Payment
id string(uuid) API unique identifier for the Deferred Payment
number string The Deferred Payment's customer friendly public identifier (e.g. "P-7WR2-PR0S")
payment_plan string(uuid) API unique identifier of the personalised payment plan attached to the deferred payment
order string(uuid) API identifier for the Order
status string Deferred Payment status

Deferred Payment status

When it is created, the deferred payment status can be one of:

code description
accepted the payment has been accepted
pending_review the payment is pending manual review by Hokodo, you will be notified of the result
customer_action_required more information is required by the customer (e.g. upload KYC documents)
rejected the payment has been rejected by Hokodo

After that, the deferred payment status can become one of:

code description
cancelled the payment has been cancelled
part_fulfilled the order has been partially fulfilled
fulfilled the order has been entirely fulfilled
reversed

We will be adding more statuses here soon to help you monitor the state of fulfillment and disbursement of funds from Hokodo to you.

View Deferred Payment

Request

GET /v1/payment/deferred_payments/<deferredpayment_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/deferred_payments/<deferredpayment_id> \
     --header "Authorization: <your_api_key>"
}"

Responses

  • Regular Response
200 Ok
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/deferred_payments/defpay-bqRyGIGaORKiK8bhMVPirp",
  "id": "defpay-bqRyGIGaORKiK8bhMVPirp",
  "number": "P-7WR2-PR0S",  
  "payment_plan": "pln-gJdDHAGaFrDLDvJNXJird",
  "order": "order-dTHo9Q2idffT7CMPCVjztA",
  "status": "pending_review"
}
  • Not Found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}

Retrieve an Existing Deferred Payment

Payouts

A Payout represents a payment made from Hokodo to your bank account. It consists of the amount, date, and currency of the payout, as well as a list of individual Order changes and adjustments which were used to calculate the payout amount.

To facilitate cash reconciliation, each Payout object includes a unique payout reference id which can be found on your bank statement.

Payout endpoints

Payout object

{
  "url": "https://api-sandbox.hokodo.co/v1/payment/payouts/po-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "po-yQKxbtCg9aTS5JYnsRVA9B",
  "payout_reference_id": "HK-XYZ",
  "payout_date": "2022-01-01",
  "amount_from_payout_items": 12000,
  "amount_from_adjustments": 1000,
  "fees": 1000,
  "type": "net_of_fees",
  "amount": 12000,
  "currency": "GBP",
  "min_balance": {
    "fixed": 1000,
    "relative": 500,
    "actual": 1000,
    "withheld_amount": 2000,
  },
  "items": [
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/payout_items/poitm-yQKxbtCg9aTS5JYnsRVA9B",
      "id": "poitm-yQKxbtCg9aTS5JYnsRVA9B",
      "type": "fulfillment",  
      "payout": "po-yQKxbtCg9aTS5JYnsRVA9B", 
      "deferred_payment": "defpay-yQKxbtCg9aTS5JYnsRVA9B", 
      "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
      "status": "paid",
      "creation_date": "2021-12-26",
      "earliest_payout_date": "2022-01-01",
      "actual_payout_date": "2022-01-01",
      "amount": 1100,
      "fees": 100,
      "amount_net_of_fees": 1000,
      "currency": "GBP",
    },
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/payout_items/poitm-yQKxbtCg9aTS5JYnsRVA9B",
      "id": "poitm-yQKxbtCg9aTS5JYnsRVA9B",
      "type": "fulfillment",  
      "payout": "po-yQKxbtCg9aTS5JYnsRVA9B",
      "deferred_payment": "defpay-yQKxbtCg9aTS5JYnsRVA9B", 
      "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
      "status": "paid",
      "creation_date": "2021-12-26",
      "earliest_payout_date": "2022-01-01",
      "actual_payout_date": "2022-01-01",
      "amount": 1100,
      "fees": 100,
      "amount_net_of_fees": 1000,
      "currency": "GBP",
    },
  ],
  "adjustments": [
    {
      "id": "poadj-yQKxbtCg9aTS5JYnsRVA9B",
      "type": "credit_review_fee",
      "net_amount": 400,
      "tax_rate": 25,
      "amount": 500, 
      "currency": "GBP",     
    },
    {
      "id": "poadj-yQKxbtCg9aTS5JYnsRVA9B",
      "type": "minimum_fee",
      "net_amount": 400,
      "tax_rate": 25,
      "amount": 500,  
      "currency": "GBP",
    }
  ],  
}
field type description
url string API endpoint to access the Payout
id string(uuid) API unique identifier for the Payout
payout_reference_id string Id which appears on your bank statement
payout_date date Date the payout was made (i.e. when Hokodo initiated the transfer of funds to your bank account)
amount_from_payout_items int Total amount of payout_items including any applicable fees, in minor units (cents)
amount_from_adjustments int Total amount of adjustments in minor units (cents)
fees int Total amount of fees in minor units (cents)
type string How are your Payouts structured? net_of_fees or gross_of_fees
amount int Amount paid to your bank account in minor units (cents). See calculating the payout amount
currency string ISO 4217 currency code (e.g. GBP, EUR)
min_balance dictionary Minimum account balance parameters at the time the payout was made
min_balance[fixed] int Your fixed minimum account balance at the time the payout was made
min_balance[relative] int Your relative minimum account balance (as a % of unpaid Orders) at the time the payout was made
min_balance[actual] int The actual minimum balance used when calculating the payout amount. It is the max of fixed or relative
min_balance[withheld_amount] int Total amount of payout items (e.g. fulfilled Order items) which were not included in this payout, in order to maintain your minimum account balance
payout_items list List of payout items included in the payout
adjustments list List of adjustments which were included in the payout_amount
adjustments[*][id] string(uuid) API identifier for the Adjustment
adjustments[*][type] string Type of adjustment (see Adjustment Type section)
adjustments[*][net_amount] int Net amount for this adjustment (excluding tax) in minor units (cents)
adjustments[*][tax_rate] decimal Tax rate on this adjustment, in percent (e.g. "19.50" for 19.5%)
adjustments[*][amount] int Total amount for this adjustment (including tax) in minor units (cents)
adjustments[*][currency] string ISO 4217 currency code (e.g. GBP, EUR)

Calculating the payout amount

The final payout amount takes a number of factors into account:

Minimum account balance

Your Hokodo account contains two minimum account balance parameters:

When calculating the amount for an upcoming payout, Hokodo will compute your current minimum account balance min_balance[actual]. This is the maximum of your fixed or relative minimum account balance. Hokodo may withhold a number of PayoutItems needed to maintain this balance. The total amount of the withheld Payout items is stored in the Payout's min_balance[withheld_amount] field.

Adjustment amount

The Adjustment amount can be positive or negative.

Adjustment type

An adjustment can have one of the following types:

status description
balancing_item this is only used if adjustments are needed between successive payouts. Balancing items should always offset with items in preceding or subsequent months such that they should sum to zero
minimum_fee adjustment required if monthly transaction volumes don't achieve minimum fee
credit_review_fee fee for any credit reviews
balance_carried_to_next_payout amount carried over to next payout
balance_carried_from_last_payout amount carried over from last payout
fee_discount applied when any fees are waived
fx_fee fee incurred if any currency conversions are required as part of the payout
other

List Payouts

Request

GET /v1/payment/payouts HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/payouts \
     --header "Authorization: <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/payout/po-yQKxbtCg9aTS5JYnsRVA9B",
      "id": "po-yQKxbtCg9aTS5JYnsRVA9B",
      "payout_reference_id": "HK-XYZ",
      "payout_date": "2022-01-01",
      "amount_from_payout_items": 12000,
      "amount_from_adjustments": 1000,
      "fees": 1000,
      "type": "net_of_fees",
      "amount": 12000,
      "currency": "GBP",
      "min_balance": {
        "fixed": 1000,
        "relative": 500,
        "actual": 1000,
        "withheld_amount": 2000,
      },
      "items": [...],
      "adjustments": [...] 
    },
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/payout/po-yQKxbtCg9aTS5JYnsRVA9B",
      "id": "po-yQKxbtCg9aTS5JYnsRVA9B",
      "payout_reference_id": "HK-XYZ",
      "payout_date": "2022-01-01",
      "amount_from_payout_items": 12000,
      "amount_from_adjustments": 1000,
      "fees": 1000,
      "type": "net_of_fees",
      "amount": 12000,
      "currency": "GBP",
      "min_balance": {
        "fixed": 1000,
        "relative": 500,
        "actual": 1000,
        "withheld_amount": 2000,
      },
      "items": [...],
      "adjustments": [...] 
    },
  ]
}  

View Payout

Request

GET /v1/payment/payouts/<payout_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/payouts/<payout_id> \
     --header "Authorization: <your_api_key>"

Responses

  • Regular Response
200 Ok
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/payouts/po-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "po-yQKxbtCg9aTS5JYnsRVA9B",
  "payout_reference_id": "HK-XYZ",
  "payout_date": "2022-01-01",
  "amount_from_payout_items": 12000,
  "amount_from_adjustments": 1000,
  "fees": 1000,
  "type": "net_of_fees",
  "amount": 12000,
  "currency": "GBP",
  "min_balance": {
    "fixed": 1000,
    "relative": 500,
    "actual": 1000,
    "withheld_amount": 2000,
  }, 
  "items": [
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/payout_items/poitm-yQKxbtCg9aTS5JYnsRVA9B",
      "id": "poitm-yQKxbtCg9aTS5JYnsRVA9B",
      "type": "fulfillment",
      "payout": "po-yQKxbtCg9aTS5JYnsRVA9B",
      "deferred_payment": "defpay-yQKxbtCg9aTS5JYnsRVA9B", 
      "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
      "status": "paid",
      "creation_date": "2021-12-26",
      "earliest_payout_date": "2022-01-01",
      "actual_payout_date": "2022-01-01",
      "amount": 1100,
      "fees": 100,
      "amount_net_of_fees": 1000,
      "currency": "GBP",
    },
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/payout_items/poitm-yQKxbtCg9aTS5JYnsRVA9B",
      "id": "poitm-yQKxbtCg9aTS5JYnsRVA9B",
      "type": "fulfillment",
      "payout": "po-yQKxbtCg9aTS5JYnsRVA9B",
      "deferred_payment": "defpay-yQKxbtCg9aTS5JYnsRVA9B",  
      "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
      "status": "paid",
      "earliest_payout_date": "2022-01-01",
      "actual_payout_date": "2022-01-01",
      "amount": 1100,
      "fees": 100,
      "amount_net_of_fees": 1000,
      "currency": "GBP",
    },
  ],
  "adjustments": [
    {
      "id": "poadj-yQKxbtCg9aTS5JYnsRVA9B",
      "type": "credit_review_fee",
      "net_amount": 100,
      "tax_rate": 10,
      "amount": 110,  
      "currency": "GBP",      
    },
    {
      "id": "poadj-yQKxbtCg9aTS5JYnsRVA9B",
      "type": "minimum_fee",
      "net_amount": 200,
      "tax_rate": 10,
      "amount": 220,  
      "currency": "GBP",
    }
  ]  
}
  • Not Found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}

Query Params

GET /v1/payment/payouts?start_date=2022-01-01&end_date=2022-02-01 HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
     --url "https://api-sandbox.hokodo.co/v1/payment/payouts?start_date=2022-01-01&end_date=2022-02-01" \
     --header "Authorization: <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/payout/po-yQKxbtCg9aTS5JYnsRVA9B",
      "id": "po-yQKxbtCg9aTS5JYnsRVA9B",
      "payout_reference_id": "HK-XYZ",
      "payout_date": "2022-01-01",
      "amount_from_payout_items": 12000,
      "amount_from_adjustments": 1000,
      "fees": 1000,
      "type": "net_of_fees",
      "amount": 12000,
      "currency": "GBP",
      "min_balance": {
        "fixed": 1000,
        "relative": 500,
        "actual": 1000,
        "withheld_amount": 2000,
      },
      "items": [...],
      "adjustments": [...] 
    },
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/payout/po-yQKxbtCg9aTS5JYnsRVA9B",
      "id": "po-yQKxbtCg9aTS5JYnsRVA9B",
      "payout_reference_id": "HK-XYZ",
      "payout_date": "2022-01-01",
      "amount_from_payout_items": 12000,
      "amount_from_adjustments": 1000,
      "fees": 1000,
      "type": "net_of_fees",
      "amount": 12000,
      "currency": "GBP",
      "min_balance": {
        "fixed": 1000,
        "relative": 500,
        "actual": 1000,
        "withheld_amount": 2000,
      },
      "items": [...],
      "adjustments": [...] 
    },
  ]
}  

When you want to search for a specific Payout (e.g. a Payout with a certain payout_reference_id) or a specific set of Payouts (e.g. all Payouts from the last quarter), the query params below can be applied to the Payout's endpoint.

param type description
start_date date Include payouts made to your account on or after this date
end_date date Include payouts made to your account on or before this date
payout_reference_id string Only include the Payout with this payout_reference_id

PayoutItem object

{
  "url": "https://api-sandbox.hokodo.co/v1/payment/payout_items/poitm-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "poitm-yQKxbtCg9aTS5JYnsRVA9B",
  "type": "fulfillment",
  "payout": null,  
  "deferred_payment": "defpay-yQKxbtCg9aTS5JYnsRVA9B",  
  "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "status": "scheduled",
  "creation_date": "2021-12-26",
  "earliest_payout_date": "2022-02-01",
  "actual_payout_date": null,
  "amount": 1100,
  "fees": 100,
  "amount_net_of_fees": 1000,
  "currency": "GBP",
}

A Payout typically contains one or more PayoutItems. A PayoutItem provides a direct link between a post sale Order event (e.g. fulfillment, discount, etc.) and the subsequent Payout.

field type description
url string API endpoint to access the PayoutItem
id string(uuid) API identifier for the PayoutItem
type string Type of Order change (e.g. fulfillment) which triggered the creation of this PayoutItem
payout string(uuid) API identifier of the underlying Payout. This will be null for PayoutItems which are scheduled to be paid but haven't been paid yet.
deferred_payment string(uuid) API identifier of the underlying DeferredPayment. To view all fields for this DeferredPayment, include expand=deferred_payment in your request's query params
order string(uuid) API identifier of the underlying Order. To view all fields for this Order, include expand=order in your request's query params
status string Status of the PayoutItem (scheduled or paid)
creation_date date Date the PayoutItem was created
earliest_payout_date date Earliest possible date this item will be paid
actual_payout_date date Actual date this item was paid. This will be null for items which haven't been paid
amount int Total amount of the PayoutItem (i.e. total amount of the underlying Order change) in minor units (cents) before any fees
fees int Fees which have been applied (or will apply) to this PayoutItem in minor units (cents)
amount_net_of_fees int Net amount for this PayoutItem (i.e. amount - fees) in minor units (cents). Note that depending on your payout settings the actual cash paid to you may be the amount or the amount_net_of_fees. This is stated in the Payout payout_structure field
currency string ISO 4217 currency code (e.g. GBP, EUR)

Order Change Type

type description
fulfillment occurs when you notify us of a fulfillment
cancellation occurs when you notify us of a cancellation
return occurs when you notify us of a return
discount occurs when you notify us of a refund/discount
reversal occurs when we reverse back to you a transaction which we have previously financed
settlement used when payouts are linked to customer settlements (may be positive or negative)
chargeback used when payouts are linked to customer settlements & a customer executes a chargeback
other

List PayoutItems

Request

GET /v1/payment/payout_items HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/payout_items \
     --header "Authorization: <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
     {
          "url": "https://api-sandbox.hokodo.co/v1/payment/payout_items/poitm-yQKxbtCg9aTS5JYnsRVA9B",
          "id": "poitm-yQKxbtCg9aTS5JYnsRVA9B",
          "type": "fulfillment",
          "payout": null,  
          "deferred_payment": "defpay-yQKxbtCg9aTS5JYnsRVA9B",
          "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
          "status": "scheduled",
          "creation_date": "2021-12-26",
          "earliest_payout_date": "2022-02-01",
          "actual_payout_date": null,
          "amount": 1100,
          "fees": 100,
          "amount_net_of_fees": 1000,
          "currency": "GBP"
     },
     {   
          "url": "https://api-sandbox.hokodo.co/v1/payment/payout_items/poitm-yQKxbtCg9aTS5JYnsRVA9B",
          "id": "poitm-yQKxbtCg9aTS5JYnsRVA9B",
          "type": "fulfillment",
          "payout": null,  
          "deferred_payment": "defpay-yQKxbtCg9aTS5JYnsRVA9B",
          "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
          "status": "scheduled",
          "creation_date": "2021-12-26",
          "earliest_payout_date": "2022-02-01",
          "actual_payout_date": null,
          "amount": 1100,
          "fees": 100,
          "amount_net_of_fees": 1000,
          "currency": "GBP"
     }
  ]   
}

View PayoutItem

Request

GET /v1/payment/payout_items/<payout_item_id> HTTP/1.1
Authorization: Token <your_api_key>
curl --request GET \
     --url https://api-sandbox.hokodo.co/v1/payment/payout_items/<payout_item_id> \
     --header "Authorization: <your_api_key>"

Responses

  • Regular Response
200 Ok
Content-Type: application/json
{
  "url": "https://api-sandbox.hokodo.co/v1/payment/payout_items/poitm-yQKxbtCg9aTS5JYnsRVA9B",
  "id": "poitm-yQKxbtCg9aTS5JYnsRVA9B",
  "type": "fulfillment",
  "payout": null,  
  "deferred_payment": "defpay-yQKxbtCg9aTS5JYnsRVA9B",
  "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
  "status": "scheduled",
  "creation_date": "2021-12-26",
  "earliest_payout_date": "2022-02-01",
  "actual_payout_date": null,
  "amount": 1100,
  "fees": 100,
  "amount_net_of_fees": 1000,
  "currency": "GBP"
}
  • Not Found
404 Not Found
Content-Type: application/json
{
  "detail": "Not found."
}

Query Params

GET /v1/payment/payout_items?order_unique_id=xxx HTTP/1.1
Content-Type: application/json
Authorization: Token <your_api_key>
curl --request GET \
     --url "https://api-sandbox.hokodo.co/v1/payment/payout_items?order_unique_id=xxx" \
     --header "Authorization: <your_api_key>"

Response

200 Ok
Content-Type: application/json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "url": "https://api-sandbox.hokodo.co/v1/payment/payout_items/poitm-yQKxbtCg9aTS5JYnsRVA9B",
      "id": "poitm-yQKxbtCg9aTS5JYnsRVA9B",
      "type": "fulfillment",
      "payout": null,  
      "deferred_payment": "defpay-yQKxbtCg9aTS5JYnsRVA9B",
      "order": "order-yQKxbtCg9aTS5JYnsRVA9B",
      "status": "scheduled",
      "creation_date": "2021-12-26",
      "earliest_payout_date": "2022-02-01",
      "actual_payout_date": null,
      "amount": 1100,
      "fees": 100,
      "amount_net_of_fees": 1000,
      "currency": "GBP"
    },
  ]
}  

When you want to search for a specific set of PayoutItems (e.g. all PayoutItems attached to a specific Order), the query params below can be applied to the PayoutItems endpoint.

param type description
order_id string(uuid) API identifier for the Order
order_unique_id string(uuid) Unique identifier of the order on your platform
start_date date Include payouts made to your account on or after this date.
end_date date Include payouts made to your account on or before this date.

Webhooks / Notifications / Callbacks

Sample content

Deferred Payment Application Complete

{
    "created": "2021-01-01T12:00:00Z",
    "data": {
        "order": { 
            "id": "order-QWLGzh3ciDXo3P4QkPtrnH",
            "unique_id": "",
            "po_number": "",
            "customer": {
                "organisation": {
                    "id": "org-mSuTHdaodb5pjDmKsBj5Z4",
                    "unique_id": "1",
                    "registered": "2010-06-30T00:00:00Z",
                    "company": null,
                    "users": [
                        "96608083-4783-44e3-a474-4bad3fa6e82a"
                    ]
                },
                "user": {
                    "id": "user-pHm3kfFQXwzs8ND8HYNTYV",
                    "email": "syTnvfVbZjFv@email.com",
                    "unique_id": "",
                    "name": "name_SUUgVUVuRVaB",
                    "phone": "",
                    "registered": "2010-06-30T00:00:00Z",
                    "type": "registered"
                },
                "invoice_address": {
                    "name": "name_LGDZJAFYLRus",
                    "company_name": "company_name_touyMqWkVyAn",
                    "address_line1": "address_line1_gKmCACesrqbd",
                    "address_line2": "address_line2_shliflLciPie",
                    "address_line3": "",
                    "city": "city_edqpaQOKqUXI",
                    "region": "",
                    "postcode": "E1 1D0",
                    "country": "GB",
                    "phone": "",
                    "email": ""
                },
                "delivery_address": {
                    "name": "name_tLoyeGeGMXlc",
                    "company_name": "company_name_DgcvLcFejRbl",
                    "address_line1": "address_line1_XKWMakHAilHa",
                    "address_line2": "address_line2_MzczHXdoRqQR",
                    "address_line3": "",
                    "city": "city_jSjusADEJkuE",
                    "region": "",
                    "postcode": "E1 1D1",
                    "country": "GB",
                    "phone": "",
                    "email": ""
                },
                "billing_address": {
                    "name": "name_LGDZJAFYLRus",
                    "company_name": "company_name_touyMqWkVyAn",
                    "address_line1": "address_line1_gKmCACesrqbd",
                    "address_line2": "address_line2_shliflLciPie",
                    "address_line3": "",
                    "city": "city_edqpaQOKqUXI",
                    "region": "",
                    "postcode": "E1 1D0",
                    "country": "GB",
                    "phone": "",
                    "email": ""
                }
            },
            "created": "2020-11-10T08:31:39.915557Z",
            "currency": "EUR",
            "order_date": "2020-11-10",
            "invoice_date": null,
            "due_date": null,
            "paid_date": null,
            "total_amount": 1000,
            "tax_amount": 200,
            "metadata": null,
            "items": [
                {
                    "item_id": "0",
                    "type": "",
                    "description": "",
                    "metadata": null,
                    "reference": "",
                    "category": "",
                    "supplier_id": "",
                    "supplier_name": "",
                    "quantity": "10.000",
                    "unit_price": 100,
                    "total_amount": 1000,
                    "tax_amount": 200,
                    "tax_rate": "25.00",
                    "fulfilled_quantity": "0.000",
                    "cancelled_quantity": "0.000"
                }
            ],
            "payment_offer": {
                "url": "/v1/payment/offers/offr-SFRufpfb4wMh8Jkr84W8Gf",
                "id": "offr-SFRufpfb4wMh8Jkr84W8Gf",
                "order": "order-QWLGzh3ciDXo3P4QkPtrnH",
                "offered_payment_plans": [
                    {
                        "id": "ppln-E8tWZ3MahpeDp798k9fzVH",
                        "name": "",
                        "template": "pptemp-MNhaDZyoRatSZTyizGTgtb",
                        "currency": "EUR",
                        "scheduled_payments": [
                            {
                                "date": "2021-01-31",
                                "amount": 1000,
                                "allowed_payment_methods": [
                                    {
                                        "type": "direct_debit"
                                    },
                                    {
                                        "type": "invoice"
                                    },
                                    {
                                        "type": "card"
                                    }
                                ],
                                "payment_method": {"type": "invoice"}
                            }
                        ],
                        "merchant_fee": {
                            "currency": "EUR",
                            "amount": 0
                        },
                        "customer_fee": {
                            "currency": "EUR",
                            "amount": 0
                        },
                        "valid_until": "2020-11-17T08:31:40.059Z",
                        "payment_url": "https://api-sandbox.hokodo.co/?order=order-QWLGzh3ciDXo3P4QkPtrnH&plan=ppln-E8tWZ3MahpeDp798k9fzVH&key=cjuHbDjF3txeTaHgtDUilQ9UdYqHllC2iFFarKdJemU&template=pptemp-MNhaDZyoRatSZTyizGTgtb",
                        "status": "offered",
                        "rejection_reason": null
                    }
                ],
                "urls": {
                    "success": "",
                    "failure": "",
                    "cancel": "",
                    "notification": "",
                    "merchant_terms": ""
                },
                "locale": "",
                "metadata": null
            },
            "deferred_payment": {
                "url": "/v1/payment/deferred_payments/defpay-8BvTZ9T6K5gj6LeSqvfqzm",
                "id": "defpay-8BvTZ9T6K5gj6LeSqvfqzm",
                "number": "P-PMNE-DN6C",
                "payment_plan": {
                    "id": "ppln-E8tWZ3MahpeDp798k9fzVH",
                    "name": "",
                    "template": "pptemp-MNhaDZyoRatSZTyizGTgtb",
                    "currency": "EUR",
                    "scheduled_payments": [
                        {
                            "date": "2021-01-31",
                            "amount": 1000,
                            "allowed_payment_methods": [
                                {
                                    "type": "direct_debit"
                                },
                                {
                                    "type": "invoice"
                                },
                                {
                                    "type": "card"
                                }
                            ],
                            "payment_method": {"type": "invoice"}
                        }
                    ],
                    "merchant_fee": {
                        "currency": "EUR",
                        "amount": 0
                    },
                    "customer_fee": {
                        "currency": "EUR",
                        "amount": 0
                    },
                    "valid_until": "2020-11-17T08:31:40.059Z",
                    "payment_url": "https://api-sandbox.hokodo.co/?order=order-QWLGzh3ciDXo3P4QkPtrnH&plan=ppln-E8tWZ3MahpeDp798k9fzVH&key=cjuHbDjF3txeTaHgtDUilQ9UdYqHllC2iFFarKdJemU&template=pptemp-MNhaDZyoRatSZTyizGTgtb",
                    "status": "offered",
                    "rejection_reason": null
                },
                "order": "order-QWLGzh3ciDXo3P4QkPtrnH",
                "outstanding_balance": {
                    "amount": null,
                    "currency": "EUR"
                },
                "next_payment_date": null,
                "payments": null,
                "status": "accepted"
            },
            "status": "draft",
            "pay_method": "unknown"
        }
    }
}

Hokodo uses webhooks to notify your application when an event happens in your account. For example, when one of your customers has their deferred payment application approved.

Webhooks allow you to avoid polling and instead receive notifications when changes related to an Order, Offer or DeferredPayment object occur.

Webhook Payload

The webhook payload will include a full Order object.

field type description
created string Time the notification was sent (e.g. 2021-01-01T12:00:00Z)
data dictionary Dictionary containing the Order object
data[order] dictionary The Order object

The Order object will have the following fields expanded(if available):

Events

You will receive a notification when any of the following events occur:

Please note that the payload for all of the events will contain the latest version of the Order object with the expanded fields (if available) as described above.

Getting Started

1. Select Integration Option

Depending on your use-case Hokodo can configure your account so that all notifications will be sent to the same webhook. Alternatively, when you create an Offer you can include a notification url in the request, and we'll send all notifications related to that specific Offer to this url. Changes to related objects such as the underlying Order or a DeferredPayment will also be sent to this url.

If you prefer the first option please let us know at support@hokodo.co and we will be happy to configure your account.

No additional setup is required if you prefer the second option. Note, if you do select this option, you won't receive any notifications about Order changes until you create an Offer.

2. Secure Your Webhook (optional)

For enhanced security, Hokodo can include an authentication string in the Authorization header of all notifications. If you're interested in this option please let us know at support@hokodo.co

Notes

  1. Your endpoint must be using HTTPS.

  2. In production, our API will verify the validity of the HTTPS certificate. In sandbox, you can use a self-signed certificate.

  3. Our API will send a POST request, with the content of the Order in the POST request body as JSON.

  4. Our API expects a 2xx status code from your endpoint for a successful response.

  5. Our API will retry up to 3 times if it can't connect successfully to your endpoint. It will wait 0, 2, and 4 seconds respectively before the 1st, 2nd and 3rd retry.

Error codes

The Hokodo API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- The requested function is not available for your account.
404 Not Found -- The specified object could not be found.
405 Method Not Allowed -- You tried to access an object with an invalid method.
409 Conflict -- The requested action conflicts with the current state of the object.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

Testing in sandbox

Bypass underwriting engine

To facilitate testing in Sandbox, you can bypass the underwriting engine to create Offers with specific statuses and so test their behaviour in your checkout. This bypasses our Underwriting engine, which determines the Offer status.

To create an Offer with a specific status, you need to create a User with an email corresponding to a specific pattern, and use that User to create your order. For example, if you would like to test an Offer that is rejected during underwriting, set the User email to myuser+paymentplan_declined@mail.com.

Searched pattern Payment Plan Status Example
paymentplan_offered offered sandrine_bouchon+paymentplan_offered@yourdomain.com
paymentplan_declined declined gerard_colins+paymentplan_declined@yourdomain.com
paymentplan_partly_offered one offered, the others declined gerard_colins+paymentplan_partly_offered@yourdomain.com

Bypass fraud engine

To facilitate testing in Sandbox, you can create DeferredPayments with specific statuses and so test their behaviour in your checkout. This bypasses our fraud engine, which determines the DeferredPayment status.

To create a DeferredPayment with a specific status, you need to create a User with an email corresponding to a specific pattern, and use that User to create your order. For example, if you would like to test a DP with an accepted status, set the User email to myuser_dp_fraud_accepted@yourdomain.com.

Searched pattern Deferred Payment Status Example
dp_fraud_accepted accepted sandrine_bouchon+dp_fraud_accepted@yourdomain.com
dp_fraud_rejected rejected gerard_colins+dp_fraud_rejected@yourdomain.com
dp_fraud_customer_action_required customer_action_required dp_fraud_customer_action_required_fatou_ndial@yourdomain.com
dp_fraud_pending_review pending_review kevin_fischer+dp_fraud_pending_review@yourdomain.com

Combine underwriting and fraud pattern

You can combine both patterns to test different combinations of Offer and DeferredPayment status. For example:

Searched pattern Payment Plan Status Deferred Payment Status
paymentplan_offered_dp_fraud_accepted offered accepted
paymentplan_offered_dp_fraud_rejected offered rejected
paymentplan_declined_dp_fraud_accepted declined never get to fraud detection
paymentplan_partly_offered_dp_fraud_pending_review one offered, the others declined pending_review

If the offer is declined, you cannot create a Deferred Payment.

Important note

If two different fraud or payment plan status are found (dp_fraud_accepted_dp_fraud_rejected@mail.com), the first match is taken.

When testing from sandbox, we are sending emails, to properly test: