Shopopop API documentation (1.0.0)

Overview

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

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

General information

All calls must use HTTPS.

Environments

All the endpoints are available in

  • Staging : for testing purpose
  • Prod : for production

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

  • Staging : https://partners-api-preprod.shopopop.com
  • Prod : https://partners-api.shopopop.com

Authentication

  • Each call must have the api_key and partner_id header.

  • Access information (api_key / partner_id) will be communicated by Shopopop.

Deliveries

All deliveries endpoints

Check the eligibility of a delivery

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

Authorizations:
partnerApiKey
header Parameters
partner_id
string
api_key
string
Request Body schema: application/json
required
partner_id
string or null
api_key
string or null
required
object (PartnerDataRequest)

Responses

Request samples

Content type
application/json
{
}

Response samples

Content type
application/json
Example
{
}

Create a delivery

Create delivery request

You will notice this request parameters and the Check eligibility ones are the same.

⚠️ Calling this route immediately creates a valid delivery in our system and available for all shoppers.

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

Any updates on the created delivery will be done by our Customer Service.

To cancel a delivery, please refer to the next part of this document.

Authentication

api_key and partner_id can be provided in the header (better) or in the body

Authorizations:
partnerApiKey
header Parameters
partner_id
string
api_key
string
Request Body schema: application/json
required
partner_id
string or null
api_key
string or null
required
object (PartnerDataRequest)

Responses

Response Schema: application/json
creation_date
required
string <date-time>
message
required
string (DuplicateDeliveryMessage)
Value: "DUPLICATE"

Request samples

Content type
application/json
{
}

Response samples

Content type
application/json
{
}

Shift delivery slot

Authorizations:
partnerApiKey
path Parameters
deliveryId
required
string
header Parameters
partner_id
string
api_key
string
Request Body schema: application/json
optional
delivery_start
required
string

start of the new delivery slot (format ISO full UTC), ex. 2023-09-03T14:30Z

delivery_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

The errorDesc field could have multiple values :

  • DELIVERY_DATE_TOO_CLOSE The date/time required for the delivery is too close (at least 2 hours before the beginning of the delivery timeslot).

  • DELIVERY_DISTANCE_TOO_LONG Distance between customer address and pickup location (drive) is too far.

  • WRONG_INTERVAL_BETWEEN_DELIVERY_DATES Delivery slot is too short.

{
}

Cancel delivery

Authorizations:
partnerApiKey
path Parameters
deliveryId
required
string

delivery's unique ID

header Parameters
partner_id
string
api_key
string
Request Body schema: application/json
required
partner_id
string or null
api_key
string or null
reason
required
string

reason of the cancellation

Responses

Request samples

Content type
application/json
{
}

Response samples

Content type
application/json
{
}

Delivery status

Return the latest status of a delivery.

Authorizations:
partnerApiKey
path Parameters
deliveryId
required
string

delivery's unique ID

header Parameters
partner_id
string
api_key
string

Responses

Response Schema: application/json
status
required
string (DeliveryEventsStatus)
event_date
required
string <date-time>

Response samples

Content type
application/json
Example
{
}

Delivery history

Return all the events that occured on a delivery.

Authorizations:
partnerApiKey
path Parameters
deliveryId
required
string

delivery's unique ID

header Parameters
partner_id
string
api_key
string

Responses

Response Schema: application/json
Array
status
required
string (DeliveryEventsStatus)
Enum: "ADDED" "ARRIVED_AT_CLIENT" "ARRIVED_AT_DRIVE" "BOOKED" "CANCELLED" "GOING_TO_CLIENT" "GOING_TO_DRIVE" "REMOVED" "SHOW_REFERENCE" "VALIDATED" "DELIVERY_INCIDENT"
event_date
required
string
required
object (DeliveryEventAdditionalInfos)

Response samples

Content type
application/json
[
]

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.

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

Responses

Request samples

Content type
application/json
Example
{
}