Shopopop API documentation (2.0.0)

Overview

This is the documentation of Shopopop API.

Shopopop API allows our partners to integrate their information system with ours.

Using Shopopop API, partners can create deliveries and track their worflow.

General information

All calls must use HTTPS.

Environments

All the endpoints are available in

  • Sandbox : for testing purpose
  • Prod : for production

The endpoints are the same in both environments, but the domains differ :

  • Sandbox : https://partners-api.sandbox.shopopop.com/v2
  • Prod : https://partners-api.shopopop.com/v2

Authentication

To authenticate API requests, use Basic Authentication by including the Authorization header with each call otherwise a 401 Unauthorized error will be returned.

Authorization Header

  • The Authorization header should be in the format: Authorization: Basic <base64-encoded-credentials>
  • <base64-encoded-credentials> is the base64 encoding of the partner_id:partner_key.

Example:

  • The Authorization header might look like this: Authorization: Basic cGFydG5lcl9pZDpwYXJ0bmVyX2tleQ== (e.g. in decoded form it would be Authorization: Basic partner_id:partner_key)

Access Information

  • The partner_id and partner_key will be communicated securely by Shopopop.
  • The credentials are sensitive and should be handled securely, ensuring they are not exposed in public or insecure environments.

Deliveries

All deliveries endpoints

Check the eligibility of a delivery

Checks if a delivery is eligible according to the delivery time and travel distance.

This endpoint use the same payload as the delivery creation endpoint. If the delivery is not eligible, the response is an error with the reason of the refusal. If it is eligible, the response is a success; the delivery is not created.

Authorizations:
BasicAuth
Request Body schema: application/json
required
retailer
string or null <= 255 characters

Code of the retailer

If you can create deliveries for several retailers, this code indicate for which retailer this delivery should be done. This value is provided by Shopopop.

required
object (PartnerPickupRequest)
required
object (PartnerDropoffRequest)

Information about the drop-off location.

If the latitude and longitude are provided these are use to define the drop-off location. The other address information are still displayed to the deliverer as additional information.

If latitude and longitude are not given, "street", "zip_code", "city" and "country" are used to geolocate the address.

required
object (PartnerDeliveryRequest)

Responses

Request samples

Content type
application/json
{
}

Response samples

Content type
application/json
Example
{
}

Create a delivery

Create delivery request

Note that the parameters are the same as the Check eligibility parameters.

Calling this route creates a valid delivery in our system that a deliverer can book immediately.

If you need to validate a delivery without creating it, use the eligibility route.

Authorizations:
BasicAuth
Request Body schema: application/json
required
retailer
string or null <= 255 characters

Code of the retailer

If you can create deliveries for several retailers, this code indicate for which retailer this delivery should be done. This value is provided by Shopopop.

required
object (PartnerPickupRequest)
required
object (PartnerDropoffRequest)

Information about the drop-off location.

If the latitude and longitude are provided these are use to define the drop-off location. The other address information are still displayed to the deliverer as additional information.

If latitude and longitude are not given, "street", "zip_code", "city" and "country" are used to geolocate the address.

required
object (PartnerDeliveryRequest)

Responses

Response Schema: application/json
creation_date
required
string <date-time>
message
required
string
Value: "DUPLICATE"
object or null <date-time>

Request samples

Content type
application/json
{
}

Response samples

Content type
application/json
{
}

Get a delivery

Return delivery information

Authorizations:
BasicAuth
path Parameters
deliveryId
required
string

Unique ID of the delivery.

This is the ID provided in the creation.

Responses

Response Schema: application/json
delivery_id
string [ 1 .. 60 ] characters

Unique ID of the delivery

status
string
Enum: "AVAILABLE" "RESERVED" "TO_PICKUP_POINT" "AT_PICKUP_POINT" "PICKUP_VALIDATED" "TO_RECIPIENT" "AT_RECIPIENT" "VALIDATED" "INCIDENT" "DELETED"

Status of the delivery

object
object
object

Response samples

Content type
application/json
{
}

Cancel delivery

Authorizations:
BasicAuth
path Parameters
deliveryId
required
string

Unique ID of the delivery.

This is the ID provided in the creation.

Request Body schema: application/json
reason
string or null [ 0 .. 255 ] characters

Reason of the cancellation

Responses

Request samples

Content type
application/json
{
}

Response samples

Content type
application/json
Example
{
}

Shift delivery slot

Authorizations:
BasicAuth
path Parameters
deliveryId
required
string

Unique ID of the delivery.

This is the ID provided in the creation.

Request Body schema: application/json
optional
dropoff_start
required
string

Start of the new delivery slot (format ISO full UTC)

dropoff_end
required
string

End of the new delivery slot (format ISO full UTC)

Responses

Request samples

Content type
application/json
{
}

Response samples

Content type
application/json
Example
{
}

Webhooks

Using webhooks, Shopopop can send information about changes on deliveries

Delivery Events Webhook

Webhook used to send events occuring on a delivery. Those events can be a status change, or a delivery slot modification for example. To use webhooks, you have to give us the URL to use to send you this information.

Events

Validating Webhook Signatures

To ensure the integrity and authenticity of the webhook events received from our API, it's crucial to verify the signature sent with each request. This guide provides instructions on validating webhook payloads. Each webhook request includes a signature in the X-Shopopop-Signature-256 header. Use this signature to verify the payload's integrity by computing the expected hash and comparing it to the received hash.

Creating a Secret Token

Ask our team to generate a secret token using a high-entropy string, which will be used to compute a hash signature for each payload. When creating a new webhook, input this token into the appropriate field in your configuration settings.

Storing the Secret Token Securely

Store the token in a secure location accessible by your server's environment. Avoid hardcoding it directly into your codebase or version control systems.

Plain example

Given this payload:

{
  "date": "2023-12-19T15:00:00.000Z",
  "deliveryId": "PARTNERREF12345",
  "event": "DELIVERY_ADDED"
}

With this signatureKey : 12345-abcde-£.?./+
Header will be prefixed with sha256= so an example header given the signatureKey and payload above :

X-Shopopop-Signature-256 : sha256=0dd4e829b49855c4238ca56b9cc241aee35106274124ca656ace52b277cc07dc

Verifying Webhook Payloads

JavaScript Example:

const crypto = require('crypto');

function verifySignature(payload, receivedSig, secret) {
    const hash = crypto.createHmac('sha256', secret)
                       .update(payload)
                       .digest('hex');
    const expectedSig = `sha256=${hash}`;
    return crypto.timingSafeEqual(Buffer.from(expectedSig), Buffer.from(receivedSig));
}

// Example usage
const payload = JSON.stringify(request.body);
const receivedSig = request.headers['x-shopopop-signature-256'];
const secret = process.env.SIGNATURE_KEY;

if (!verifySignature(payload, receivedSig, secret)) {
    console.error('Invalid signature');
}

Python Example:

import hmac
import hashlib

def verify_signature(payload, received_sig, secret):
    hash = hmac.new(secret.encode(), msg=payload.encode(), digestmod=hashlib.sha256).hexdigest()
    expected_sig = f'sha256={hash}'
    return hmac.compare_digest(expected_sig, received_sig)

# Example usage
payload = request.get_data(as_text=True)
received_sig = request.headers.get('X-Shopopop-Signature-256')
secret = os.getenv('SIGNATURE_KEY')

if not verify_signature(payload, received_sig, secret):
    print('Invalid signature')

Troubleshooting

If the signature verification fails:

  • Ensure the secret token is correct and securely stored.
  • Confirm that the X-Shopopop-Signature-256 header is being used.
  • Make sure the payload and headers are not modified in transit, possibly by middleware or proxies.
  • Ensure that the payload is handled as UTF-8 to accommodate any unicode characters.

By following these guidelines, you can secure your webhook interactions against unauthorized and tampered requests.

Retry policy

If webhooks calls are rejected by the partner with one of these HTTP errors : 408/429/500/502/503/504, then a new call is tried 1 min later.

If we still get an error, 2 other tries are done after 15 min and 60 min.

Authorizations:
None
header Parameters
X-Shopopop-Signature-256
required
string

The signature of the request body, computed using the HMAC-SHA256 algorithm, the secret token as key, and the request body as value, then encoded to hexadecimal.

Request Body schema: application/json

Information about the event

event
required
string (WebhookEvents)
date
required
string <date-time>
deliveryId
required
string
required
object

Responses

Request samples

Content type
application/json
Example
{
}