# Sendcloud

Source: https://developers.swell.is/app-guides/sendcloud

The Sendcloud app connects your Swell store to Sendcloud. Orders are sent to Sendcloud's Incoming Orders, where you create shipping labels. When a label is created, the app adds the carrier and tracking number to the Swell order and fulfills it, and Sendcloud keeps the parcel status up to date on the order.

The app works with any storefront. It doesn't change checkout, and the shipments it creates are standard Swell shipments.

## How it works

| When | What the app does |
| --- | --- |
| An order is paid, or submitted if you choose | Sends the order to Sendcloud's Incoming Orders with its shipping address, customer, items, weights and totals. |
| A label is created in Sendcloud | Adds the carrier and tracking number to the Swell order, and creates a shipment for the items still to be shipped, which fulfills the order. |
| The parcel's status changes | Updates the status, tracking number, tracking link and carrier on the order's Sendcloud tab. |
| A parcel is canceled in Sendcloud | Cancels the Swell shipment created for it. |
| An order is canceled in Swell | Removes the order from Sendcloud's Incoming Orders. |

Only order items with the shipment delivery type are sent. An order without any is not sent.

Sendcloud reports parcel changes to the app through a webhook, which you connect during setup.

## Before you begin

- A Sendcloud account.
- Your Swell store ID, and the public key of the environment you are connecting. Public keys are under **Developer > API keys** in the Swell dashboard.
- A separate Sendcloud API integration for each environment you connect. An integration has one webhook URL, and the URL points to one Swell environment.
- Shipment weights on your products, so each order is sent with its weight. Orders without weights use the **Default parcel weight** setting.

## Set up

Install Sendcloud from the Swell App Store, and set it up in your test environment before the live one. Orders from the test environment are sent to the Sendcloud integration you connect there, the same way live orders are.

**1. Create a Sendcloud API integration**

In Sendcloud, go to **Settings > Integrations** and add a **Sendcloud API** integration. Copy its **Public Key** and **Secret Key**, and note its **Integration ID**, the number at the end of the integration's page URL.

**2. Add the keys to the app**

In Swell, go to **Apps > Sendcloud > Settings**, enter the **Public Key**, **Secret Key** and **Integration ID**, and click **Save settings**. If the integration shows a separate **Webhook Signature Key**, enter it too.

Orders are sent when they are paid. To also ship unpaid orders, such as cash on delivery, set **Send orders to Sendcloud when** to **Order is submitted**.

**3. Build the webhook URL**

The **Webhook URL** setting shows this pattern:

```txt
https://{store-id}:{public-key}@{store-id}.swell.store/functions/sendcloud/sendcloud-webhook
```

Replace `{store-id}` with your Swell store ID in both places, and `{public-key}` with the public key of the environment you are connecting. Use a public key, never a secret key.

**4. Connect the webhook in Sendcloud**

In the Sendcloud integration, paste the URL into **Webhook URL**, turn on **Webhook feedback enabled** and click **Save**. **Test API Webhook** in Sendcloud should return 200.

**5. Place a test order**

Place an order for a product that ships, and pay for it. The order's **Sendcloud** tab in Swell shows a **Sendcloud order ID** and the status **Sent to Sendcloud**. The fields fill in a few seconds after payment, so refresh the page if they are empty.

In Sendcloud, find the order in **Incoming Orders** and create a label. The Swell order then shows the parcel status and tracking number, and has a shipment.

**6. Go live**

In the live environment, repeat steps 1 to 4 with a separate Sendcloud API integration and your live public key.

## Using Sendcloud

### Fulfillment

- When a parcel has a label, the app creates a shipment for every item still to be shipped. The shipment has the carrier, shipping method and tracking number from Sendcloud, and a note with the Sendcloud parcel ID and tracking link.
- To fulfill orders yourself, turn off **Create Swell shipment when label is created**. Tracking is still saved on the order's **Sendcloud** tab.
- The **Tracking page** link on the order's **Sendcloud** tab can be shared with the customer.

### Canceled orders and parcels

- Canceling an order in Swell removes it from Sendcloud's Incoming Orders. A label that was already created is not canceled, so cancel it in Sendcloud.
- Canceling a parcel in Sendcloud cancels the Swell shipment the app created for it. A new label for the order then replaces the canceled parcel.

### Weights and addresses

- Item weights come from each product's shipment weight and are converted to kilograms from your store's weight unit. Orders whose items have no weight are sent with the **Default parcel weight**.
- Sendcloud needs the street and the house number separately. The app splits the first address line on a number at its start or end, so "Stationsstraat 12A" is sent as Stationsstraat and 12A. If neither matches, the whole line is sent as the street. Check the address in Sendcloud if a label fails.
- The shipping service chosen at checkout is sent to Sendcloud with the order. HS codes and countries of origin are sent for products that have them.

### Parcel statuses

The **Status** field shows Sendcloud's status message for the parcel. Common statuses:

| Status | Meaning |
| --- | --- |
| Sent to Sendcloud | The order is in Sendcloud's Incoming Orders, with no label yet. Set by the app. |
| Ready to send | The label is created. The app creates the Swell shipment. |
| En route to sorting center, Driver en route | The parcel is on its way. |
| Awaiting customer pickup | The parcel is at a pickup point. |
| Delivered | The parcel was delivered. |
| Cancelled, Cancellation requested | The parcel was canceled. The app cancels the Swell shipment it created. |

### In the dashboard

| Location | What it shows |
| --- | --- |
| Order > Sendcloud tab | The Sendcloud order ID, parcel status, parcel ID, carrier, tracking number, a link to the tracking page, and the last error. |
| Orders list | A Sendcloud column with the parcel status of each order. |
| Order > Fulfillment | The shipment created from the Sendcloud label. |

## Settings

Settings are in **Apps > Sendcloud > Settings** and are saved separately for each environment.

| Setting | Description | Default |
| --- | --- | --- |
| Public Key | Public key of your Sendcloud API integration. Required. | None |
| Secret Key | Secret key of the same integration. Required. Also verifies webhook signatures, unless a Webhook Signature Key is set. | None |
| Integration ID | ID of the Sendcloud API integration, the number at the end of its page URL in Sendcloud. Required. Orders are created under this integration. | None |
| Webhook URL | Pattern of the webhook URL to paste into Sendcloud. Read-only. | Set by the app |
| Webhook Signature Key | Only needed if your Sendcloud integration shows a separate Webhook Signature Key. | None |
| Send orders to Sendcloud when | Order is paid, or Order is submitted to also ship unpaid orders such as cash on delivery. | Order is paid |
| Default shipping option code | Preselects a Sendcloud shipping option on each order, for example postnl:standard. Leave it empty to choose in Sendcloud or use your Sendcloud shipping rules. | None |
| Default parcel weight (kg) | Weight sent when an order's items have no shipment weight. | 1 |
| Create Swell shipment when label is created | Fulfills the Swell order with the carrier and tracking number when a label is created. | On |
| Enabled | When off, new orders and cancellations are not sent to Sendcloud. Updates from Sendcloud are still applied. | On |

## Limitations

- Labels are created in Sendcloud. The app doesn't create labels from Swell.
- Shoppers don't see Sendcloud shipping rates at checkout.
- One parcel is tracked per order. A second parcel replaces the first only after the first is canceled, and multi-parcel (multicollo) shipments aren't tracked separately.
- Canceling a Swell order doesn't cancel a label that was already created.
- Sendcloud's order API documents prices in EUR, GBP and USD only. Orders in other currencies may be rejected, and the error is shown on the order.
- An order is sent once. If sending fails because of the order's data or your keys, fixing the problem doesn't resend it.

## Troubleshooting

### The Sendcloud tab is empty right after an order is placed

The order is sent a few seconds after it is paid. Refresh the page.

### An order doesn't appear in Sendcloud

The order must be paid, or submitted if you chose that setting, and have at least one item to ship. Check that **Enabled** is on, and that **Public Key**, **Secret Key** and **Integration ID** are filled in. Orders placed while the app was turned off or the keys were missing are not sent later.

### The Sendcloud tab shows an error

| Error | What to do |
| --- | --- |
| Missing shipping address | Add a shipping address to the order. |
| Sendcloud 401 or Sendcloud 403 | The keys are wrong or belong to another integration. Copy the Public Key, Secret Key and Integration ID again from the same Sendcloud integration. |
| Sendcloud 400, followed by a field name | Sendcloud rejected part of the order, usually the address or the currency. Correct the order data. |

An order that failed to send is not resent after you fix the problem. To ship it, create the parcel in Sendcloud with the Swell order number as its order number. The app matches parcels to orders by order number, so tracking still reaches the Swell order.

### The webhook test in Sendcloud fails

Check the webhook URL: your store ID in both places, the public key of the right environment, and the path `/functions/sendcloud/sendcloud-webhook`. Check that the **Secret Key** in the app matches the integration. If the integration shows a separate Webhook Signature Key, enter it in the app settings.

### Tracking doesn't update

Check that **Webhook feedback enabled** is on in the Sendcloud integration, and that the webhook URL is saved there.

### The order isn't fulfilled after the label is created

Check that **Create Swell shipment when label is created** is on, and that the order still has items to ship.

## Uninstalling

Uninstalling the app stops sending orders to Sendcloud and stops applying Sendcloud's updates. Uninstalling applies to the environment you are in, so remove the app from the test and live environments separately.

Shipments the app created are standard Swell records and stay in your store.

Uninstalling doesn't change anything in Sendcloud. Orders already in Incoming Orders and labels already created stay there. Remove the webhook URL from your Sendcloud integration, or delete the integration if you no longer use it.

## For developers

The app stores its data under `$app.sendcloud` on orders.

| Field | Description |
| --- | --- |
| sendcloud_order_id | ID of the order in Sendcloud's Incoming Orders. |
| sendcloud_parcel_id | ID of the Sendcloud parcel tracked for the order. |
| sendcloud_status_id | Sendcloud parcel status ID. |
| sendcloud_status | Sendcloud parcel status message, or Sent to Sendcloud before a parcel exists. |
| sendcloud_tracking_number | Tracking number of the parcel. |
| sendcloud_tracking_url | Tracking page of the parcel. |
| sendcloud_carrier | Sendcloud carrier code. |
| sendcloud_shipment_id | ID of the Swell shipment created from the label. |
| sendcloud_error | Most recent error from sending the order. |
| sendcloud_status_timestamp | Timestamp of the latest webhook update applied, used to skip updates that arrive out of order. |

Orders are created with Sendcloud's v3 Orders API, under the integration set in the app settings. Each is sent with the Swell order ID as its order ID and the Swell order number as its order number. Canceled orders are deleted with the same API.

Sendcloud sends `parcel_status_changed` events to the public route `/functions/sendcloud/sendcloud-webhook`. The app checks the `Sendcloud-Signature` header with the Webhook Signature Key, or the Secret Key when none is set, matches the parcel to a Swell order by order number, and skips updates older than the last one applied. Other events are acknowledged and ignored.

## Support

Swell builds and maintains the Sendcloud app. For help with the app, email support@swell.is. For questions about your Sendcloud account, labels or carriers, contact Sendcloud.
