NAV Navbar
Logo

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.

SDK

Plugins

Authorization

Required http header

Authorization: Bearer [bearer token]

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

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

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

Strings

The maximum length a string may be is 255 characters.

Currency

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

Country

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

Orders

Create a new order

POST /v1/orders HTTP/1.1
Content-Type: application/json
Authorization: Bearer [bearer token]

Request body example

{
  "orderId": "c8e0bda3-dbe0-55ad-8de7-4b341fab49a3",
  "firstName": "Matthew",
  "lastName": "Hunter",
  "company": "LeaseCloud AB",
  "orgNumber": "559089-4308",
  "email": "hello@leasecloud.com",
  "authorizedSignatory": null,
  "phone": "09 61 64 48 49",
  "customerIp": "131.168.20.70",
  "totalAmount": 1010000,
  "VAT": 252500,
  "shippingAmount": 10000,
  "shippingVAT": 2500,
  "currency": "SEK",
  "months": 24,
  "tariff": 1.1,
  "billing": {
    "address": "Mystreet 121",
    "address2": null,
    "city": "Stockholm",
    "state": null,
    "postalCode": "12345",
    "country": "SE"
  },
  "shipping": {
    "firstName": null,
    "lastName": null,
    "company": null,
    "address": null,
    "address2": null,
    "city": null,
    "state": null,
    "postalCode": null,
    "country": null,
  },
  "customerMessage": "I like cookies!",
  "items": [
    {
      "name": "Shiny new phone",
      "productId": "32832849-23cc-550c-9456-06ea2ff0b55c",
      "quantity": 2,
      "unitAmount": 250000,
      "totalAmount": 500000,
      "VAT": 125000
    },
    {
      "name": "40\" TV",
      "productId": "88624a25-e7e8-5da4-a819-8af8f5079ce2",
      "quantity": 1,
      "unitAmount": 500000,
      "totalAmount": 500000,
      "VAT": 125000
    }
  ]
}

Response body

{
  "orderId": "c8e0bda3-dbe0-55ad-8de7-4b341fab49a3",
  "monthlyAmount": 50500
}

Error response body

{
  "error": {
    "code": "InvalidOrder",
    "message": "Validation error",
    "fields": [
      {
        "title": "notNull Violation",
        "message": "orderId cannot be null on orderId",
        "field": "orderId"
      },
      {
        "message": "A valid organisation number is required e.g. xxxxxx-xxxx on orgNumber",
        "field": "orgNumber"
      }
    ]
  }
}

HTTP Request

POST /v1/orders

Order object

Parameter Type Required Description
orderId string ✔︎ A unique ID for the order
firstName string ✔︎ Given name
lastName string ✔︎ Family name
company string ✔︎ Name of the company
orgNumber string ✔︎ Company organisation number 000000-0000
email string ✔︎ Valid email address
authorizedSignatory string Email of the person authorized to sign the contract
phone string ✔︎ Phone number
customerIp string ✔︎ IP of the customer (for extra fraud check)
totalAmount integer ✔︎ Total amount the customer will pay Ex. VAT
Minimum 6000 * 100
VAT integer ✔︎ Total VAT amount
shippingAmount integer ✔︎ The shipping cost
shippingVAT integer ✔︎ The shipping cost VAT
currency enum ✔︎ In which currency are the amounts. We only support SEK at the moment
months integer ✔︎ How many months the customer want to lease for
tariff decimal ✔︎ Current tariff at the time of purchase
billing object ✔︎ An object containing the billing fields below
• address string ✔︎ The street address
• address2 string Second street address line
• city string ✔︎ City
• state string State if applicable
• postalCode string ✔︎ Postal code
• country string ✔︎ Country 2 letter code e.g. SE
shipping object An object containing the shipping fields below
• firstName string Given name
• lastName string Family name
• company string Company name
• address string Street address
• address2 string Street address line 2
• city string City
• state string State if applicable
• postalCode string Postal code
• country string Country 2 letter code e.g. SE
customerMessage string If the user left a custom message
items Item object ✔︎ See below

Item object

Parameter Type Required Description
name string ✔︎ Name / title of the product
productId string ✔︎ Product 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
sku string Stock Keeping Unit
variationId string Variation id
serialNumber string Serial number of the product

Cancel an order

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

To cancel an order make a POST request /v1/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 /v1/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 /v1/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.

We will then send a confirmation email where the customer sign that they have received the package and the order is completed.

Get order status

GET /v1/orders/{orderId}/status HTTP/1.1
Authorization: Bearer [bearer token]
{
  "statuses": [
    {
      "code": "ACCEPTED",
      "setAt": "2017-10-04T13:55:16.000Z",
      "message": null
    }, {
      "code": "SIGNED",
      "setAt": null,
      "message": null
    }, {
      "code": "SHIPPED",
      "setAt": null,
      "message": null
    }, {
      "code": "DELIVERY_APPROVED",
      "setAt": null,
      "message": null
    }, {
      "code": "DECLINED",
      "setAt": "2017-10-05T13:37:12.000Z",
      "message": "Not credit worthy"
    }, {
      "code": "CANCELLED",
      "setAt": null,
      "message": null
    }
  ]
}

Get the current status for an order

Status Description
ACCEPTED The order has been accepted and is waiting for the customer to sign the agreement
SIGNED The customer has signed and the order can be shipped
DELIVERY_APPROVED The customer has signed that the order has arrived
DECLINED The order has been declined
CANCELLED The order has been cancelled

Config

Get current config

GET /v1/config HTTP/1.1
Authorization: Bearer [bearer token]

Response body

{
  "financeCompany": {
    "name": "Montly Leasing",
    "logo": "https://example.com/logo.svg"
  },
  "tariffs": [  
    {  
      "months": 24,
      "tariff": 1.47
    },
    {  
      "months": 36,
      "tariff": 1.04
    }
  ]
}

Config contains tariffs and info about the finance company

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]

{
  "id": "UNIQUE_EVENT_ID"
  "action": "NAME_OF_ACTION",
  "data": {
    "FIELDS": "FOR ACTION"
  }
}
<?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.

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

We will make up to 12 attempts to deliver the webhook with exponential delay up to 7 days from first try. Returns 200 http status for success else we assume it failed.

Events

Order accepted

{
  "id": "evt:sdfgkjshdfg87oihsjdgfb",
  "action": "order.accepted",
  "data": {
    "orderId": 42
  }
}

When we have accepted an order and awaiting the customer to sign the agreement

Order declined

{
  "id": "evt:askjshdfg54fsjdgfb",
  "action": "order.declined",
  "data": {
    "orderId": 42,
    "reason": "Customer is not credit worthy"
  }
}

The order is declined

Order signed

{
  "id": "evt:sdfgkjshdfg87oihsjdgfb",
  "action": "order.signed",
  "data": {
    "orderId": 42
  }
}

The customer has signed and the shop can ship the products

Order delivery has been approved

{
  "id": "evt:sdfgkjshdfg87oihsjdgfb",
  "action": "order.deliveryApproved",
  "data": {
    "orderId": 42
  }
}

The customer has confirmed that the products has arrived

Updated tariffs

{
  "id": "evt:dsfsdf55ds3dgfb",
  "action": "tariff.updated",
  "data": {
    "tariffs": [
      {
        "months": 24,
        "tariff": 1.51
      },
      {
        "months": 36,
        "tariff": 1.01
      }
    ]
  }
}

When the tariff changes

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": [
      {
        "field": "billing.address",
        "message": "billing.address can't be null"
      },
      {
        "field": "orgNumber",
        "code": "OrgNumberNotFound",
        "message": "xxxxxx-xxxx is not a registered organization number"
      }
    ]
  }
}

Fields