Skip to content
pcreative Commerce

Advanced selling: bundles, quantity pricing and personalisation

Three ways of selling that go beyond "one product, one price": a bundle made of other products, a price that drops with quantity, and a product the customer…

Three ways of selling that go beyond "one product, one price": a bundle made of other products, a price that drops with quantity, and a product the customer personalises (an engraving, a photo, gift wrapping). All three are set up on the product, in Products → the product, and the server works out the price: what the store shows is not trusted.

Of the factory themes, only base shows them in the store: the bundle's contents and its choices, the table of tiers, and the personalisation form (with file upload). The mascotas, cinematografico and dulce-obrador themes do not show any of the three yet.

Bundles

A bundle is a variant that contains other variants: "coffee maker + 2 bags of coffee". It has no stock of its own: it comes from the stock of its components, and they are the ones discounted when it is sold. How many bundles are available is what the scarcest component allows.

Products → the product → Variants → edit a variant → Bundle → Turn into a bundle.

  • Add a component from this product lists the product's other variants. To add variants from other products, paste their identifier (variant_…) into the box below and press Enter.
  • Each component has a quantity (from 1 to 999). Up to 30 components.
  • Bundle price:
    • Add up the components, with a Discount on the sum (%). The price is written on the variant when you save, and is recalculated from the components' prices when someone adds it to the cart.
    • The one I set on the variant: a fixed price, the one in the variant's price field.
  • Remove turns it back into a standalone product.

The bundle's weight is the sum of its components', so shipping by weight is right without doing anything.

What it does not allow:

  • A bundle inside another bundle, or a bundle that contains itself.
  • In the panel, Turn into a bundle is disabled if the product has no other variant, even though you could paste variants from other products.

When it is sold, the bundle's price is split among its components in proportion to what each is worth, and that split is stored on the order line.

Bundles with choices ("pick 3 of these 6")

A bundle can also have groups of choices: a title, a list of variants to choose from, and a minimum and maximum (up to 30). The customer picks in the store, and if they pick too few or too many, the cart refuses it with the code PACK_INCOMPLETO. With the price as Add up the components, what the customer picked is what is added up. Two identical bundles with different choices are separate lines in the cart.

🔴 Groups are not in the panel. They are set only through the API (POST /gestion/productos/<id>/variantes/<variant>/pack with grupos). And saving the bundle from the panel deletes its groups, because the panel only sends the fixed components.

🔴 If a bundle has only groups and no fixed component, the stock of what was picked is checked when it is added to the cart, but is not reserved when the order is placed.

Quantity pricing

The more the customer takes, the cheaper each unit. The tier price applies to every unit, not only the ones past the threshold: at "from 10 units, 15 % off", 12 units are 12 units at the discounted price.

Products → the product → Variants → Quantity pricing → Set quantity pricing.

  • Units count: Per variant (10 red and 10 blue are two sets of 10) or Counting every variant (they are 20).
  • Each tier means: A discount in %, A discount in a fixed amount, or The price per unit directly.
  • If the product is on sale: The lowest price wins (the tier is calculated on the regular price, and if it is not lower than the sale price, the sale price stays) or The tier applies on top of the sale price.
  • Add tier: From how many units, and its value. Up to 10 tiers, from 2 units, and each must improve on the previous one. A fixed-price tier must be below the price of every variant.
  • Minimum per purchase, Maximum per purchase and Sold in multiples of N. The tiers must respect them.

If a threshold makes buying one more unit cheaper in total, the panel warns you ("Buying more is cheaper in total") so you can tell the customer on the product page.

When the quantity is checked:

  • The maximum is checked every time the cart changes.
  • The minimum and the multiple too, except with Counting every variant: then they are checked when paying, so the customer can build the quantity up variant by variant.

The API answers with a code (MINIMO_NO_ALCANZADO, MAXIMO_SUPERADO, MULTIPLO_INCORRECTO) and the limit, and the message comes in the customer's language.

A tier is not a promotion: it changes the line's unit price. Coupons, points and taxes are then calculated on that price. While a tier applies, the line does not show a crossed-out price; it carries the tier and the regular unit price instead.

Personalisation

What the customer types or picks without it being a variant: an engraved name, a photo, a delivery date, gift wrapping.

Products → the product → Personalisation → Add field. Up to 20 fields per product.

TypeFor
Short text / Long textA name, a dedication. With Maximum characters and What is accepted: Anything, Letters only, Numbers only, Letters and numbers, An email.
NumberA shirt number, a numeric size.
List of optionsFinish, typeface. Each option can have its own surcharge.
CheckboxGift wrap.
DateDelivery day or a date to engrave.
FileA photo or a logo: JPEG, PNG, WebP, GIF, AVIF or PDF, up to 15 MB.

Each field has What the customer sees, a Help text, an Internal name, Required, and optionally Only if another field equals (it only appears if another field has a given value; one level, no chains).

Surcharge: No surcharge, Fixed per unit, A % of the price, or Per character (text only, with a number of Free characters). The server calculates it, adds it to the unit price and stores on the order exactly what was shown.

Two identical products with different personalisation are separate lines in the cart.

"Makes the product custom-made"

On by default in every new field. It marks the line as custom-made, and where the law allows it, custom-made products are excluded from the right of withdrawal. It depends on the order's shipping country: in the EU, the United Kingdom and Turkey it is on by default; in Brazil and Mexico it is off unless the store turns it on; elsewhere it does not apply. The switch is Settings → Billing → Returns and digital content → Custom-made products cannot be returned.

Picking a colour or gift wrapping does not make a product custom-made: untick it on those fields.

Files the customer uploads

The file is checked to really be an image or a PDF (by its content, not its name), stored outside the website, in the backend's privado/personalizacion folder, and can only be downloaded with a signed link valid for 10 minutes. It expires 2 days after being uploaded if it does not end up in an order, and PCC_DIAS_FICHEROS days (90 by default) after the order.

🔴 Nothing deletes expired files yet. The expiry date is recorded, but the cleanup task is not scheduled.

Not in the panel yet

  • Minimum length of a text, minimum and maximum of a number, whether decimals are allowed, the window of allowed dates, which file types a field accepts, and limiting a field or an option to certain variants: the engine supports them, but they are set only through the API (POST /gestion/productos/<id>/personalizacion).

Seeing it on the order

🔴 The panel's order detail shows neither the personalisation nor the bundle's contents, and neither does the management API. They are stored on each order line (order_line_item.metadata, keys pcc_personalizacion and pcc_pack), and today that is the only place to read them. The customer's files are in the privado/personalizacion folder, and the panel has no link to download them.

See also