eCommerce

Online store

MarketplaceOperationsVersion 0.2.0manifest

What it is for ​

Store the data of an online shop: listings, shipping methods, discount codes and web orders with a fulfilment flow. Refunds need a manager and an approval. A storefront or other client reads and writes this data through the API.

What the package does and does not do ​

An online shop: categories, product listings with translations, shipping methods, discount codes, web orders with lines and a fulfilment flow of pending, paid, shipped, delivered, cancelled and refunded. When the instance runs with the public site enabled, visitors browse the published listings and place orders without an account; the server prices every order from the published listing and never trusts the browser. There is no payment provider: an order starts as pending and the shop contacts the buyer. Refunds need a human approval from a manager; agents may only propose them. Customer name, email and addresses are personal data and are never public. Needs the Products package.

Models ​

ecommerce_category ​

A group of listings shown together in the shop

Read group: ecommerce.user. Write group: ecommerce.manager.

FieldKindData classPersonal dataGroupAgents seeDescription
nametextnonenoecommerce.userin clearCategory name shown in the shop
slugtextnonenoecommerce.userin clearURL part of the category, lowercase with dashes
descriptiontextnonenoecommerce.userin clearShort text about the category
sequencenumbernonenoecommerce.userin clearOrder among categories, lowest first
publishedboolnonenoecommerce.userin clearWhether the category is visible to shoppers

ecommerce_listing ​

A product as it appears in the online shop

Read group: ecommerce.user. Write group: ecommerce.manager.

FieldKindData classPersonal dataGroupAgents seeDescription
product_idref → productnonenoecommerce.userin clearThe product being sold online
titletextnonenoecommerce.userin clearTitle shown in the shop
slugtextnonenoecommerce.userin clearURL part of the product page, lowercase with dashes
summarytextnonenoecommerce.userin clearOne or two sentences shown on product cards
descriptionlongtextnonenoecommerce.userin clearDescription shown on the product page, in Markdown
category_idref → ecommerce_categorynonenoecommerce.userin clearThe category the listing is shown under
pricemoneynonenoecommerce.userin clearShop price including tax (minor currency units, e.g. cents)
compare_at_pricemoneynonenoecommerce.userin clearPrevious price shown crossed out (minor currency units)
currencytextnonenoecommerce.userin clearISO 4217 currency code of the prices, for example EUR; empty means the shop currency from the instance settings
skutextnonenoecommerce.userin clearStock keeping unit shown on the product page
stock_policyselect (always_available, block_when_out, allow_backorder)nonenoecommerce.userin clearWhat happens when stock runs out: always_available, block_when_out, allow_backorder
stock_quantitynumbernonenoecommerce.userin clearUnits on hand, used with the stock policy. Orders do not reduce it: adjust it by hand
publishedboolnonenoecommerce.userin clearWhether the listing is visible to shoppers

ecommerce_listing_translation ​

A listing translated into another language

Read group: ecommerce.user. Write group: ecommerce.manager.

FieldKindData classPersonal dataGroupAgents seeDescription
listing_idref → ecommerce_listingnonenoecommerce.userin clearThe listing this translates
langselect (en, de, fr, pl, fi, sv, es)nonenoecommerce.userin clearLanguage of the translation: en, de, fr, pl, fi, sv or es
titletextnonenoecommerce.userin clearTranslated title
summarytextnonenoecommerce.userin clearTranslated card text
descriptionlongtextnonenoecommerce.userin clearTranslated description in Markdown
publishedboolnonenoecommerce.userin clearWhether the translation is shown; it is only reachable while its listing is published

ecommerce_shipping_method ​

A way of delivering orders with its price

Read group: ecommerce.user. Write group: ecommerce.manager.

FieldKindData classPersonal dataGroupAgents seeDescription
nametextnonenoecommerce.userin clearName shown at checkout, for example Standard delivery
carriertextnonenoecommerce.userin clearCarrier that delivers, for example DHL
pricemoneynonenoecommerce.userin clearDelivery price (minor currency units)
free_overmoneynonenoecommerce.userin clearOrder total above which delivery is free (minor currency units); empty means never
delivery_daysnumbernonenoecommerce.userin clearUsual number of days until delivery
activeboolnonenoecommerce.userin clearWhether shoppers can choose it

ecommerce_discount_code ​

A code a shopper enters at checkout for a reduction

Read group: ecommerce.user. Write group: ecommerce.manager.

FieldKindData classPersonal dataGroupAgents seeDescription
codetextnonenoecommerce.userin clearThe code shoppers type, for example SPRING10
kindselect (percent, fixed)nonenoecommerce.userin clearType of reduction: percent or fixed
valuenumbernonenoecommerce.userin clearReduction: basis points for percent (1000 is 10.00 percent), minor currency units for fixed
starts_ondatenonenoecommerce.userin clearFirst day the code works (YYYY-MM-DD)
ends_ondatenonenoecommerce.userin clearLast day the code works (YYYY-MM-DD)
max_usesnumbernonenoecommerce.userin clearHow many times the code may be used in total; empty means unlimited
used_countnumbernonenoecommerce.userin clearHow many times it has been used (kept up to date by hand)
minimum_ordermoneynonenoecommerce.userin clearSmallest order total the code applies to (minor currency units)
activeboolnonenoecommerce.userin clearWhether the code can be used

ecommerce_order ​

An order placed online

Read group: ecommerce.user. Write group: ecommerce.user.

FieldKindData classPersonal dataGroupAgents seeDescription
numbertextnonenoecommerce.userin clearOrder number shown to the shopper. Free text: packages cannot generate sequences; the public checkout makes a random one
customer_emailtextinternalyesecommerce.usermaskedEmail address of the shopper
customer_nametextinternalyesecommerce.usermaskedName of the shopper
customer_idref → partynonenoecommerce.userin clearThe matching contact, once the shopper is known
shipping_addresslongtextinternalyesecommerce.usermaskedDelivery address
billing_addresslongtextinternalyesecommerce.usermaskedBilling address when different from delivery
shipping_method_idref → ecommerce_shipping_methodnonenoecommerce.userin clearThe chosen way of delivery
discount_code_idref → ecommerce_discount_codenonenoecommerce.userin clearThe discount code used, if any
placed_ondatenonenoecommerce.userin clearDay the order was placed (YYYY-MM-DD)
currencytextnonenoecommerce.userin clearISO 4217 currency code, for example EUR
subtotalmoneynonenoecommerce.userin clearSum of the lines (minor currency units, entered not computed)
discount_totalmoneynonenoecommerce.userin clearReduction from the discount code (minor currency units)
shipping_totalmoneynonenoecommerce.userin clearDelivery charge (minor currency units)
tax_totalmoneynonenoecommerce.userin clearTax included in the total (minor currency units)
totalmoneynonenoecommerce.userin clearAmount the shopper pays (minor currency units)
payment_referencetextfinancialyesecommerce.userwithheldReference from the payment provider; never a card number
tracking_referencetextnonenoecommerce.userin clearCarrier tracking number
access_tokentextsecretnoecommerce.userwithheldSecret link token that lets the shopper who placed a public order see its confirmation page. Nobody can read it back
stateselect (pending, paid, shipped, delivered, cancelled, refunded)nonenoecommerce.userin clearFulfilment status: pending, paid, shipped, delivered, cancelled, refunded

ecommerce_order_line ​

One product line of a web order

Read group: ecommerce.user. Write group: ecommerce.user.

FieldKindData classPersonal dataGroupAgents seeDescription
order_idref → ecommerce_ordernonenoecommerce.userin clearThe order the line belongs to
product_idref → productnonenoecommerce.userin clearThe product ordered
listing_idref → ecommerce_listingnonenoecommerce.userin clearThe shop listing the line was ordered from
descriptiontextnonenoecommerce.userin clearProduct text as it was when ordered
quantitynumbernonenoecommerce.userin clearUnits ordered
unit_pricemoneynonenoecommerce.userin clearPrice per unit including tax (minor currency units)
subtotalmoneynonenoecommerce.userin clearLine total (minor currency units, entered not computed)

Workflows ​

ecommerce_order ​

ActionMovesWho may run itApproval
ecommerce_order.mark_paidstate: pending → paidecommerce.userno
ecommerce_order.shipstate: paid → shippedecommerce.userno
ecommerce_order.deliverstate: shipped → deliveredecommerce.userno
ecommerce_order.cancelstate: pending → cancelledecommerce.userno
ecommerce_order.refundstate: paid → refundedecommerce.manageryes
ecommerce_order.refund_deliveredstate: delivered → refundedecommerce.manageryes

Permission groups ​

Groups used by this app:

  • ecommerce.manager
  • ecommerce.user

Approval steps ​

Steps an agent can only propose:

  • ecommerce_order.refund
  • ecommerce_order.refund_delivered

What agents can and cannot do ​

An agent can read, search, create and update records of this app, and run the actions that need no approval, within the permission groups of its token.

It can only propose these steps, and a person must approve them: ecommerce_order.refund, ecommerce_order.refund_delivered, ecommerce_category.delete, ecommerce_listing.delete, ecommerce_listing_translation.delete, ecommerce_shipping_method.delete, ecommerce_discount_code.delete, ecommerce_order.delete, ecommerce_order_line.delete.

Personal data is masked as placeholder tokens: ecommerce_order.customer_email, ecommerce_order.customer_name, ecommerce_order.shipping_address, ecommerce_order.billing_address.

These fields are withheld from agents entirely: ecommerce_order.payment_reference, ecommerce_order.access_token.

Dependencies ​

  • base
  • product

Install ​

Install it from the Customize app (Marketplace), or from the command line:

bash
obop modules install-from ecommerce

Needs a database and administrator rights.

Build your own ​

The module guide shows how apps like this one are written