Shipping

USPS labels for GoCommerce

A Go package that buys a label straight from the United States Postal Service’s APIs when an operator ships an order — no aggregator in between. USPS does not host the label, so the module keeps the PDF and serves it from one admin route.

What it does

The module registers “usps” as a fulfillment provider. An operator ships through the engine’s own POST /api/admin/create-fulfillment with the provider usps — the engine keeps the order’s state and its events, and the module only talks to USPS.

USPS needs two credentials to buy one label, and the package walks through the three calls: an OAuth client-credentials token, a payment authorisation tied to the CRID, MID and Enterprise Payment System account that will be charged, and the label itself. Both tokens are cached, so a hundred labels cost a hundred and two calls rather than three hundred.

The label comes back inline, as a base64 PDF. Rather than put a quarter of a megabyte into every order response, the module stores the bytes in its own table and serves them at GET /api/admin/x/fulfill-usps/labels/{tracking} — the one API operation it adds, open only to an operator with orders.read, because a label carries the buyer’s name and address.

Configuration

Eight settings are required: the developer application’s client id and secret, the CRID, MID and payment account from the Business Customer Gateway, a default mail class, and a ship-from street address and ZIP code. Set them in Config, or fill them in under Settings › Shipping providers.

USPS module settings — 18 settings, 8 required
SettingEnvironment variableRequiredWhat it does
ClientID
Client ID
USPS_CLIENT_ID Yes The consumer key of a USPS developer application.
ClientSecret
Client secret
USPS_CLIENT_SECRET Yes Its consumer secret. With the client id it mints the OAuth bearer token every USPS API takes.
CRID
CRID
USPS_CRID Yes From the Business Customer Gateway. With the MID and the account number it mints the payment authorisation that label creation needs.
MID
MID
USPS_MID Yes The mailer id, from the Business Customer Gateway.
AccountNumber
Payment account number
USPS_EPS_ACCOUNT Yes The payment account charged for postage.
ManifestMID
Manifest MID
— No The MID that manifests the shipment. Defaults to the MID, which is right for a store with one mailer id.
AccountType
Account type
— No EPS, the Enterprise Payment System, by default — in the code’s words, the only one most stores have.
MailClass
Mail class
— Yes The default service: USPS_GROUND_ADVANTAGE, PRIORITY_MAIL, PRIORITY_MAIL_EXPRESS and the rest. Meta mail_class overrides it for one parcel.
RateIndicator
Rate indicator
— No The rate band. SP, single piece, by default; meta rate_indicator overrides it for one parcel.
ProcessingCategory
Processing category
— No MACHINABLE by default; IRREGULAR, NON_MACHINABLE, LETTERS and FLATS are the others.
From.StreetAddress
From: street address
— Yes Where parcels are posted from.
From.ZIPCode
From: ZIP code
— Yes The ship-from ZIP code.
From.SecondaryAddress, From.City, From.State, From.Firm
From: unit, suite; city; state; firm
— No The rest of the ship-from address.
From.FirstName, From.LastName, From.ZIPPlus4, From.Phone — No Also part of the ship-from address, settable in Go only; the package doc’s example sets FirstName.
DefaultWeightGrams
Default weight (grams)
— No Per unit, for a parcel holding a variant with no weight recorded. 500 by default.
DefaultLengthMM, DefaultWidthMM, DefaultHeightMM — No The box sent when the engine has no unambiguous size, which is any parcel holding more than one unit. 230 × 150 × 50 mm by default. Go only.
BaseURL
API base URL
— No Overrides https://apis.usps.com, for tests. Empty for production.
Client — No Replaces the HTTP client, which otherwise times out after 45 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. Get the credentialsA USPS developer application gives the client id and secret; the Business Customer Gateway gives the CRID, the MID and the Enterprise Payment System account that pays for postage.
  2. Install the moduleImport it and pass usps.New to gocommerce.New, as below — or run the reference binary with -carriers, which installs every carrier module idle.
  3. Fill in the settingsCredentials, mail class and ship-from address, in Config or under Settings › Shipping providers. A value typed into the panel counts on the next shipment, with no restart.
  4. Ship and printPOST /api/admin/create-fulfillment with the order id and the provider usps. The shipment’s label URL points at /api/admin/x/fulfill-usps/labels/{tracking}, which serves the PDF.

main.go

import (
	"os"

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

app, err := gocommerce.New(cfg,
	usps.New(usps.Config{
		ClientID:      os.Getenv("USPS_CLIENT_ID"),
		ClientSecret:  os.Getenv("USPS_CLIENT_SECRET"),
		CRID:          os.Getenv("USPS_CRID"),
		MID:           os.Getenv("USPS_MID"),
		AccountNumber: os.Getenv("USPS_EPS_ACCOUNT"),
		From: usps.Address{
			FirstName: "Acme", StreetAddress: "4120 Bingham Ave",
			City: "St. Louis", State: "MO", ZIPCode: "63116",
		},
	}),
)

The package doc’s own example, with its imports; cfg is your gocommerce.Config. It sets no MailClass, which is required, so as written the module installs idle until a mail class is typed into the panel. Import path github.com/itswadesh/gocommerce/ext/fulfill-usps.

How it works

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.

FAQ

Questions about the USPS module

Where is the label kept?

In the module’s own table in your PostgreSQL database, as PDF bytes keyed by tracking number. GET /api/admin/x/fulfill-usps/labels/{tracking} serves it to an operator with orders.read, and to nobody else. It is the only fulfillment module with a route of its own, because USPS is the only carrier here that does not host its labels.

Why does it need so many credentials?

Because USPS asks for two tokens to buy one label: an OAuth token from the developer application, and a payment authorisation naming the CRID, MID and payment account that pay. Without the second, the package notes, every label call answers 401 with a perfectly valid bearer token.

Can it ship abroad?

Not as written. The label request has no destination country and no customs form, so it is for US domestic parcels.

Is this a USPS partnership?

No. The module calls the public USPS APIs with credentials you supply. USPS 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-usps in the GoCommerce repository, MIT licensed. When this page and the code disagree, the code is right and this page is out of date.USPS is a trademark of its owner; this module talks to its public API and implies no endorsement. See trademarks.

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.

Chat on WhatsApp