# Shipment Creating

The Shipment Creation function is triggered whenever a new shipment or a return shipment is created. The following app function allows the shipping company to call its API to generate the AWB label, return the tracking link, and provide tracking information. The returned data is then used to update the shipment details inside Salla.

## Step By Step Guide

On Salla Partners Portal, click on "+ Add New Function"

![SCR-20251118-jhsx.png](https://api.apidog.com/api/v1/projects/451700/resources/366102/image-preview)

Select the App Function you want to add, which is in this case the Shipment Cancelled Function. After selecting, add a name to the function.


![](https://api.apidog.com/api/v1/projects/451700/resources/366103/image-preview)

### Code Details

Salla auto-generates starter code, which you can overwrite with the following implementation. This gives a clear place to plug in your shipping logic and connect Salla with the shipping company’s API.

![17C40F55-BDDF-4E3A-9B7F-CCD8A87E9A98_1_201_a.jpeg](https://api.apidog.com/api/v1/projects/451700/resources/367585/image-preview)

:::note[]
This flow handles both shipments and return shipments. Shipments use the payload type `"shipment"`, while returns follow the same process with the payload type `"return"`.
:::

<Tabs>
  <Tab title="Explanation">

<Steps>
  <Step title="Function definition">
    This function is autogenerated by Salla. It runs when Salla triggers Shipment Creation, receives the `context` data, and must return a `Shipment` object.
    ```js
    export default async (context: Shipments): Promise<Shipment> => {
    ```
  </Step>

  <Step title="Shipment Company API call">
    Declares the supported shipment types: a forward shipment or a return shipment. This makes it easier to branch logic later.
    ```js
      // generate the awb from thridparty shipping API
  const labelRequest = {
        shipment_id: shipment.id,
        order_id: shipment.order_id,
        tracking_number: shipment.tracking_number,
        origin_address: shipment.ship_from,
        shipping_address: shipment.ship_to,
        customer: {
          id: settings.customer_id,
        },
        label_options: {
          format: settings.label_format, // pdf
          size: settings.label_size, // A6
        },
  };

  const response = await fetch(`https://api.mock.com/label/generate`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(labelRequest),
  });

  const result = await response.json();
    ```
  </Step>

  <Step title="Build and return final Shipment object">
    This part is autogenerated by Salla. It builds the final response using Salla’s `Shipment` builder. All fields are taken from the updated `shipmentResponse` object and returned to Salla.
    ```js
    return Shipment.success()
        .setShipmentNumber(shipment.id)
        .setPdfLabel(result.label_url);
    ```
  </Step>
</Steps>

  </Tab>
  <Tab title="Full Code">

Feel free to copy the below code and paste it *(with some modifications)* to the Salla Partners Portal > App Functions.
      
```js
export default async (context: Shipments): Promise<Shipment> => {
  const { payload, settings, merchant } = context;
  const { data: shipment } = payload;

  const labelRequest = {
    shipment_id: shipment.id,
    order_id: shipment.order_id,
    tracking_number: shipment.tracking_number,
    origin_address: shipment.ship_from,
    shipping_address: shipment.ship_to,
    customer: {
      id: settings.customer_id,
    },
    label_options: {
      format: settings.label_format, // pdf
      size: settings.label_size, // A6
    },
  };

  const response = await fetch(`https://api.mock.com/label/generate`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(labelRequest),
  });

  const result = await response.json();
  /*
   * The Shipment can be used to set multiple things based on the use
   * case. There are other setter methods available to set other things.
   * The setShipmentNumber() is required to be set to identiify shipment.
   * Use Shipment.error() incase an error needs to be returned.
   */
  return Shipment.success()
    .setShipmentNumber(shipment.id)
    .setPdfLabel(result.label_url);
    .setStatus(ShipmentStatusEnum.IN_TRANSIT);
};
```
  </Tab>
</Tabs>
      

### Sequence Diagram
      
The following diagram shows visually how the shipment creating app function works within Salla Partners Portal:
      
```mermaid
sequenceDiagram
    actor m as Salla Merchant
    participant s as Salla App Function
    participant a as Your Server
    participant p as Salla API
    m->>s: Create Shipment
    Note right of m: Auto when Order Status is 'completed' <br/> or policy is requested by Merchant
    s->>a: Make an API call to your server
    Note left of a: POST {SHIPMENT_COMPANY}/{GENERATE_AWB}
    a->>a: Generate Shipment
    Note left of a: Get shipment details <br/> {awb_label, tracking_number, tracking_link ..}
    a->>s: Provide Shipment Details via API
    s->>s: Update Shipment Details
    Note left of s: in order details and history
    s->>m: Return Shipment Details
     Note right of a: Optional realtime shipment updates
    a->>p: PUT /shipment/{shipment_id} <br/> {cost, status_note} 
```
