# Delhivery Shipping for GoCommerce — Open-Source Module

> Manifest parcels with Delhivery from a GoCommerce order: the API token, pickup warehouse, GSTIN, COD amounts, units, and what the module leaves out.

- Canonical: https://kitcommerce.store/integrations/fulfill-delhivery/
- Last updated: 2026-09-25

---

Shipping

## Delhivery shipping for GoCommerce

A Go package that manifests a parcel with Delhivery and takes the waybill Delhivery assigns, from the engine’s own fulfillment call. An API token, a registered warehouse and a seller name are what it needs.

- **Shipping** module
- **10** settings
- **8** tests
- **ext/fulfill-delhivery**

### What it does

Registering the module adds “delhivery” as a fulfillment provider. An operator ships the usual way — the admin’s ship dialog, or POST /api/admin/create-fulfillment with "provider": "delhivery" — and the module manifests the parcel with Delhivery and returns the waybill as the tracking number, with the carrier recorded as Delhivery. The engine stores the shipment and moves the order on; the module only talks to Delhivery.

In the admin it describes itself as “Manifests parcels with Delhivery and takes the waybill it assigns.” It sends the parcel’s own lines, weight, size and value — the engine has already worked out what goes in this box — plus the seller details printed on the label.

Delhivery’s manifestation endpoint is not a JSON API: it takes a form whose data field holds the whole payload as a JSON string. The package doc records that sending JSON as the body returns a bare 400 with no explanation, which is why this module encodes twice and looks unlike its neighbours.

### Configuration

Three settings are required: the API token, the pickup warehouse’s nickname and the seller name. Set them in Config from your own main(), or leave Config empty and fill them in under Settings › Shipping providers.

*Delhivery module settings — 10 settings, 3 required*

| Setting | Environment variable | Required | What it does |
| --- | --- | --- | --- |
| `Token` API token | `DELHIVERY_TOKEN` | Yes | Sent as Authorization: Token \<token>. The staging host takes a different token from production. |
| `PickupLocation` Pickup location | — | Yes | The warehouse nickname registered with Delhivery, matched case-sensitively on their side. |
| `SellerName` Seller name | — | Yes | Printed on the label. Required because, in the code’s words, an unnamed seller is a parcel nobody can return. |
| `SellerAddress` Seller address | — | No | Printed on the label. |
| `SellerGSTIN` Seller GSTIN | — | No | Sent as seller_gst_tin when set. Optional here, because whether Delhivery requires it depends on what the store sells. |
| `HSNCode` HSN code | — | No | Sent with every parcel when set. One code for the whole store. |
| `DefaultWeightGrams` Default weight (grams) | — | No | Per unit, for a parcel the engine could not weigh. 500 g when unset. |
| `DefaultLengthCM, DefaultWidthCM, DefaultHeightCM` | — | No | The box used for any parcel of more than one unit, where the engine has no single size. 15 × 15 × 10 cm when unset. Go only. |
| `BaseURL` API base URL | — | No | Defaults to production, https://track.delhivery.com. Staging is https://staging-express.delhivery.com. |
| `Client` | — | No | Replaces the HTTP client, which otherwise times out after 30 seconds. Go only; not in the panel. |

The module reads its Config struct, not the environment. The variable names are the ones the package’s own example or the reference binary uses; in your own `main()` you choose where each value comes from. Where a setting has a panel label, the admin’s settings drawer can hold it too, and a value typed there wins over Config.

### Setting it up

1. **Register the warehouse** — In Delhivery, register the pickup warehouse and note its nickname exactly — it is matched case-sensitively — and copy the API token.
2. **Install the module** — Import it and pass delhivery.New to gocommerce.New, as below — or run the reference binary with -carriers, which installs every carrier module idle.
3. **Configure it** — Token, pickup location and seller name, in Config or under Settings › Shipping providers. Add the GSTIN and HSN code if your goods need them.
4. **Ship an order** — Choose Delhivery in the admin’s ship dialog, or POST /api/admin/create-fulfillment with "provider": "delhivery". The waybill becomes the tracking number.

main.go

```
import (
	"os"

	"github.com/itswadesh/gocommerce/core"
	delhivery "github.com/itswadesh/gocommerce/ext/fulfill-delhivery"
)

app, err := gocommerce.New(cfg,
	delhivery.New(delhivery.Config{
		Token:          os.Getenv("DELHIVERY_TOKEN"),
		PickupLocation: "Primary",
		SellerName:     "Acme Retail",
	}),
)
```

The package doc’s own example, with its imports; cfg is your gocommerce.Config. With an empty delhivery.Config the module installs idle and waits for the panel. Import path `github.com/itswadesh/gocommerce/ext/fulfill-delhivery`.

### How it works

- **A form with JSON inside**

  The manifest is posted to /api/cmu/create.json as a URL-encoded form, format=json and data= holding the payload — the shape that endpoint accepts.

- **A refusal is a failure**

  Delhivery can answer 200 with a refusal inside. A package without a waybill is treated as refused and Delhivery’s remarks are returned, so the engine does not move the order to shipped.

- **COD is this parcel’s value**

  An unpaid order is booked COD with cod_amount set to the value of what is in this parcel; a paid order is booked Prepaid and collects nothing.

- **Grams and centimetres**

  Weight goes in grams and the sides in centimetres, kept to the tenth. The engine’s measured weight is used only when every line was weighed; otherwise the default per unit.

- **A new id per parcel**

  Delhivery rejects a duplicate order id, so the first parcel goes as the order number and later ones as number-2, number-3 and so on.

- **Pre-pulled waybills**

  A waybill passed in the request’s meta is sent with the manifest — in the code’s words, how a store prints labels ahead of manifesting them.

### What it does not do

Read these before an order depends on it. No store is known to run GoCommerce in production yet, so these come from the code, not from anyone’s experience.

- **No label URL** — The module returns the waybill and the carrier, not a label. Labels come from Delhivery’s own tools.
- **No tracking updates** — Nothing comes back after manifesting: no webhook, no polling. Marking an order delivered is a separate step, in the admin or through the API.
- **No rates, pickups or cancellation** — It quotes no rates and books no pickup, and deleting a fulfillment in GoCommerce does not cancel the manifest in Delhivery.
- **The units are an assumption** — The package doc says Delhivery’s documentation does not state its units; grams and centimetres are what working integrations send. A store that finds otherwise should say so.
- **One HSN code for the store** — HSNCode is a single setting sent with every parcel. A catalogue with goods under several codes cannot vary it per product.
- **Rupees only, in practice** — Amounts are minor units divided by 100. The code notes that is exact for INR, the only currency Delhivery settles cash on delivery in.

FAQ

### Questions about the Delhivery module

**Does it need a GSTIN?**

Not to be installed. The module sends seller_gst_tin and hsn_code only when they are set, because — as its own comment puts it — whether they are mandatory depends on what the store sells, and Delhivery is the one entitled to refuse.

**Can I test against Delhivery’s staging?**

Yes. Set BaseURL to https://staging-express.delhivery.com and use a staging token; the two hosts take different tokens. Left empty, BaseURL is production.

**Why does a shipment fail with a reason from Delhivery?**

Because Delhivery refused it. It can answer HTTP 200 with a refusal per package, and the module reports that package’s remarks rather than letting the engine mark the order shipped. Fix what the remark names and ship again.

**Does the order update when the parcel is delivered?**

No. The module manifests and returns; it has no webhook and polls nothing. Mark the order delivered from the admin or with POST /api/admin/orders/{id}/deliver.

**Is Delhivery a partner?**

No. The module calls Delhivery’s API with a token you supply. Delhivery does not endorse GoCommerce, and no store is known to run this module in production yet.

### Source

Everything on this page is read from [`ext/fulfill-delhivery`](https://github.com/itswadesh/gocommerce/tree/main/ext/fulfill-delhivery) in the GoCommerce repository, MIT licensed. When this page and the code disagree, the code is right and this page is out of date.Delhivery is a trademark of its owner; this module talks to its public API and implies no endorsement. See [trademarks](https://kitcommerce.store/about/#trademarks).

- [ext/fulfill-delhivery on GitHub](https://github.com/itswadesh/gocommerce/tree/main/ext/fulfill-delhivery)
- [Delhivery](https://www.delhivery.com)
- [All GoCommerce modules](https://kitcommerce.store/integrations/)

### Try it against a store of your own

The one-command stack gives you GoCommerce’s API and admin on your own machine in minutes. Add this module to it and try it on test orders before a real one depends on it.

[Deploy in minutes](https://kitcommerce.store/#one-command) · [Read the module](https://github.com/itswadesh/gocommerce/tree/main/ext/fulfill-delhivery) · [All integrations](https://kitcommerce.store/integrations/)
