NAV Navbar

Introduction

Welcome to LeaseCloud API reference site. Please feel free to contact us if you have any questions or feedback.

Here you will find everything you need to develop LeaseCloud modules for different e-commerce platforms or to integrate LeaseCloud in your checkout.

Authorization

Required http header
Authorization: Bearer [bearer token]

All requests requires Authorization header to be set with Bearer [ACCESS_TOKEN]. When you are becoming a partner we will give you a access token and a webhook token

Use this contact form to get a API key or give us a call at +46844688100.

Until we have a signed partner agreement you will use a sandbox API key that is fully functional but doesn’t create live orders.

Data formats

Amount

All amounts will be in the smallest currency amount. E.g. 1 SEK = 100 ören, 1 USD = 100 cent Total amount are excluding VAT eg totalAmount, shippingAmount

Strings

The maximum length of a string may be 255 characters.

Currency

All currencies is in ISO 4217 standard. E.g. SEK, EUR

Country

All Countries are is in ISO 3166 alpha-2. E.g. se = Sweden, no = Norway.

Locale

Must be a language string compliant with RFC 1766

Endpoints

We have 2 different API's: * The checkout API is used to generate and update the chekout * The main API is used to get and update an order after the customer has made the order

Checkout API

API

Checkout

Introduction

LeaseCloud checkout is designed to be used either as a complete checkout solution for leasing only sites or as a payment provider within an existing checkout-flow for sites that wish to provide other payment methods.

The following description describes the initial implementation that will be checkout only.

Endpoints

Partner site setup

The following items need to be setup by the partner in order to integrate with the LeaseCloud checkout.

Page Description
Checkout page A URL to the page used to embed the LeaseCloud checkout. Includes a div that will be populated with HTML code received from the LeaseCloud checkout api.
Confirmation page A URL to the page the LeaseCloud checkout will redirect to when the checkout process completes. leasecloud_order_id={ID} will be added to the url so the order can be fetched and created
Terms and conditions page A URL to the partners terms and conditions that any customer agrees to by purchasing via their site

Starting the checkout process

Before starting the checkout process the customer must have selected one or more items they wish to buy. The partners site may then trigger a checkout by making a http request to the checkout API entry point. The LeaseCloud orderId should be saved by the partner and connected to the checkout (to allow the order to be updated before checkout completion) and the partners checkout page should be displayed with the html code snippet received from the entry point embedded in it.

Completing the checkout process

Once the LeaseCloud checkout process has been successfully completed the customer will be redirected to the confirmation url sent during the initial checkout request. The redirect will also include the GET query parameter leasecloud_order_id containing the orderId.

The partner can then retrieve the completed checkout information via a request to the order API. Note that when the checkout is complete the item may still not be ready to send, the status of the order retrieved is provided in the response and the order should only be dispatched to the customer when the status is OK.

The information will also be synced back to the shop via the notification webhook sent in the initial request to the checkout API entry point.

Updating a checkout process

If the customer does not fulfill the checkout process and returns to the shop to modify items or shipping information. The partners site can update the order on the LeaseCloud checkout by performing a http request containing the new information to the LeaseCloud checkout API update end point.

Checkout API entry point

POST /v1/orders HTTP/1.1
Content-Type: application/json
Authorization: Bearer [bearer token]
Request body example
{
  "totalAmount": 12000,
  "shippingAmount": 0,
  "shippingVAT": 0,
  "currency": "SEK",
  "locale": "sv-se",
  "country": "SE",
  "VAT": 0,
  "months": 24,
  "items":
  [
    {
      "name": "MacBook Pro 15",
      "productId": "13",
      "articleNr": "NCC-5347XF",
      "quantity": 1,
      "unitAmount": 3400000,
      "totalAmount": 3400000,
      "VAT": 0
    },
    {
      "name": "iPhone X",
      "productId": "233",
      "articleNr": "ABC-53RF7XF",
      "quantity": 2,
      "unitAmount": 1200000,
      "totalAmount": 2400000,
      "VAT": 0
    }
  ],
  "partner": {
    "name": "Permånad",
    "domain": "permanad.se",
    "urls": {
      "terms": "https://permanad.se/terms",
      "checkout": "https://permanad.se/checkout",
      "confirmation": "https://permanad.se/yay/you/did/it"
    }
  },
  "reseller": {
    "id": "VAT_NR",
    "name": "Store name AB"
  }
}
Response body
{
  "html": "<div id=’leasecloud_leaseflow_container’>
        <script>(function() {
          // Some script to load the iframe into the page
          var conf = {
            orderID: '1293u924972439'
          }
          createElement(script)
        })()</script>
        <noscript>Please <a href=’https://enable-javascript.com/’>enable javascript</a>.</noscript>
      </div>",
  "orderId": "1293u924972439"
}
Error response body
{
  "error": {
    "code": "InvalidOrder",
    "message": "Validation error",
    "fields": [
      {
        "title": "notNull Violation",
        "message": "totalAmount cannot be null",
        "field": "totalAmount"
      },
    ]
  }
}

HTTP Request

POST /v1/orders

HTTP Body

The body of the http request contains the order information.

Parameter Type Required Description
partner object ✔︎ An object containing information relevant to the partner
• name string ✔︎ The display name to be used for the partner in the checkout
• domain string ✔︎ The name of the top domain that will be hosting the checkout
• urls object ✔︎ An object containing urls to the relevant partner pages
  • terms string ✔︎ The terms and conditions url
  • checkout string ✔︎ The checkout page url
  • confirmation string ✔︎ The confirmation page url
reseller object An object containing information relevant to the reseller
• id string A unique id to the reseller, used later to fetch more info
• name string The display name to be used in the checkout
totalAmount integer ✔︎ Total amount the customer will pay excluding VAT
Minimum 600000 cent
VAT integer ✔︎ Total VAT amount
shippingAmount integer ✔︎ The shipping cost (excluding VAT)
shippingVAT integer ✔︎ The shipping cost VAT
currency enum ✔︎ In which currency is the amounts. We only support SEK at the moment
locale enum ✔︎ Purchase language string compliant with RFC 1766
country enum ✔︎ The purchase country 2 letter code e.g. SE
months integer The leasing period in months, if known
items Item object ✔︎ See below

Item object

The items object contains an array of items.

Bundled items

When items are part of a bundle, a bundle id should be created for the bundle and the bundle should be added to the items array as if it was a normal item. The items that make up the bundle should also be added to the array but with a 0 for toal cost and a bundle id attribute linking to the bundle.

Parameter Type Required Description
name string ✔︎ Name / title of the product
productId string ✔︎ Product id
articleNr string Article number
bundleId string If the item is part of a bundle or is the bundle add the id
quantity integer ✔︎ Quantity
unitAmount integer ✔︎ Price for a single unit ex VAT
totalAmount integer ✔︎ Total amount (quantity * unitAmount) ex VAT
VAT integer ✔︎ VAT for the total amount

HTTP Response

Parameter Type Description
html string The HTML snippet to load the checkout iframe
orderId string The leasecloud order id

Checkout API update endpoint

PATCH /v1/orders/{orderId} HTTP/1.1
Content-Type: application/json
Authorization: Bearer [bearer token]
Request body example
{
  "totalAmount": 12000,
  "shippingAmount": 0,
  "shippingVAT": 0,
  "currency": "SEK",
  "locale": "sv-se",
  "country": "SE",
  "VAT": 0,
  "months": 36,
  "items":
  [
    {
      "name": "MacBook Pro 15",
      "productId": "13",
      "quantity": 1,
      "unitAmount": 3400000,
      "totalAmount": 3400000,
      "VAT": 0
    },
    {
      "name": "iPhone X",
      "productId": "233",
      "quantity": 2,
      "unitAmount": 1200000,
      "totalAmount": 2400000,
      "VAT": 0
    }
  ],
  "partnerUrls": {
    "terms": "https://www.example.se/terms",
    "checkout": "https://www.example.se/checkout",
    "confirmation": "https://www.example.se/confirmation"
  }
}
Response body
{
  "html": "<div id=’leasecloud_leaseflow_container’>
        <script>(function() {
          // Some script to load the iframe into the page
          var conf = {
            orderID: '1293u924972439'
          }
          createElement(script)
        })()</script>
        <noscript>Please <a href=’https://enable-javascript.com/’>enable javascript</a>.</noscript>
      </div>",
  "orderId": "1293u924972439"
}
Error response body
{
  "error": {
    "code": "InvalidOrder",
    "message": "Validation error",
    "fields": [
      {
        "title": "notNull Violation",
        "message": "totalAmount cannot be null",
        "field": "totalAmount"
      },
    ]
  }
}

HTTP Request

POST /v1/orders/{orderId}

HTTP Body

Same as create

HTTP Response

Same as create

Orders API

Orders API provides endpoints for retreiving and manipulating orders after they have been added to leasecloud via the checkout API.

Endpoints

Retrieve an order

GET /v2/orders/{orderId} HTTP/1.1
Content-Type: application/json
Authorization: Bearer [bearer token]
Response body
{
  "id": "c1f0acd8-8e3e-4477-85d3-18337c3c92d6",
  "orgNumber": "5590894308",
  "status": "PENDING",
  "totalAmount": 23323,
  "VAT": 32,
  "shippingAmount": 0,
  "shippingVAT": 0,
  "currency": "SEK",
  "months": 24,
  "billing": {
    "firstName": "Ora",
    "lastName": "Roob",
    "email": "Myrtice70@yahoo.com",
    "phone": "(719) 365-7934 x29126",
    "company": "Langosh, Kautzer and Ullrich",
    "address": "1532 Edna Spring",
    "address2": "",
    "city": "East Guidofort",
    "state": "",
    "postalCode": "17875",
    "country": "SE"
  },
  "shipping": {
    "firstName": "Brigitte",
    "lastName": "Wunsch",
    "email": "Jon60@gmail.com",
    "phone": "803-546-0329",
    "company": "Volkman - Goodwin",
    "address": "46995 Sandra Green",
    "address2": "",
    "city": "South Aileenfurt",
    "state": "",
    "postalCode": "47920",
    "country": "SE"
  },
  "items": [
    {
      "name": "MacBook Pro 15",
      "productId": "13",
      "articleNr": "NCC-5347XF",
      "quantity": 1,
      "unitAmount": 3400000,
      "totalAmount": 3400000,
      "VAT": 0
    },
    {
      "name": "iPhone X",
      "productId": "233",
      "articleNr": "ABC-5347XF",
      "quantity": 2,
      "unitAmount": 1200000,
      "totalAmount": 2400000,
      "VAT": 0
    }
  ],
  "createdAt": "2018-01-03T15:10:00.000Z",
  "updatedAt": "2018-01-03T15:10:00.000Z"
}

To retrieve a order after checkout has been completed make a GET request /v2/orders/{orderId}

An order information will be returned, including it's current status. See example on right.

Order statuses

Status Description
PENDING The order has been received but the customer has not signed or the leasing company has not yet authorized the transaction. The order should not be shipped
OK All requirements have been forfilled and the order can be shipped
DONE The order has been forfilled and the contract started, changes are no longer possible by the partner
CANCELLED The order has been cancelled

Cancel an order

POST /v2/orders/{orderId}/cancel HTTP/1.1
Authorization: Bearer [bearer token]

To cancel an order make a POST request /v2/orders/{orderId}/cancel which will respond with 200 and an empty body

An order can be canceled until the user has signed the order

Order shipped

POST /v2/orders/{orderId}/shipped HTTP/1.1
Authorization: Bearer [bearer token]
(Optional) Request body example
{
  "shippedAt": "2017-07-20T13:37:00.000Z"
}

Make a POST request to /v2/orders/{orderId}/shipped when an order has been shipped. When the request is received we will set the current time as the shipped date and time but you can send the body shippedAt and ISO-8601 date to override the date.

Parameter Type Required Description
shippedAt string Date and time shipped ISO-8601

Webhooks

POST https://example.com/my/callback/ HTTP/1.1
LeaseCloud-Version: 1.0.0
LeaseCloud-Signature: t=1499785732,v1=[HMAC_SHA-256_PAYLOAD],v1=[HMAC_SHA-256_PAYLOAD_OLD]

Request body

{
  "id": "UNIQUE_EVENT_ID",
  "action": "NAME_OF_ACTION",
  "data": {
    "FIELDS": "FOR ACTION"
  }
}

Request body

{
  "id": "UNIQUE_EVENT_ID",
  "processed": true|false
}

Example to generate webhook signature

<?php hash_hmac("sha256", "${TIMESTAMP}.${PAYLOAD}", WEBHOOK_SECRET);

When becoming a partner we will ask for a url endpoint where we will make post requests to with updates. Webhooks are used to communicate events from leasecloud back to the partners site. They always contain the same datastructure.

We will make a POST request to the endpoint with a JSON body

The signature is generated with the timestamp found in the LeaseCloud-Signature header combined with a . and the payload.

Response body

You have to return the event ID to sigal that you have received and processed the webhook. We also prefer if you set processed if you processed the hook or just acknowledged the hook.

Order status updated

Request body

{
  "id": "evt:e1f0aed8-883a-9751-74a3-48537d3d94ce",
  "action": "order.created",
  "data": {
    "id": "c1f0acd8-8e3e-4477-85d3-18337c3c92d6",
    "orgNumber": "5590894308",
    "status": "PENDING",
    "totalAmount": 23323,
    "VAT": 32,
    "shippingAmount": 0,
    "shippingVAT": 0,
    "currency": "SEK",
    "months": 24,
    "billing": {
      "firstName": "Ora",
      "lastName": "Roob",
      "email": "Myrtice70@yahoo.com",
      "phone": "(719) 365-7934 x29126",
      "company": "Langosh, Kautzer and Ullrich",
      "address": "1532 Edna Spring",
      "address2": "",
      "city": "East Guidofort",
      "state": "",
      "postalCode": "17875",
      "country": "SE"
    },
    "shipping": {
      "firstName": "Brigitte",
      "lastName": "Wunsch",
      "email": "Jon60@gmail.com",
      "phone": "803-546-0329",
      "company": "Volkman - Goodwin",
      "address": "46995 Sandra Green",
      "address2": "",
      "city": "South Aileenfurt",
      "state": "",
      "postalCode": "47920",
      "country": "SE"
    },
    "items": [
      {
        "name": "Towels",
        "productId": "23",
        "articleNr": "NCC-5347XF",
        "quantity": 42,
        "unitAmount": 34,
        "totalAmount": 8400,
        "VAT": 0
      },
      {
        "name": "NOPE",
        "productId": "233",
        "articleNr": "NCC-5347XF",
        "quantity": 42,
        "unitAmount": 34,
        "totalAmount": 8400,
        "VAT": 0
      }
    ],
    "createdAt": "2018-01-03T15:10:00.000Z",
    "updatedAt": "2018-01-03T15:10:00.000Z"
  }
}

Order status updated

Partner response body
{
  "id": "evt:e1f0aed8-883a-9751-74a3-48537d3d94ce"
}

We will make a POST request to the notification WebHook endpoint provided in the initial checkout request every time the order status is updated.

The signature is generated with the timestamp found in the LeaseCloud-Signature header combined with a . and the payload

An example of the request body is provided on the right

The webhook will be repeatedly called until the partner acknowledges receipt. Acknowledgement is achieved by the store replying to the webhook with a 200 response, and a json object containing the leasecloud webhook id.

Actions

Errors


{
  "error": {
    "code": "OrderCantBeModified",
    "message": "It's to late to edit the order",
  }
}

LeaseCloud are using rest status codes

If there is an error we will return a 4xx or 5xx status code

The response will be a json object only containing an error object.

The error object will always contain code and message and in the case of InvalidOrder it will also contain fields which is an array of invalid fields.

Codes:

Default responses

Custom errors

{
  "error": {
    "code": "InvalidOrder",
    "message": "Validation error",
    "fields": [
      {
        "message": "totalAmount cannot be null",
        "field": "totalAmount"
      }
    ]
  }
}

Fields

Names * required: a required field is missing * type: a required field is of the wrong type