boxnowLogoPopup

Try out the

BOX NOW App!

BoxNow

Steps

Step 1: Setup

Step 2: Environments

Step 3: Requesting a delivery

Step 4: Destination Map

Step 5: Troubleshooting

Help

Tailor Made

Before you start

Step 1: Set up

OAUTH_CLIENT_ID

Keep this value private and safe! This is your OAuth2 Client ID that you will use to authenticate with the Partner API.

OAUTH_CLIENT_SECRET

Keep this value private and safe! This is your OAuth2 Client Secret that you will use to authentica te with the Partner API.

API_URL

This is your Base URL for the Partner API, to which you will then append the relevant endpoint paths.

Step 2: Environments

Test / Stage

An environment with limited functionalities, where you can test the integration.

Production

Use this environment with caution, as it is live and connected to real end users.

Step 3: Process of requesting a delivery

Follow these steps to successfully request a delivery and perform other related actions:

3.1 Authenticate yourself /auth sessions

Authentication is based on OAuth 2.0 standard, Client Credentials grant.

In order to use the API, you must attach the access token to Authorization header as a Bearer token.

See an example of a successful integration:

POST /api/v1/ auth sessions

{

"grant_type”: "client_credentials”,

"client_id": “string”,

"client_secret": “string”

}

Status Code 200

{

"access_token”: “client_credentials”,

"token_type": “Bearer”,

"expires_in”: 3600

}

Further responses, which might occur:

400

The server cannot or will not process the request due to something that is perceived to be your error (e.g., not to spec request syntax, invalid request message). You are to modify the request before sending it again.

401

Not Authorized. You are either using an expired Access token to access the data or trying to initialize Auth session with invalid data.

403

Account disabled. Your account had been disabled, contact support.

3.2 List all available origins/origins

This call will list all available pick up point (PUP locations where BoxNow can pick up all your parcels from typically your warehouses.

You can list all your warehouses using /origins API call which has the same parameters as /destinations API call where you do not specify parameters latlng, radius or requiredSize, but you specify locationType as “warehouse”. You refer to this location by its ID (locationid).

Moreover there is one specific location called any-apm that can be listed by the same way and using locationType as “any-apm”, it returns just one location-any-apm. You can refer to it by its ID (locationid). Usage of this will be explained in the next section.

Below is the parameter availa ble for you to filter all Origin locations:

Name Type Description
locationType string

Return only locations with given a type. If not present, filter is not applied.

  • Possible origins: any-apm, warehouse

See an example of a successful integration:

GET /api/v1/ origins

curl -X ‘GET’\

'…/origins\

-H 'accept: application/json’

Status Code 200

{

"data": [

{

"id": "string",

"type": "warehouse",

"image": "https://via.placeholder.com/175",

"lat": "48.940819584637266",

"lng": "12.366962491028423",

"title": "Warehouse 1",

"name": "Main Warehouse",

"addressLine1": "ul.Tsar Boris III",

"addressLine2": "Sofia",

"postalCode": "1000",

"country": "BG",

"note": "Next to Super market"// can be null

}

]

}

Further responses, which might occur:

Error Code

400

The server cannot or will not process the request due to something that is perceived to be your error (e.g., malformed request syntax, invalid request message). You are to modify the request before sending it again.

401

Not Authorized. You are either using an expired Access token to access the data or trying to initialize Auth session with invalid data.

403

Account disabled. Your account had been disabled, contact support.

3.3. List all available destinations /destinations

This call will list all available APM (Automatic Parcel Machine) locations where we can deliver your parcel to.

Beloware the parameters available for you to filter all APM locations:

Name Type Description
locationType string

If applied, only locations in the specified radius from these gps coordinates are returned.

  • Example: 48.78081955454138,12.446962472273063
radius number

Radius in meters to return only locations within a selected radius from given GPS location. Ignored if latlng is not present.

  • Example: 1000
  • Default Value: 25000
requiredSize number

Return only locations that can accept a package of your requiredSize.

  • Example 1
locationType string

Return only locations with given a type. If not present, filter is not applied.

  • Available values: apm, any-apm

See an example of a successful integration:

GET api/v1/ destinations

curl X ‘GET’\

‘.../destinations\

-H 'accept: application/json'

Status Code 200

{

"data": [

{

"id": "string",

"type": "apm",

"image": "https://via.placeholder.com/150",

"lat": "48.78081955454138",

"lng": "12.446962472273063",

"title": "1842 - Building SIVEN, Hladilnika",

"name": "1842 - бул. Черни връх №47А, София, 1407",

"addressLine1": "bul. Cherni Vrah 47A",

"addressLine2": "string",

"postalCode": "1407",

"country": "BG",

"note": "You can find it behind the pet shop"

}

]

}

Alternatively, refer to section 4 for a Java Script snippet you can embed into your web to display all available APMs via a pop-up/iframe widget, or for a brief description of a successful custom map integration.

id

When requesting a delivery, you will refer to these records by id-More commonly:

locationId

Further responses, which might occur:

Error Code

400

The server cannot or will not process the request due to something that is perceived to be your error (e.g., malformed request syntax, invalid request message). You are to modify the request before sending it again.

401

Not Authorized. You are either using an expired Access token to access the data or trying to initialize Auth session with invalid data.

403

Account disabled. Your account had been disabled, contact support.

3.4 Request a delivery /delivery requests

Use this call to order a delivery of a parcel (or multiple parcels). This is the main call you will be using to create any type of delivery requests.

Once a successful request for delivery is made:

  • (optional) We will send you an email notifying you of a successful delivery request creation with a PDF label attached. Parameter notifyOnAccepted needs to be populated for this function (See Appendix 6.3).
  • (Described below) Alternatively, you should fetch the PDF label for each parcel using the GET/parcels/{id}/label.pdf call print it and stick it to the parcel(s).
  • We will send a courier to pick up the parcel(s) at the agreed pick up times.
  • We will also notify the customer that
  1. We have received a delivery order and that a parcel will be delivered to them.
  2. We have successfully delivered their parcel(s) to the specified destination APM with the necessary details for collecting the parcel(s).

See an example of a successful integration:

POST api/v1/ delivery requests

{

"orderNumber": “string”,

"invoiceValue": “25.50”,

"paymentMode":”prepaid”,

”amountToBeCollected": “0.00",

"allowReturn”: true,

"origin”:{

"contactNumber":“+3598XXXXXXXX”,

"contactEmail”: [email protected],

"contactName": “Ivan Ivanov",

"locationId":”string”

},

“destination”:{

"contactNumber": "+3598XXXXXXXX”,

"contactEmail”: [email protected],

"contactName” "Ivan Petrov",

"locationId":”string”

},

"items”: [

{

"id": “string”,

"name": “Smartphone”

"value”: “3.45”,

"weight”: 0

}

]

}

items: weight

If the parcel weight is unknown, pass 0.

These parameters are the main identifiers of pick up & delivery locations:

origin: locationId

The warehouse where the parcel will be picked up from.

destination: locationId

Automatic Parcel Machine (APM) where the parcel will be delivered to.

Also,

do not forget to pass us the following personal details with each delivery request:

Sender:

  1. Name

Recipient:

  1. Name
  2. Phone number
  3. Email

Status Code 200

{

"referenceNumber":”string”,

"parcels”:[

{

"id":”string”

}

]

}

Note:In the above example, the “items correspond to parcels, but item ID is eshop unique ID (reference number, if you will). If you do not have unique ID of each item then create it by order number combined with sequential item number or any other way. Whileparcel ID (parcels ID)is BoxNow internal unique ID used further to refer to the parcel.

For sending from APM you can use origin any APM and destination specific APM.

For delivering to APM where customer will pick up from the same APM you can use both origin and destination location any-APM.

Further responses, which might occur:

Error Code

400

Bad Request. The server cannot or will not process the request due to something that is perceived to be your error (e.g., malformed request syntax, invalid request message). You are to modify the request before sending it again.

401

Not Authorized. You are either using an expired Access token to access the data or trying to initialize Auth session with invalid data.

403

Account disabled. Your account had been disabled, contact support.

3.5 Fetch a PDF label /parcels/{id}/label.pdf

Use this call to request a .pdf file with a label you shoold print a stick onto each parcel.

Only this parameter is available to you:

Name Type Description
id string Unique parcel number returned to you by method /delivery-requests

See an example of a successfol integration:

GET /api/v1/ parcels

curl -X 'GET' \

‘.../parcels/{id}/label.pdf’ \

-H 'accept: application/pdf’

Status Code 200

.pdf file with the corresponding label

To print all PDF labels at once for your order, you can replace {id} with {orderNumber}:

GET /api/v1/ delivery requests

curl -X 'GET' \

‘.../delivery-requests/{orderNumber}/label.pdf’ \

-H 'accept: application/pdf’

Step 4: Destination Map (Widget /Custom

4.1 Widget Integration

As an alternative to integrating our API, you can embed our ready made widget into your check out page. This widget is communicating with our API and includes the same data you can access via GET /api/v1/ destination.

How to install BoxNow Map Widget:

  1. Paste the BoxNow Map Widget JavaScript code into the checkout page (or any other page where you want to display the BoxNow Map Widget).
  2. Create new HTML button with class attribute boxnow-widget-button to open BoxNow Map Widget. For example:
    <a href="javascript:;" class="boxnow-widget-button">Open widget</a>
  3. Create function for accept data from selected locker (id, address, name, etc.).

BoxNow Map Widget (Javascript Code):

    

<div id="boxnowmap"></div>

<script type="text/javascript">

var _bn_map_widget_config = {

partnerId: 123,

parentElement: "#boxnowmap"

afterSelect: function(selected){

alert(selected.boxnowLockerPostalCode);

alert(selected.boxnowLockerAddressLine1);

alert(selected.boxnowLockerId);

}

};

(function(d){var e = d.createElement("script");e.src = "https://widget-cdn.boxnow.bg/map-widget/client/v5.js";e.async = true;e.defer = true;d.getElementsByTagName("head")[0].appendChild(e);})(document);</script>

Note:The most important is variable _bn_map_widget_config. With this variable you can setup all required options , as shown below.

Name Usage Description
parentElement required

Please fill CSS selector for Map Widget container. For example, just create

<div id="boxnowmap"></div> 

and fill #boxnowmap. The BoxNow map widget will be placed inside this element.

afterSelect

required for type:iframe

and type:popup

Function that is triggered when the lock is selected. Included one parameter (object) contains all information about locker (properties boxnowLockerPostalCode, boxnowLockerAddressLine1 and boxnowLockerId are the most important).

partnerId optional Please use your partnerId
type optional Use iframe, popup or navigate. Defaolt is iframe.
gps optional Use it if you want to change the user's location request immediately after displaying the map. Possible options are true or false. Defaolt is true.
autoclose optional Use it when you want to change what happens after you select a locker. For type:iframe, the defaolt value is true, which means that the map will be hidden when the locker is selected. For type:popup, autoclose is always true. The possible values are true or false. The defaolt value is true.

**For more integration examples you can refer to: widget-v4.boxnow.bg/developers

4.2 Custom Map Integration

Our widget takes advantage of Google Maps Javascript API: https://developers.google.com/maps/apis-by-platform

By calling GET /api/v1/ destination, you can obtain longitude as variable lng and latitude as variable lat of each delivery location, that you can then pass to the Google Maps API to display the location on the map:

https://developers.google.com/maps/documentation/javascript/adding-a-google-map
  1. id for locker ID
  2. image for a url with image of the locker
  3. name
  4. addressLine1 and addressLine2
  5. postalCode
  6. note for a detailed description of the lockerlocker’s location.
Step 5: Troubleshooting

Description of error codes for 400 Unprocessable entity responses:

Error Code P400

Invalid request data. Make sure you are sending the request according to the documentation.

Error Code P401

Invalid request origin location reference. Make sure you are referencing a valid location ID from Origins endpoint or valid address.

Error Code P402

Invalid request destination location reference. Make sure you are referencing a valid location ID from Destinations endpoint or valid address.

Error Code P403

You are not allowed to use AnyAPM-SameAPM delivery. Contact support if you believe this is a mistake.

Error Code P404

Invalid import CSV. See error contents for additional info.

Error Code P405

Invalid phone number. Make sure you are sending the phone number in foll international format, e.g. +30 xx x xxx xxxx.

Error Code P406

Invalid compartment/parcel size. Make sure you are sending one of required sizes 1, 2 or 3 ( Medium or Large). Size is required when sen ding from AnyAPM directly.

Error Code P407

Invalid country code. Make sure you are sending country code in ISO 3166-1 alpha-2 format, e.g. BG.

Error Code P410

Order number conflict. You are trying to create a delivery request for order ID that has already been created. Choose another order ID.

Error Code P411

You are not eligible to use Cash-on-delivery payment type. Use another payment type or contact our support.

Error Code P420

Parcel not ready for cancel. You can cancel only new, undelivered, or parcels that are not returned or lost. Make sure parcel is in transit and try again.

Error Code P430

Parcel not ready for AnyAPM confirmation. Parcel is probably already confirmed or being delivered. Contact support if you believe this is a mistake.

Contact us:

If you are having troubles integrating our API into your online store based on the current documentation reach out to us at [email protected]

Notes:

  1. Testing plugin with stage Api keys.
  2. Select stage locker: Test Locker 1, locker id: 5365
  3. When a new order is completed we will automatically send you a PDF shipping label, if you've passed "NotifyOnAccepted" paratmeter with a valid e-mail address.
  • (POST) Authorization: {baseURL}/api/v1/auth-sessions
  • (GET) Origins: {baseURL}/api/v1/origins
  • (GET) Destinations: {baseURL}/api/v1/destinations
  • (POST) Delivery-request: {baseURL}/api/v1/delivery-requests
  • (GET) Parcel label: {baseURL}/api/v1/parcels/{id}/label.pdf
  • (GET) Parcels: {baseURL}/api/v1/parcels
  • (POST) Cancel parcel: {baseURL}/api/v1/parcels/{id}:cancel