Skip to content

Powered by Grav CMS + Helios Theme

Labels

This page covers buying postage from an order, what to do when a purchase goes wrong, and how a refund works.

Before you begin

  • A ship-from address, at least one carrier switched on, and a working key. See Getting started.
  • kahunacart.shipping.labels to buy or void. Reading a label and its tracking takes kahunacart.orders.view.
  • Your label format chosen on the Settings → Labels tab. It cannot be changed after a label is bought.

Buy a label

  1. In the admin sidebar, click KahunaCart, then Orders, and open an order with something left to ship.
  2. In the parcels panel, click Buy label.
  3. Check the parcels the packer made and the address the courier read back.
  4. Choose a service from the ones the courier quoted.
  5. Click the confirm button, which names the price: Buy this label for $9.41.

The label is bought, the file is kept on your server, the parcel is recorded on the order, and the shipped email goes out with a working tracking link on it.

Note

Buy label appears only on an order that has something left to ship, has a delivery address with a country, and on a store with a ship-from address and a working key. The button's tooltip says which of those is missing rather than making you guess.

What happens when you press it

Seven steps, and the order of them is the design.

  1. The order is locked. Two people pressing the button at the same moment meet here, and one of them waits.
  2. A key is worked out from the store, the order, the service and what is in the parcels. The same button pressed twice produces the same key.
  3. A row is written and saved before any money is spent. This is what makes an unknown outcome recoverable rather than only regrettable.
  4. The label is bought, with nothing holding the database open while the courier thinks about it.
  5. The row is settled: bought, with the tracking number, the cost and the file; or failed, with the courier's own words. The cost is in the currency of your carrier account, whatever the order was sold in, and the row keeps that currency beside it. See Selling in more than one currency.
  6. The parcel is recorded on the order, which works out whether the order is now partly or fully shipped and queues the shipped email.
  7. The label is linked to the shipment and the purchase is written into the order's history.

The six states a label can be in

Status On screen What it means
pending Being bought Nobody knows yet whether it was bought. It is being chased.
bought Bought There is a label, a number and a price.
failed Refused The courier or the aggregator said no, in their own words.
void_requested Refund asked for A refund has been asked for and has not settled. This is not a failure.
voided Refunded The money came back.
void_refused Refund refused The label had been used. It is still a bought label.

Every one of those has a row on the Labels tab, and where there is anything to do about it there is a button on the row.

Open or reprint a label

  1. Open KahunaCart → Shipping carriers and the Labels tab, or open the order.
  2. Click Open the label.

The file is downloaded at the moment it is bought and kept on your server, under user/data/kahunacart-shipping/labels/. The aggregator's own link to it expires, so a label you print again in March would otherwise be a 404 exactly when you need it.

If the stored file has gone, the button falls back to the aggregator's link and tells you it did. If that has expired too, the honest answer is the one you get: void the label and buy another.

Important

The format is chosen before the label is bought and cannot be changed afterwards — no courier converts a label from one format to another. Pick pdf_4x6, pdf, png or zpl to match your printer and leave it alone.

Void a label

  1. Open the Labels tab and find the label.
  2. Click Void….
  3. Confirm.

Voiding is slow, and the screen says so rather than showing you a spinner.

Rule The number
How long you have to ask 90 days from the purchase
How long it takes to settle up to 14 business days
A used label cannot be refunded at all

A request outside the ninety days is refused here, before anything is sent, naming the date the label was bought. Nothing recovers it — the postage is spent, and saying so plainly is the only honest answer.

In between asking and settling the label reads Refund asked for, which is a normal steady state and not a stuck one. It is being asked about in the background.

Note

One clock people confuse with the refund window: a USPS label must be used within 30 days of being bought. That is a different rule with a different number and nothing to do with refunds.

Tip

In test mode a refund comes back pending and stays that way, and the transaction reads REFUNDPENDING. A test proves the request was accepted and recorded. It proves nothing about the money, because there is none.

When a purchase goes wrong

What happened What you see What fixes it
The address is refused The sheet stays open with the courier's messages under the fields, and its correction offered Correct the address on the order and try again
The service is not available The sheet says so and offers the ones that are Pick another service
The aggregator has no balance The purchase fails, in the aggregator's words Top the account up
Customs facts are missing The sheet names the lines and the fields, before the button Fill them in on the product. See Customs
The purchase timed out "We could not tell whether the label was bought", and a row reading Being bought Nothing. A job asks the courier every minute and settles it
The chase gave up A banner on the order and a Label outcome unknown notification Open the aggregator's own console. Then Record the parcel, or buy again
The label was bought and the shipment was not written A banner naming both facts Record the parcel finishes the job with the number in hand, or Void refunds it
Two people pressed Buy at once The second is told a label already exists Nothing. The database refused the second write

Important

A bought label whose shipment failed to write is not rolled back automatically. Throwing away paid-for postage to tidy up a database error is the wrong trade, so both facts are put in front of you and you choose.

Buy a label automatically when an order is paid

Off by default, and worth leaving off until the packing on the Boxes tab looks right — a store whose packer is making three parcels where two would do will be buying three labels a time before anybody notices.

  1. Open KahunaCart → Shipping carriers and the Settings tab.
  2. On the Labels tab, switch Buy a label when an order is paid on (labels.auto_buy_on_paid).
  3. Click Save.

Switched on, it buys everything still owed on an order once the order is paid in full, using the service the customer's own shipping method names. A method that names no carrier service — a flat rate, free shipping — buys nothing, which is not a failure.

When that is depends on how the customer paid:

The customer paid by The label is bought
Card, captured at checkout Straight away, when the order is placed
Bank transfer or another offline method When the money arrives and the order is marked paid
A card that was only authorised When the payment is captured
A deposit, with the balance still to come When the balance is paid

The money can arrive any way at all — a pay link, a provider webhook, a capture, or you pressing Mark paid — and the label follows it. You can still buy a label by hand from the order screen at any time, paid or not.

Nobody is on a screen when this goes wrong, so it tells you. If the parcels could not be planned, No label was bought for a paid order goes to your channels with the order number, once per order per day. If a label could not be voided on an order that was refunded or cancelled, A label could not be voided goes out at high priority, once per label, because the postage is spent. It is sent when the carrier says no, when the ninety days for a refund have passed, when the carrier cannot refund from here, when the request could not be made at all, and when a refund that was pending is refused later. The message gives a plain reason and never the carrier's own words, which can repeat a customer's details. A refund that is merely pending is not a failure and sends nothing. A carrier turning a purchase down is the existing Label refused message.

It hangs off KahunaCart's compensating hooks rather than a plain event listener, which buys two things:

  • It cannot buy twice. An order that completes twice — a retried webhook, a job that ran again after a worker was killed — runs it exactly once. A payment that arrives twice still buys one label, and an order paid at checkout is not bought again when it is marked paid.
  • A cancelled or refunded order voids its own label, including one bought when the money arrived after the order was placed. Only the labels it bought: a label you bought by hand was a decision, and undoing somebody's deliberate action is not what this is for.

Note

Before 1.1.1 this setting never bought a label at all: every automatic purchase was refused before the carrier was asked, and only a line in the Grav log said so. If you switched it on under 1.1.0 and saw nothing happen, that was the bug, and 1.1.1 fixes it. Check the packing looks right before you update with it switched on.

Who can do what

Action Permission
Quote an order, buy, void, record a parcel kahunacart.shipping.labels
Read a label, its file and its tracking history kahunacart.orders.view
Carrier accounts, boxes, addresses, customs facts, the address check kahunacart.shipping.manage

A user with kahunacart.orders.view and not kahunacart.shipping.labels sees the parcels panel with Buy label disabled and a line saying why, and the API refuses the purchase anyway.

What reaches the customer

The courier's name, the tracking number, its link, and the dates. Nothing else. No cost, no label file, no box, no internal note.

ShipEngine labels

A domestic quote is checked again on a shipment carrying its recovery reference. Its account, service and price must match before the fresh rate is bought; a changed price asks you to get fresh prices. For an international label, the driver obtains a fresh rate with the order's customs declaration and creates a full shipment carrying that declaration. It records ShipEngine's returned shipment_cost, downloads the requested PDF, PNG or ZPL, and keeps the hosted link as a fallback. A PNG link supplied beside a PDF is also downloaded for the label card, without buying another label. The sandbox key selects test shipping; the driver does not request unrecoverable sample labels.

If a purchase answer is lost, the reconciliation job finds the shipment through its external reference and reads its labels without buying again. That reference is for recovery; it is not an API guarantee against duplicate purchases. Voids are synchronous: the carrier either approves or refuses, and its message is kept.

Sendcloud labels

Test mode buys a free label. Sendcloud has no sandbox, so in Test mode every label is bought as Sendcloud's free Unstamped letter, whatever service the sheet named. The sheet still shows the real price for the service you picked, but the label row records a cost of 0 and says it was a test label. The file is Sendcloud's real letter label, with your sender line and the customer's address, and no carrier will carry it. Switch to Live to buy the service you chose.

One box per label. Sendcloud's label endpoint takes one parcel at a time, so an order the packer puts in two boxes cannot be bought as one Sendcloud shipment yet, and the purchase is refused with a sentence saying so. Pack it in one box, or buy those labels in Sendcloud's own panel.

A label is never bought twice. Each purchase carries the add-on's own reference, and Sendcloud answers a repeat with the shipment it already made. A purchase whose answer was lost is found again, not bought a second time.

Voiding is a request. Sendcloud cancels a label that has not been handed over at once, or queues it: it watches a label that is ready to send for fourteen days and cancels it if nothing happens to it. A queued label shows as Void requested, which is not a failure, and the store checks it again until it settles or the fourteen days are up. Sendcloud refuses any cancellation forty-two days after the label was made, and some carriers refuse one sooner.

The price on the label row is the price quoted just before the purchase, because Sendcloud's purchase answer does not include one. Your Sendcloud invoice is the final word.