NAV Navbar
Logo
cURL Ruby PHP

ShopRunBack API Documentation

Welcome on the ShopRunBack public API documentation.

ShopRunBack is the inventor of the Return As A Service solution.

This API provides all the endpoints for any e-commerce retailer to get all the features for an optimized return experience for its customers.

You can also get the swagger documentation on http://api-portal.shoprunback.com.

For feature request, use the built in form: https://dashboard.shoprunback.com/features

If you are coding in PHP, please use our PHP library.

If you got any questions, send an email to: tech_at_shoprunback.com.

Authentication

To authorize your queries, you must provide your company API Token in the HTTP Headers like this:

response = HTTParty.post(
              endpoint,
              body: content,
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )
curl "<endpoint>"
  -H "Authorization: Token token=<your_token>"

<?php
// Load the library
require 'path/to/lib/shoprunback-php/init.php';

// Set your token
\Shoprunback\RestClient::getClient()->setToken('your_token');

// Define the environment you want to use (Production or Sandbox)
\Shoprunback\RestClient::getClient()->useProductionEnvironment();

// Here your token is already set
// You can check if your token is correct by loading your ShopRunBack account
$account = \Shoprunback\Elements\Account::getOwn();

Replace your_token with your API key.

We use API keys to allow access to the API.

You can get your API key on the dashboard.

ShopRunBack expects for the API key to be included in all API requests to the server in a header that looks like the following:

Authorization: Token token=<your_token>

Products catalog

Once your account created and configured (follow the onboarding process for that), you must push your products catalog. Only products in the ShopRunBack catalog can be returned.

First, create your brands if you have any and then create your products.

Create a brand

body = {
  name: "Apple",
  reference: "apple"
}

HTTParty.post(
              "https://dashboard.shoprunback.com/api/v1/brands",
              body: body,
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )
curl -X "POST" "https://dashboard.shoprunback.com/api/v1/brands" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d $'{
  "name": "Apple",
  "reference": "apple"
}'

<?php
// Load the library
require 'path/to/lib/shoprunback-php/init.php';

// Set your token
\Shoprunback\RestClient::getClient()->setToken('your_token');

// Define the environment you want to use (Production or Sandbox)
\Shoprunback\RestClient::getClient()->useProductionEnvironment();

// Create a new blank Brand and add mandatory attributes
$brand = new \Shoprunback\Elements\Brand();
$brand->name = 'Apple';
$brand->reference = 'apple';

// Save the Brand
$brand->save();

The above command returns JSON structured like this:

{
  "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
  "name": "Apple",
  "reference": "apple",
  "default": false
}

By default, once your retailer account is created and your company details entered, a default Brand is created. But you can add your own Brands if you have multiple Brands in your catalog.

This endpoint creates a new Brand.

HTTP Request

POST https://dashboard.shoprunback.com/api/v1/brands

Query Parameters

Parameter Required Description
name yes Name of the brand, displayed to the customer on the return process
reference yes Unique reference of the brand (if you don’t have any, use the name)

List your brands

HTTParty.get(
              "https://dashboard.shoprunback.com/api/v1/brands",
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )
curl -X "GET" "https://dashboard.shoprunback.com/api/v1/brands" \
     -H "Authorization: Token token=<your_token>" \
<?php
// Load the library
require 'path/to/lib/shoprunback-php/init.php';

// Set your token
\Shoprunback\RestClient::getClient()->setToken('your_token');

// Define the environment you want to use (Production or Sandbox)
\Shoprunback\RestClient::getClient()->useProductionEnvironment();

// Get all your brands
$brands = \Shoprunback\Elements\Brand::all();

The above command returns JSON structured like this:

[
  {
    "id": "1f27f9d9-3b5c-4152-98b7-760f56967deb",
    "name": "default",
    "reference": "default",
    "default": true,
  },
  {
    "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
    "name": "Apple",
    "reference": "apple",
    "default": false,
  },
  {
    "id": "1f27f9d9-3b5c-4152-98b7-760f56967dec",
    "name": "Samsung",
    "reference": "samsung",
    "default": false,
  }
]

This endpoint lists all your brands.

HTTP Request

GET https://dashboard.shoprunback.com/api/v1/brands

Add your products

body = {
  "label": "Iphone 14S Blue",
  "reference": "IPHONE 14S B",
  "ean": "1258987561456",
  "weight_grams": 200,
  "brand_id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
  "image_url": "http://www.apple.com/images/iphone-14s.jpg"
}

HTTParty.post(
              "https://dashboard.shoprunback.com/api/v1/products",
              body: body,
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )
curl -X "POST" "https://dashboard.shoprunback.com/api/v1/products" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d $'{
  "label": "Iphone 14S Blue",
  "reference": "IPHONE 14S B",
  "ean": "1258987561456",
  "weight_grams": 200,
  "brand_id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
  "picture_file_url": "http://www.apple.com/images/iphone-14s.jpg"
}'

<?php
// Load the library
require 'path/to/lib/shoprunback-php/init.php';

// Set your token
\Shoprunback\RestClient::getClient()->setToken('your_token');

// Define the environment you want to use (Production or Sandbox)
\Shoprunback\RestClient::getClient()->useProductionEnvironment();

// Create a new Product
$product = new \Shoprunback\Elements\Product();
$product->label = 'Iphone 14S Blue';
$product->reference = 'IPHONE 14S B';
$product->weight_grams = 200;
$product->brand_id = '1f27f9d9-3b5c-4152-98b7-760f56967dea';
$product->ean = '1258987561456';
$product->picture_url = 'https://s3.eu-central-1.amazonaws.com/shoprunback-dev/products/484/7b4/f4-/pictures/medium.?1505912197';

// Save the Product
$product->save();

The above command returns the same JSON object with the id of the created product:

{
  "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
  "label": "Iphone 14S Blue",
  "reference": "IPHONE 14S B",
  "ean": "1258987561456",
  "weight_grams": 200,
  "picture_url": "https://s3.eu-central-1.amazonaws.com/shoprunback-dev/products/484/7b4/f4-/pictures/medium.?1505912197",
  "brand": {
    "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
    "name": "Apple",
    "reference": "apple"
  }
}

Push all your products’ catalog with this endpoint.

The image in not mandatory but the return experience of your customer will be better with it.

HTTP Request

POST https://dashboard.shoprunback.com/api/v1/products

Query Parameters

Parameter Required Description
label yes Label of the product (ie. common name)
reference yes unique reference in your catalog
weight_grams yes weight (grams) of the product (package included)
ean no barcode
brand_id no if you have created a brand and this product has this brand. Otherwise, the default brand is automaticaly used
picture_file_url no public URL to the product image (JPG or PNG), to avoid imperfect cropping, use a square image
picture_file_base64 no if your product’s image is not hosted on the internet, you can provide it with a base64 version of it

Create a product with its brand

body = {
  "label": "Iphone 14S Blue",
  "reference": "IPHONE 14S B",
  "ean": "1258987561456",
  "brand": {
    "name": "Apple",
    "reference": "apple"
  },
  "image_url": "http://www.apple.com/images/iphone-14s.jpg"
}

HTTParty.post(
              "https://dashboard.shoprunback.com/api/v1/products",
              body: body,
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )
curl -X "POST" "https://dashboard.shoprunback.com/api/v1/products" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d $'{
  "label": "Iphone 14S Blue",
  "reference": "IPHONE 14S B",
  "ean": "1258987561456",
  "weight_in_grams": 200,
  "brand": {
    "name": "Apple",
    "reference": "apple"
  },
  "picture_file_url": "http://www.apple.com/images/iphone-14s.jpg"
}'

<?php
// Load the library
require 'path/to/lib/shoprunback-php/init.php';

// Set your token
\Shoprunback\RestClient::getClient()->setToken('your_token');

// Define the environment you want to use (Production or Sandbox)
\Shoprunback\RestClient::getClient()->useProductionEnvironment();

// Create a Brand for your Product
$brand = new \Shoprunback\Elements\Brand();
$brand->name = 'Apple';
$brand->reference = 'apple';

// Create a new Product
$product = new \Shoprunback\Elements\Product();
$product->label = 'Iphone 14S Blue';
$product->reference = 'IPHONE 14S B';
$product->weight_grams = 200;
$product->brand = $brand;
$product->ean = '1258987561456';
$product->picture_url = 'https://s3.eu-central-1.amazonaws.com/shoprunback-dev/products/484/7b4/f4-/pictures/medium.?1505912197';

// Save the Product
$product->save();

The above command returns the same JSON object with the id of the created product:

{
  "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
  "label": "Iphone 14S Blue",
  "reference": "IPHONE 14S B",
  "ean": "1258987561456",
  "brand": {
    "id": "20d0be72-a191-4eb8-af22-9dd4c3e65fe8",
    "name": "Apple",
    "reference": "apple"
  },
  "weight_grams": 200,
  "picture_url": "https://s3.eu-central-1.amazonaws.com/shoprunback-dev/products/484/7b4/f4-/pictures/medium.?1505912197"
}

You can create your product directly with the brand object embedded.

The image in not mandatory but the return experience is better with it.

HTTP Request

POST https://dashboard.shoprunback.com/api/v1/products

Query Parameters

Parameter Required Description
label yes Label of the product (ie. common name)
reference yes unique reference in your catalog
weight_grams yes weight (grams) of the product (package included)
ean no barcode
color no displayed as is on the web return process (no translation)
brand no the brand object with all its required attributes
picture_file_url no public URL to the product image (JPG or PNG), to avoid imperfect cropping, use a square image
picture_file_base64 no if your product’s image is not hosted on the internet, you can provide it with a base64 version of it

List your products

HTTParty.get(
              "https://dashboard.shoprunback.com/api/v1/products",
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )
curl -X "GET" "https://dashboard.shoprunback.com/api/v1/products?page=1" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8" \

<?php
// Load the library
require 'path/to/lib/shoprunback-php/init.php';

// Set your token
\Shoprunback\RestClient::getClient()->setToken('your_token');

// Define the environment you want to use (Production or Sandbox)
\Shoprunback\RestClient::getClient()->useProductionEnvironment();

// Get all your products
$products = \Shoprunback\Elements\Product::all();

The above command returns JSON structured like this:

{
  "pagination": {
    "current_page": 1,
    "first_page": 1,
    "previous_page": null,
    "next_page": null,
    "last_page": 1,
    "count": 5,
    "per_page": 10
  },
  "products":
    [
      {
        "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
        "label": "Iphone 14S Blue",
        "reference": "IPHONE 14S B",
        "ean": "1258987561456",
         "brand": {
            "id": "20d0be72-a191-4eb8-af22-9dd4c3e65fe8",
            "name": "Apple",
            "reference": "apple"
          },
        "picture_url": "http://s3.amazonaws/assets/iphone_14s.jpg"
      },
      {...},
      {
        "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
        "label": "Iphone 14S Red",
        "reference": "IPHONE 14S B",
        "ean": "1258987561456",
         "brand": {
            "id": "20d0be72-a191-4eb8-af22-9dd4c3e65fe8",
            "name": "Apple",
            "reference": "apple"
          },
        "picture_url": "http://s3.amazonaws/assets/iphone_14s.jpg"
      }
    ]
}

You can list all your products on ShopRunBack with this endpoint.

The result is paginated, provide the page parameter to get a specific page (default is page 1).

HTTP Request

GET https://dashboard.shoprunback.com/api/v1/products?page=1

Order

Once your catalog is uploaded on ShopRunBack, you can plug your e-commerce website to the ShopRunBack dashboard.

Only an existing order can be returned. You have 2 possibilities, depending on your desired return flow :

In both cases, you will have to create the order, sooner or later.

Create an order

body = {
  "ordered_at": "2017-02-03",
  "order_number": "4548-9854",
  "customer": {
    "first_name": "Steve",
    "last_name": "Jobs",
    "email": "steve@apple.com",
    "phone": "555-878-456",
    "address": {
      "line1": "One Infinite Loop",
      "line2": "Building B",
      "zipcode": "95014",
      "country_code": "US",
      "city": "Cupertino",
      "state": "California"
    }
  },
  "items": [
    {
      "product_id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
    },
  ],
  "metadata": {
    "foo": "bar",
    "bar": "foo"
  }
}

HTTParty.post(
              "https://dashboard.shoprunback.com/api/v1/orders",
              body: body,
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )
curl -X "POST" "https://dashboard.shoprunback.com/api/v1/orders" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d $'{
  "ordered_at": "2017-02-03",
  "order_number": "4548-9854",
  "customer": {
    "first_name": "Steve",
    "last_name": "Jobs",
    "email": "steve@apple.com",
    "phone": "555-878-456",
    "address": {
      "line1": "One Infinite Loop",
      "line2": "Building B",
      "zipcode": "95014",
      "country_code": "US",
      "city": "Cupertino",
      "state": "California"
    }
  },
  "items":
  [
    {
      "product_id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
    },
    {
      "product_id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
    }
  ],
  "metadata": {
    "foo": "bar",
    "bar": "foo"
  }
}'
<?php
// Load the library
require 'path/to/lib/shoprunback-php/init.php';

// Set your token
\Shoprunback\RestClient::getClient()->setToken('your_token');

// Define the environment you want to use (Production or Sandbox)
\Shoprunback\RestClient::getClient()->useProductionEnvironment();

// Create an Address for the Customer
$address = new \Shoprunback\Elements\Address();
$address->country_code = 'US';
$address->line2 = 'Building B';
$address->state = 'California';
$address->line1 = 'One Infinite Loop';
$address->zipcode = '95014';
$address->city = 'Cupertino';

// Create a Customer for the Order
$customer = new \Shoprunback\Elements\Customer();
$customer->email = 'steve@apple.com';
$customer->phone = '555-878-456';
$customer->first_name = 'Steve';
$customer->last_name = 'Jobs';
$customer->address = $address;

// Create an array of Items ordered by the Customer
$item = new \Shoprunback\Elements\Item();
$item->product_id = '1f27f9d9-3b5c-4152-98b7-760f56967dea';
$items = [$item];

// Create an Order
$order = new \Shoprunback\Elements\Order();
$order->order_number = '4548-9854';
$order->customer = $customer;
$order->items = $items;
$order->ordered_at = '2017-02-03';

// We save the Order
$order->save();

The above command returns the same JSON object with the id of the created order, customer and items:

{
  "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
  "ordered_at": "2017-02-03",
  "order_number": "4548-9854",
  "customer": {
    "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
    "first_name": "Steve",
    "last_name": "Jobs",
    "email": "steve@apple.com",
    "phone": "555-878-456",
    "address": {
      "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
      "line1": "One Infinite Loop",
      "line2": "Building B",
      "zipcode": "95014",
      "country_code": "US",
      "city": "Cupertino",
      "state": "California"
    }
  },
  "items": [
    {
      "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
      "product": {
        "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
        "label": "Iphone 14S Red",
        "reference": "IPHONE 14S B",
        "ean": "1258987561456",
        "brand_id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
        "brand_name": "Apple",
        "picture_url": "http://s3.amazonaws/assets/iphone_14s.jpg"
      }
    },
    {
      "id": "1f27f9d9-3b5c-4152-98b7-760f56967dec",
      "product": {
        "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
        "label": "Iphone 14S Red",
        "reference": "IPHONE 14S B",
        "ean": "1258987561456",
        "brand_id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
        "brand_name": "Apple",
        "picture_url": "http://s3.amazonaws/assets/iphone_14s.jpg"
      }
    }
  ],
  "metadata": {
    "foo": "bar"
  }
}

An order has a order_number, a customer and a list of items.

If you want to add extra data on the order, you can freely use the metadata attribute (a simple key/value store). The ShopRunBack API will always return this data without altering it.

HTTP Request

POST https://dashboard.shoprunback.com/api/v1/orders

Query Parameters

Parameter Required Description
ordered_at yes date of the order
order_number yes the customer’s order number
customer yes customer information (see swaggerhub documentation for details)
items yes Array of items (see swaggerhub documentation for details)
metadata no Anything you want to add to the order, this data will always be returned and never modified.

List all orders

This endpoint lists all your paginated orders.

HTTP Request

GET https://dashboard.shoprunback.com/api/v1/orders?page=1

HTTParty.get(
              "https://dashboard.shoprunback.com/api/v1/orders?page=1",
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )
curl -X "GET" "https://dashboard.shoprunback.com/api/v1/orders?page=1" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8" \

<?php
// Load the library
require 'path/to/lib/shoprunback-php/init.php';

// Set your token
\Shoprunback\RestClient::getClient()->setToken('your_token');

// Define the environment you want to use (Production or Sandbox)
\Shoprunback\RestClient::getClient()->useProductionEnvironment();

// Get all your orders
$orders = \Shoprunback\Elements\Order::all();

The above command returns JSON structured like this:

{
  "pagination": {
    "current_page": 1,
    "first_page": 1,
    "previous_page": 10,
    "next_page": null,
    "last_page": 1,
    "count": 5
  },
  "orders":
    [
      {
        "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
        "ordered_at": "2017-02-03",
        "order_number": "4548-9854",
        "customer": {
          "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
          "first_name": "Steve",
          "last_name": "Jobs",
          "email": "steve@apple.com",
          "phone": "555-878-456",
          "address": {
            "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
            "line1": "One Infinite Loop",
            "line2": "Building B",
            "zipcode": "95014",
            "country_code": "US",
            "city": "Cupertino",
            "state": "California"
          }
        },
        "items": [
          {
            "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
            "product_id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
            "product": {
              "id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
              "label": "Iphone 14S Red",
              "reference": "IPHONE 14S B",
              "ean": "1258987561456",
              "brand_id": "1f27f9d9-3b5c-4152-98b7-760f56967dea",
              "brand_name": "Apple",
              "picture_url": "http://s3.amazonaws/assets/iphone_14s.jpg"
            }
          },
        ],
        "metadata": {
          "foo": "bar"
        }
      },
      {...}
    ]
}

Delete an order

An order can only be deleted if no corresponding shipback is attached. So you must delete it first.

HTTP Request

DELETE https://dashboard.shoprunback.com/api/v1/orders/:order_id

Errors

{
  "errors": [
    {
      "code": "DEPENDENT_SHIPBACK",
      "message": "dependent shipback found (fee4a476-13ff-422d-85df-4ef68fa0c8d7)"
    }
  ]
}

If you are trying to delete an order with a dependent shipback, you will receive an error with a 400 HTTP CODE.

You will also have an error message and an error code in the returned JSON.

In this case, the error code will be DEPENDENT_SHIPBACK.

If the deletion is successful, you will receive a 200 HTTP CODE.

Return

Create the order and the return sequentially

body = {
  "ordered_at": "2017-06-12",
  "order_number": "1234567",
  "customer": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@doe.com",
    "phone": "1230145365",
    "address": {
      "line1": "651 rue de dunkerque",
      "zipcode": "78010",
      "country_code": "FR",
      "city": "Paris"
    }
  },
  "items": [
    {
      "label": "Chemise bleu",
      "reference": "item 001",
      "product_id": "reference1"
    },
    {
      "label": "Casquette rouge",
      "reference": "item 2",
      "product_id": "reference2"
    }
  ]
}

HTTParty.post(
              "https://dashboard.shoprunback.com/api/v1/orders",
              body: body,
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )

body = {
  "mode": "pickup",
  "order_id": "1234567",
  "items": [
    {
      "item_id": "item 2",
      "reason_code": "doesnt_fit"
    }
  ]
}

HTTParty.post(
              "https://dashboard.shoprunback.com/api/v1/shipbacks",
              body: body,
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )
curl -X "POST" "https://dashboard.shoprunback.com/api/v1/orders" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d $'{
  "ordered_at": "2017-06-12",
  "order_number": "1234567",
  "customer": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@doe.com",
    "phone": "1230145365",
    "address": {
      "line1": "651 rue de dunkerque",
      "zipcode": "78010",
      "country_code": "FR",
      "city": "Paris"
    }
  },
  "items": [
    {
      "label": "Chemise bleu",
      "reference": "item 001",
      "product_id": "reference1"
    },
    {
      "label": "Casquette rouge",
      "reference": "item 2",
      "product_id": "reference2"
    }
  ]
}'

curl -X "POST" "https://dashboard.shoprunback.com/api/v1/shipbacks" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d $'{
  "mode": "pickup",
  "order_id": "1234567",
  "items": [
    {
      "item_id": "item 2",
      "reason_code": "doesnt_fit"
    }
  ]
}'
<?php
// Load the library
require 'path/to/lib/shoprunback-php/init.php';

// Set your token
\Shoprunback\RestClient::getClient()->setToken('your_token');

// Define the environment you want to use (Production or Sandbox)
\Shoprunback\RestClient::getClient()->useProductionEnvironment();

//--------------------------------------------------------------------------
// To create a Shipback, we must first have an Order to link the Shipback to
//--------------------------------------------------------------------------

// Create an Address for the Customer
$address = new \Shoprunback\Elements\Address();
$address->country_code = 'US';
$address->line2 = 'Building B';
$address->state = 'California';
$address->line1 = 'One Infinite Loop';
$address->zipcode = '95014';
$address->city = 'Cupertino';

// Create a Customer for the Order
$customer = new \Shoprunback\Elements\Customer();
$customer->email = 'steve@apple.com';
$customer->phone = '555-878-456';
$customer->first_name = 'Steve';
$customer->last_name = 'Jobs';
$customer->address = $address;

// Create an array of Items ordered by the Customer
$item = new \Shoprunback\Elements\Item();
$item->product_id = '1f27f9d9-3b5c-4152-98b7-760f56967dea';
$items = [$item];

// Create an Order
$order = new \Shoprunback\Elements\Order();
$order->order_number = '4548-9854';
$order->customer = $customer;
$order->items = $items;
$order->ordered_at = '2017-02-03';

// We save the Order
$order->save();

//--------------------------------------------------------
// Now that we have an Order, we can link a Shipback to it
//--------------------------------------------------------

// Create a Shipback and link the Order
$shipback = new \Shoprunback\Elements\Shipback();
$shipback->order_id = $order->id;

  // Optionnal: you can directly link the Items the Customer wants to return
  // If you don't, the Customer will have to fill the return request's form to select them
  $returnedItem = new \Shoprunback\Elements\ReturnedItem();
  $returnedItem->item_id = $order->items[0]->id; // It must be the ID of an Item from the Order
  $returnedItem->reason_code = 'doesnt_fit';

  $shipback->items = [$returnedItem];

// We save the Shipback
$shipback->save();

You can create the order and its corresponding shipback in 2 sequential API calls without parsing the first response by using your own references.

First, create the order with an order_number and the items. You don’t have to push all the items in the initial order if you already know which items are going to be returned, just push them and not the others. You must provide item references if you want to avoid the parsing of the response. An item reference should be unique per order.

Second, create the corresponding shipback attached to your order_number by giving the item’s reference and the reason of the return.

If the customer details of the shipback are not provided, the order’s customer is copied and used for the shipback.

Delete a shipback

An shipback can only be deleted if no yet registered (the customer has not completed the whole process).

HTTP Request

DELETE https://dashboard.shoprunback.com/api/v1/shipbacks/:shipback_id

Errors

{
  "errors": [
    {
      "code": "SHIPBACK_REGISTERED",
      "message": "This shipback is already processing. You can't delete it."
    }
  ]
}

If you are trying to delete an arlready registered shipback, you will receive an error with a 400 HTTP CODE.

You will also have an error message and an error code in the returned JSON.

In this case, the error code will be SHIPBACK_REGISTERED.

If the deletion is successful, you will receive a 200 HTTP CODE.

Your own return process

If you don’t want to use the return process provided by ShopRunBack, you can built your own return’s funnel.

For that you have to:

1/ Create the shipback with the list of the returned items (with the associated reason code)

2/ Request the quotes (for each mode - pickup, postal and dropoff - a quote is created to compute the corresponding price of the return)

3/ Confirm the quote (select and confirm one of the available quotes)

4/ Get the label

1. Create the shipback

To create the return follow this instruction.

2. Request the quotes

HTTParty.get(
              "https://dashboard.shoprunback.com/api/v1/shipbacks/00082f23-9b8c-4515-b1cd-527d56a1bef3/quotes",
              body: body,
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )

curl -X "GET" "https://dashboard.shoprunback.com/api/v1/shipbacks/00082f23-9b8c-4515-b1cd-527d56a1bef3/quotes" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8"
<?php
  //The ShopRunBack library doesn't provide, at the moment, a dedicated method for that

// get cURL resource
$ch = curl_init();

// set url
curl_setopt($ch, CURLOPT_URL, 'https://dashboard.shoprunback.com/api/v1/shipbacks/00082f23-9b8c-4515-b1cd-527d56a1bef3/quotes');

// set method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

// return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// set headers
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'Authorization: Token token=your_token',
]);

// send the request and save response to $response
$response = curl_exec($ch);

// stop if fails
if (!$response) {
  die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
}

echo 'HTTP Status Code: ' . curl_getinfo($ch, CURLINFO_HTTP_CODE) . PHP_EOL;
echo 'Response Body: ' . $response . PHP_EOL;

// close curl resource to free up system resources
curl_close($ch);



The above command returns JSON structured like this:

[
  {
    "id": "570f3429-25ec-4685-9229-581853d0fecc",
    "state": "computing",
    "mode": "postal",
    "price_cents": null,
    "customer_price_cents": null
  },
  {
    "id": "dc1383df-020b-44a6-8100-69bed63c35ee",
    "state": "computing",
    "mode": "pickup",
    "price_cents": null,
    "customer_price_cents": null
  },
  {
    "id": "d014d7c6-8f46-4c87-9d81-df91d502b1ef",
    "state": "computing",
    "mode": "dropoff",
    "price_cents": null,
    "customer_price_cents": null
  }
]

The quotes are only computed on demand. So once the shipback created with the returned items inside, you have to trigger the computation of the quotes.

The computation takes some time (from 30 to 90s) to compute the 3 quotes. You can request the endpoint /api/v1/shipbacks/:id/quotes every 20 seconds to get the state of the computation.

You can also query the quote of the mode you want to follow directly the computation of this mode only : /api/v1/shipbacks/:id/quotes/postal for the postal mode.

Clear the quotes

HTTParty.post(
              "https://dashboard.shoprunback.com/api/v1/shipbacks/00082f23-9b8c-4515-b1cd-527d56a1bef3/quotes/clear",
              body: body,
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )

curl -X "POST" "https://dashboard.shoprunback.com/api/v1/shipbacks/00082f23-9b8c-4515-b1cd-527d56a1bef3/quotes/clear" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8"
<?php
  //The ShopRunBack library doesn't provide, at the moment, a dedicated method for that

// get cURL resource
$ch = curl_init();

// set url
curl_setopt($ch, CURLOPT_URL, 'https://dashboard.shoprunback.com/api/v1/shipbacks/00082f23-9b8c-4515-b1cd-527d56a1bef3/quotes/clear');

// set method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');

// return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// set headers
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'Authorization: Token token=your_token',
]);

// send the request and save response to $response
$response = curl_exec($ch);

// stop if fails
if (!$response) {
  die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
}

echo 'HTTP Status Code: ' . curl_getinfo($ch, CURLINFO_HTTP_CODE) . PHP_EOL;
echo 'Response Body: ' . $response . PHP_EOL;

// close curl resource to free up system resources
curl_close($ch);



If you have updated the shipback or simply want to retrigger the quotes computation, you have to clear them by calling the dedicated endpoint.

3. Select the mode

HTTParty.get(
              "https://dashboard.shoprunback.com/api/v1/shipbacks/00082f23-9b8c-4515-b1cd-527d56a1bef3/quotes",
              body: body,
              headers: {
                'Content-Type' => 'application/json',
                'Authorization' => "Token token=#{your_token}"
              }
            )

curl -X "GET" "https://dashboard.shoprunback.com/api/v1/shipbacks/00082f23-9b8c-4515-b1cd-527d56a1bef3/quotes" \
     -H "Authorization: Token token=<your_token>" \
     -H "Content-Type: application/json; charset=utf-8"
<?php
  //The ShopRunBack library doesn't provide, at the moment, a dedicated method for that

// get cURL resource
$ch = curl_init();

// set url
curl_setopt($ch, CURLOPT_URL, 'https://dashboard.shoprunback.com/api/v1/shipbacks/00082f23-9b8c-4515-b1cd-527d56a1bef3/quotes');

// set method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

// return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// set headers
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'Authorization: Token token=your_token',
]);

// send the request and save response to $response
$response = curl_exec($ch);

// stop if fails
if (!$response) {
  die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
}

echo 'HTTP Status Code: ' . curl_getinfo($ch, CURLINFO_HTTP_CODE) . PHP_EOL;
echo 'Response Body: ' . $response . PHP_EOL;

// close curl resource to free up system resources
curl_close($ch);



The above command returns JSON structured like this:

[
  {
    "id": "570f3429-25ec-4685-9229-581853d0fecc",
    "state": "computing",
    "mode": "postal",
    "price_cents": null,
    "customer_price_cents": null
  },
  {
    "id": "dc1383df-020b-44a6-8100-69bed63c35ee",
    "state": "computing",
    "mode": "pickup",
    "price_cents": null,
    "customer_price_cents": null
  },
  {
    "id": "d014d7c6-8f46-4c87-9d81-df91d502b1ef",
    "state": "computing",
    "mode": "dropoff",
    "price_cents": null,
    "customer_price_cents": null
  }
]

To select the mode, you have to update the shipbacks and provide one of the available modes.

A mode is available if the corresponding quote is marked as available.

Mode Dropoff

{
  "dropoff_code": "O4001",
  "mode": "dropoff"
}

To select the dropoff mode, you also have to provide a valid dropoff point code. This code is provided in the quotes endpoint.

Update the shipback with the mode dropoff and the dropoff_code on the api/v1/shipbacks/:id endpoint.

Mode Pickup

{
  "pickup_datetime": "2018-01-18 14:00:00",
  "pickup_duration": "120",
  "mode": "pickup"
}

To select the pickup mode, you also have to provide a valid pickup_datetime and pickup_duration. These values are available in the quotes endpoint.

Update the shipback with the mode pickup and these 2 values on the api/v1/shipbacks/:id endpoint.

4. Get the label

# cURL example:
curl -H "Authorization: Token token=<your_token>"
     -X POST
     'https://dashboard.shoprunback.com/api/v1/shipbacks/:id/free'
# Ruby example
response = HTTParty.post(
    'https://dashboard.shoprunback.com/api/v1/shipbacks/#{shipback_id}/free',
    headers: {
        'Content-Type' => 'application/json',
        'Authorization' => "Token token=#{your_token}"
    }
)

To validate the selected mode and get the label, payment information needs to be added to the shipback. In the case of a custom return process, where customer payment isn’t supported, we need to skip the payment phase by POSTing on the api/v1/shipbacks/:id/free endpoint.

Once the call has been successfully performed, the voucher and the label are being generated, you can get the corresponding label by polling the api/v1/shipbacks/:id endpoint.

The label generation is dependent of the carriers response time, you can expect up to 1 minute of waiting to get the label.

Overrides

Relocation

# POST on the endpoint api/v1/shipbacks/:id
{
  "mode": "pickup",
  "overrides": {
    "relocation_warehouse_id": "E002"
  }
}

The ShopRunBack’s dashboard gives you the possibility to define your rules of relocation based on the reason of the return and the country of your customer.

If the rules engine does not fit your desires, you can override the warehouse of relocation of the entire shipback while creating (or updating) the shipback on the API by providing the warehouse ID or reference.

Price paid by the customer

# POST on the endpoint api/v1/shipbacks/:id
{
  "mode": "pickup",
  "overrides": {
    "dropoff_customer_price_cents": 300,
    "postal_customer_price_cents": 450,
    "pickup_customer_price_cents": 1200
  }
}

You can change the price displayed and paid by the customer on the web return process depending on rules in your own system. If the amount paid is higher than the normal price of the service, the difference will be refunded to you.

These overrides are only for returns which are not free for the customer, if you want to create you policy for free return, please use the Smart Rules system.

Try at Home

# POST on the endpoint api/v1/shipbacks/:id
{
  "overrides": {
    "try_at_home": true
  }
}

ShopRunBack provides a Try at Home feature which makes certain returns free when they are within a specified period of time after the initial order. At the time of writing, this feature needs to be enabled in your company configuration by ShopRunBack’s support.

Shipbacks leveraging this feature needs to be flagged as Try at Home returns. This is accomplished by setting the try_at_home override to true, POSTing the following json data on the shipback’s endpoint:

# cURL example:
curl -H "Authorization: Token token=<your_token>"
     -X POST -d '{"overrides": {"try_at_home": true}}'
     'https://dashboard.shoprunback.com/api/v1/shipbacks/:id'
# Ruby example
response = HTTParty.post(
    'https://dashboard.shoprunback.com/api/v1/shipbacks/#{shipback_id}'
    body: { overrides: { try_at_home: true } },
    headers: {
        'Content-Type' => 'application/json',
        'Authorization' => "Token token=#{your_token}"
    }
)

Webhooks

Every event on ShopRunBack can trigger a webhook.

Basically, a webhook is a JSON Object send by HTTP (POST) to an URL you have set on your account.

The server expect a 200 response (HTTP OK) when posting the webhook, otherwise it is marked as not received successfully on the dashboard.

Go to the webhooks dashboard.

Data sent

  // Example of JSON sent
  {
    "id": "00082f23-9b8c-4515-b1cd-527d56a1bef3",
    "event": "shipback.relocated",
    "created_at": "2018-02-20 16:54:22 +0100",
    "data": {
      "id": "fc8520bf-3ae0-46b1-8991-cacb6b03c698",
      "mode": "postal"
    }
  }

All webhooks has the same caracteristics; this is a JSON Object with the attributes:

Collaborator

// Example of JSON sent:
  {
    "id": "00082f23-9b8c-4515-b1cd-527d56a1bef3",
    "event": "collaborator.invited",
    "created_at": "2018-02-20 16:54:22 +0100",
    "data": {
      "id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c698",
      "email" : "tim@apple.com"
    }
  }

Webhook name Trigger
collaborator.created Sent when a collaborator creates its account
collaborator.invited Sent when a manager invite a collaborator

Product

 // Example of JSON sent:
  {
    "id": "00082f23-9b8c-4515-b1cd-527d56a1bef3",
    "event": "product.created",
    "created_at": "2018-02-20 16:54:22 +0100",
    "data": {
      "id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c698",
      "label" : "Iphone 12S - Blue",
      "reference": "IPHONE-12S",
      "ean": "1237492402485"
    }
  }

Webhook name Trigger
product.created Sent when a product is created in the catalogue

Relocation

  // Example of JSON sent:
  {
    "id": "00082f23-9b8c-4515-b1cd-527d56a1bef3",
    "event": "relocation.created",
    "created_at": "2018-02-20 16:54:22 +0100",
    "data": {
      "id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c698",
      "country_code" : "FR",
      "reason_code" : "damaged",
      "warehoused_id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c699"
    }
  }

Webhook name Trigger
relocation.created Sent when a new relocation rule has been created

Returned Item

  // Example of JSON sent:
  {
    "id": "00082f23-9b8c-4515-b1cd-527d56a1bef3",
    "event": "returneditem.relocated",
    "created_at": "2018-02-20 16:54:22 +0100",
    "data": {
      "id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c698",
      "reason_code" : "damaged",
      "item" : {
        "id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c600",
        "barcode": "12149837489",
        "label": "Iphone 12S - Blue",
        "reference": "IPHONE-12S"
      }
    }
  }

Webhook name Trigger
returneditem.missing Sent when a returned item is marked as missing by an operator
returneditem.relocated Sent when a returned item is relocated to the retailer’s warehouse
returneditem.transiting Sent when a returned item is transitting

Shipback


  # Example of JSON sent for shipback.registered
  {
    "id": "00082f23-9b8c-4515-b1cd-527d56a1bef3",
    "event": "shipback.registered",
    "created_at": "2018-02-20 16:54:22 +0100",
    "data": {
      "id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c698",
      "rma" : "123",
      "registered_at": "2018-02-20 16:58:22 +0100",
      "mode": "postal",
      "weight_in_grams": "1000",
      "size": "S",
      "computed_weight_in_grams": "1000",
      "public_url": "https://web.shoprunback.com/apple/1234",
      "metadata": {},
      "price_cents": "10000",
      "customer_price_cents": "10000"
    }
  }

  # Example of JSON sent for shipback.labelled
  {
    "id": "00082f23-9b8c-4515-b1cd-527d56a1bef3",
    "event": "shipback.labelled",
    "created_at": "2018-02-20 16:54:22 +0100",
    "data": {
      "id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c698",
      "rma" : "123",
      "registered_at": "2018-02-20 16:58:22 +0100",
      "mode": "postal",
      "weight_in_grams": "1000",
      "size": "S",
      "computed_weight_in_grams": "1000",
      "public_url": "https://web.shoprunback.com/apple/1234",
      "metadata": {},
      "price_cents": "10000",
      "customer_price_cents": "10000",
      "label_url" : "http://cdn.com/label/1234.pdf",
      "tracking_number": "123456-tracking"
    }
  }

  // Example of JSON sent for other events
  {
    "id": "00082f23-9b8c-4515-b1cd-527d56a1bef3",
    "event": "shipback.registered",
    "created_at": "2018-02-20 16:54:22 +0100",
    "data": {
      "id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c698",
      "rma" : "123",
    }
  }

Webhook name Trigger
shipback.created Sent when a shipback is created (via the API or via the web interface)
shipback.registering Sent when a customer has visited the return link
shipback.registered Sent when a shipback is registered (the customer has paid or validated is free return) and the customer can download its voucher and label
shipback.labelled Sent when the label is available
shipback.delivering Sent when the shipback is transiting between the customer’s location and our warehouse
shipback.delivered Sent when the shipback is delivered to our warehouse
shipback.identified Sent when the incoming parcel has been open and all returned items have been identified with a unique barcode or marked has missing (not returned)
shipback.relocating Sent when the shipback is transitting from our warehouse to the retailer’s warehouse
shipback.relocated Sent when all the returned item’s of a shipback are relocated to the retailer’s warehouse
shipback.failed Sent when something went wront with this shipback

Sponsoring

// Example of JSON sent:
  {
    "id": "00082f23-9b8c-4515-b1cd-527d56a1bef3",
    "event": "sponsoring.created",
    "created_at": "2018-02-20 16:54:22 +0100",
    "data": {
      "id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c698",
      "percentage": "100",
      "country_code": "FR",
      "reason_code": "damaged",
      "merchant_fee_min": 5,
      "merchant_fee_max": 10,
      "customer_fee_min": null,
      "customer_fee_max": null
    }
  }

Webhook name Trigger
sponsoring.created Sent when a new sponsoring rule has been created

Warehouse

// Example of JSON sent:
  {
    "id": "00082f23-9b8c-4515-b1cd-527d56a1bef3",
    "event": "warehouse.created",
    "created_at": "2018-02-20 16:54:22 +0100",
    "data": {
      "id" : "fc8520bf-3ae0-46b1-8991-cacb6b03c698",
      "reference": "APPLE01",
      "name": "Apple store Paris",
    }
  }

Webhook name Trigger
warehouse.created Sent when a new warehouse is added to the company

Set the URL


  # in a Rake base application controller
  def webhook
    # handle the webhook content with params
    head 200 # HTTP OK
  end
<?php

  // in a PHP Framework controller
  private function webhook()
  {
    $webhook = file_get_contents("php://input");
    $webhook = json_decode($webhook); // the webhook data in an associative array

    return self::returnHeaderHTTP(200); //example in Prestashop
  }

?>

The ShopRunBack’s API send the webhooks on a public accessible HTTP or HTTPS endpoint (the certificate must be valid).

If you want to protect this endpoint, you can :

You can set your Wehbook URL on the dashboard, in the section Developers > Webhooks.

Signature

We include a signature in each webhooks sent by ShopRunBack in the Shoprunback-Signature header.

Define your secret

You can change the secret (the default one is empty) on your dashboard: section Developers > Webhooks.

Use a random string with high entropy with, by example, the following command: ruby -rsecurerandom -e 'puts SecureRandom.hex(20)' in your terminal.

Verify the signature

  digest = OpenSSL::Digest.new('sha256')
  secret = "your secret" # empty string if not set
  payload = request.body.read

  # signature
  hmac = OpenSSL::HMAC.hexdigest(digest, secret, payload)

  # verification
  hmac == request.env['HTTP_SHOPRUNBACK_SIGNATURE']
<?php

  $secret = "your secret"; // empty string if not set
  $payload = @file_get_contents('php://input');

  // signature
  $hmac = hash_hmac ('sha-256', $body , $secret)

  // verification
  $hmac == $_SERVER['HTTP_STRIPE_SIGNATURE'];

?>

ShopRunBack generates signatures using a hash-based message authentication code (HMAC) with SHA-256.

To verify this signature:

  1. Get the signature in the Shoprunback-Signature header
  2. Compare the header value with HMAC (SHA-256) of the request body

The two signature must be the same otherwise you can reject this webhook.

Volume

The volume of webhooks increase with the amount of shipbacks ShopRunBack will handle for you.

Please make sure your server and the application which provides the endpoint can handle all the requests.

If you don’t use the webhooks, don’t provide any webhooks URL and the platform will not send it.