Contents

POST [/instances/$INSTANCE]/private/products#

This is used to add a product to the inventory.

Required permission: products-write

Request:

The request must be a ProductAddDetailRequest.

Response:

204 No content:

The backend has successfully expanded the inventory.

404 Not found:

The instance, category, product group or money pot specified are unknown. Possible error code values are thus: TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN (instance unknown), TALER_EC_MERCHANT_GENERIC_PRODUCT_GROUP_UNKNOWN (product group unknown) TALER_EC_MERCHANT_GENERIC_MONEY_POT_UNKNOWN (money pot unknown), TALER_EC_MERCHANT_GENERIC_CATEGORY_UNKNOWN (category unknown, specific category is given in the details).

409 Conflict:

The backend already knows a product with this product ID, but with different details. Returned with a code of TALER_EC_MERCHANT_PRIVATE_POST_PRODUCTS_CONFLICT_PRODUCT_EXISTS.

Details:

interface ProductAddDetailRequest {

  // Product ID to use.
  product_id: string;

  // Human-readable product name.
  // Since API version **v20**.  Optional only for
  // backwards-compatibility, should be considered mandatory
  // moving forward!
  product_name?: string;

  // Human-readable product description.
  description: string;

  // Map from IETF BCP 47 language tags to localized descriptions.
  description_i18n?: { [lang_tag: string]: string };

  // Categories into which the product belongs.
  // Used in the POS-endpoint.
  // Since API version **v16**.
  categories?: Integer[];

  // Unit in which the product is measured (liters, kilograms, packages, etc.).
  unit: string;

  // Optional override to control whether fractional quantities are permitted.
  // Defaults to the policy implied by unit.
  unit_allow_fraction?: boolean;

  // Override for the fractional precision level (0-6). Only relevant if
  // unit_allow_fraction is true. Defaults come from unit.
  unit_precision_level?: Integer;

  // Preferred way to express inventory counts using "<integer>[.<fraction>]" syntax.
  // Use "-1" for unlimited stock. Required unless total_stock is provided.
  unit_total_stock?: DecimalQuantity;

  // Legacy stock counter. Deprecated, use unit_total_stock instead.
  // Still required when unit_total_stock is omitted.
  total_stock?: Integer;

  // Preferred way to express the per-unit price of the product. Supply at least one entry;
  // the first entry must match price.
  // The price given MUST include applicable taxes if price_is_net
  // is false, and MUST exclude applicable taxes if price_is_net
  // is true.
  // Zero implies that the product is not sold separately or that the price must be supplied
  // by the frontend.
  // Each entry must use a distinct currency.
  // Since API version **v25**.
  // Currency uniqueness enforced since protocol **v25**.
  unit_price?: Amount[];

  // True if the price(s) given are a net prices, false if they are
  // gross prices.
  // Since protocol **vTAXES**.
  price_is_net?: boolean;

  // Legacy price field.
  // Deprecated since **v25**;
  // when present it must match the first element of unit_price.
  price?: Amount;

  // An optional base64-encoded product image.
  image?: ImageDataUrl;

  // A list of taxes paid by the merchant for one unit of this product.
  taxes?: Tax[];

  // Identifies where the product is in stock.
  address?: Location;

  // Identifies when we expect the next restocking to happen.
  next_restock?: Timestamp;

  // Minimum age buyer must have (in years). Default is 0.
  minimum_age?: Integer;

  // Product group the product belongs to. 0 and missing both
  // means default.
  // Since **v25**.
  product_group_id?: Integer;

  // Money pot revenue on the product should be accounted in.
  // 0 and missing both mean no money pot (revenue accounted
  // in money pot of the overall order or not at all).
  // Since **v25**.
  money_pot_id?: Integer;

}

Clients SHOULD migrate to the new unit_* fields and treat total_stock and price as deprecated compatibility shims. If both the legacy and the new representation are supplied, their values must match. Omitting both unit_total_stock and total_stock (or both unit_price and price) results in a 400 Bad Request. When only price is given, the backend treats it as a one-element unit_price array.

unit_total_stock uses a fixed-point decimal string in the form INTEGER[.FRACTION] with at most six fractional digits. Scientific notation or special values such as NaN are not accepted. Supply "-1" to represent unlimited stock. See DecimalQuantity.

Fractional behaviour defaults to the value of unit. The backend disables fractions for Piece, Set, Custom, WeightUnitMg and SizeUnitMm. Other predefined units allow fractional quantities with the following default precision levels:

  • Precision 1: WeightUnitG, SizeUnitCm, SurfaceUnitMm2, VolumeUnitMm3.

  • Precision 2: WeightUnitOunce, SizeUnitInch, SurfaceUnitCm2, VolumeUnitInch3, VolumeUnitOunce, TimeUnitHour, TimeUnitMonth.

  • Precision 3: WeightUnitTon, WeightUnitKg, WeightUnitPound, SizeUnitM, SizeUnitDm, SizeUnitFoot, SurfaceUnitDm2, SurfaceUnitFoot2, VolumeUnitCm3, VolumeUnitLitre, VolumeUnitGallon, TimeUnitSecond, TimeUnitMinute, TimeUnitDay, TimeUnitWeek.

  • Precision 4: SurfaceUnitM2, SurfaceUnitInch2, TimeUnitYear.

  • Precision 5: VolumeUnitDm3, VolumeUnitFoot3.

  • Precision 6: VolumeUnitM3.

Integrations can override these defaults by explicitly setting unit_allow_fraction and/or unit_precision_level.