eCommerce

Tienda en línea

MarketplaceOperacionesVersión 0.5.0AGPL-3.0-or-latermanifest

Para qué sirve ​

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.

Qué hace y qué no hace el paquete ​

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. Orders take stock off the listing at checkout, apply discount codes and tax rates on the server, and are paid by bank transfer, by card through Stripe Checkout or in a local demo mode; the payment record, the provider reference and refunds are kept with the order. 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.

Detalles del módulo ​

  • Versión: 0.5.0
  • Autor: SpaceCorps
  • Licencia: AGPL-3.0-or-later
  • Requiere núcleo: ^0.2 (el núcleo actual es 0.2.0)
  • Madurez: Beta
  • Categorías: Ventas

Modelos ​

ecommerce_category ​

A group of listings shown together in the shop

Grupo de lectura: ecommerce.user. Grupo de escritura: ecommerce.manager.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
nametextnonenoecommerce.useren claroCategory name shown in the shop
slugtextnonenoecommerce.useren claroURL part of the category, lowercase with dashes
descriptiontextnonenoecommerce.useren claroShort text about the category
sequencenumbernonenoecommerce.useren claroOrder among categories, lowest first
publishedboolnonenoecommerce.useren claroWhether the category is visible to shoppers

ecommerce_listing ​

A product as it appears in the online shop

Grupo de lectura: ecommerce.user. Grupo de escritura: ecommerce.manager.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
product_idref → productnonenoecommerce.useren claroThe product being sold online
titletextnonenoecommerce.useren claroTitle shown in the shop
slugtextnonenoecommerce.useren claroURL part of the product page, lowercase with dashes
summarytextnonenoecommerce.useren claroOne or two sentences shown on product cards
descriptionlongtextnonenoecommerce.useren claroDescription shown on the product page, in Markdown
imageimagenonenoecommerce.useren claroMain picture of the product (PNG, JPEG, WebP or GIF, up to 5 MiB; it is re-encoded and its metadata removed on upload)
image_alttextnonenoecommerce.useren claroText that describes the main picture for people who cannot see it
category_idref → ecommerce_categorynonenoecommerce.useren claroThe category the listing is shown under
pricemoneynonenoecommerce.useren claroShop price including tax (minor currency units, e.g. cents)
compare_at_pricemoneynonenoecommerce.useren claroPrevious price shown crossed out (minor currency units)
currencytextnonenoecommerce.useren claroISO 4217 currency code of the prices, for example EUR; empty means the shop currency from the instance settings
skutextnonenoecommerce.useren claroStock keeping unit shown on the product page
stock_policyselect (always_available, block_when_out, allow_backorder)nonenoecommerce.useren claroWhat happens when stock runs out: always_available, block_when_out, allow_backorder
stock_quantitynumbernonenoecommerce.useren claroUnits on hand, used with the stock policy. Every order takes its units off at checkout, and a cancelled, expired or refunded order puts them back; correct it by hand after a stock count
publishedboolnonenoecommerce.useren claroWhether the listing is visible to shoppers

ecommerce_listing_image ​

An extra picture of a listing for its gallery

Grupo de lectura: ecommerce.user. Grupo de escritura: ecommerce.manager.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
listing_idref → ecommerce_listingnonenoecommerce.useren claroThe listing the picture belongs to; it is shown only while the listing is published
imageimagenonenoecommerce.useren claroThe picture (PNG, JPEG, WebP or GIF, up to 5 MiB)
alttextnonenoecommerce.useren claroText that describes the picture for people who cannot see it
sequencenumbernonenoecommerce.useren claroOrder in the gallery, lowest first
publishedboolnonenoecommerce.useren claroWhether the picture is shown in the shop

ecommerce_listing_translation ​

A listing translated into another language

Grupo de lectura: ecommerce.user. Grupo de escritura: ecommerce.manager.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
listing_idref → ecommerce_listingnonenoecommerce.useren claroThe listing this translates
langselect (en, de, fr, pl, fi, sv, es)nonenoecommerce.useren claroLanguage of the translation: en, de, fr, pl, fi, sv or es
titletextnonenoecommerce.useren claroTranslated title
summarytextnonenoecommerce.useren claroTranslated card text
descriptionlongtextnonenoecommerce.useren claroTranslated description in Markdown
publishedboolnonenoecommerce.useren claroWhether the translation is shown; it is only reachable while its listing is published

ecommerce_shipping_method ​

A way of delivering orders with its price

Grupo de lectura: ecommerce.user. Grupo de escritura: ecommerce.manager.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
nametextnonenoecommerce.useren claroName shown at checkout, for example Standard delivery
carriertextnonenoecommerce.useren claroCarrier that delivers, for example DHL
pricemoneynonenoecommerce.useren claroDelivery price (minor currency units)
free_overmoneynonenoecommerce.useren claroOrder total above which delivery is free (minor currency units); empty means never
delivery_daysnumbernonenoecommerce.useren claroUsual number of days until delivery
activeboolnonenoecommerce.useren claroWhether shoppers can choose it

ecommerce_discount_code ​

A code a shopper enters at checkout for a reduction

Grupo de lectura: ecommerce.user. Grupo de escritura: ecommerce.manager.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
codetextnonenoecommerce.useren claroThe code shoppers type, for example SPRING10
kindselect (percent, fixed)nonenoecommerce.useren claroType of reduction: percent or fixed
valuenumbernonenoecommerce.useren claroReduction: basis points for percent (1000 is 10.00 percent), minor currency units for fixed
starts_ondatenonenoecommerce.useren claroFirst day the code works (YYYY-MM-DD)
ends_ondatenonenoecommerce.useren claroLast day the code works (YYYY-MM-DD)
max_usesnumbernonenoecommerce.useren claroHow many times the code may be used in total; empty means unlimited
used_countnumbernonenoecommerce.useren claroHow many times it has been used. The shop counts a use when the order is placed and gives it back when the order is cancelled or never paid
minimum_ordermoneynonenoecommerce.useren claroSmallest order total the code applies to (minor currency units)
per_customer_limitnumbernonenoecommerce.useren claroHow many times one customer (by email address) may use the code; empty means no limit
category_idref → ecommerce_categorynonenoecommerce.useren claroOnly listings of this category get the reduction; empty means the whole order
activeboolnonenoecommerce.useren claroWhether the code can be used

ecommerce_discount_use ​

How many times one customer has used one discount code (the customer is kept as a hash, never as an email address)

Grupo de lectura: ecommerce.manager. Grupo de escritura: ecommerce.manager.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
code_idref → ecommerce_discount_codenonenoecommerce.manageren claroThe discount code
customer_hashtextinternalsíecommerce.managerenmascaradoHash of the customer's email address, so the per-customer limit can be checked without keeping the address here
countnumbernonenoecommerce.manageren claroUses so far

ecommerce_tax_rate ​

A tax rate the shop applies to listings, computed on the server

Grupo de lectura: ecommerce.user. Grupo de escritura: ecommerce.manager.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
nametextnonenoecommerce.useren claroName shown on the order, for example VAT
rate_bpnumbernonenoecommerce.useren claroRate in basis points: 1900 is 19.00 percent
countrytextnonenoecommerce.useren claroTwo-letter country code (for example DE) of the delivery address this rate is for; empty means every country that has no rate of its own
category_idref → ecommerce_categorynonenoecommerce.useren claroOnly listings of this category; empty means every listing (and delivery)
includedboolnonenoecommerce.useren claroWhether listing prices already include this tax (the usual way in the EU). If not, the tax is added on top at checkout
activeboolnonenoecommerce.useren claroWhether the rate is applied

ecommerce_order ​

An order placed online

Grupo de lectura: ecommerce.user. Grupo de escritura: ecommerce.user.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
numbertextnonenoecommerce.useren claroOrder number shown to the shopper. Free text: packages cannot generate sequences; the public checkout makes a random one
customer_emailtextinternalsíecommerce.userenmascaradoEmail address of the shopper
customer_nametextinternalsíecommerce.userenmascaradoName of the shopper
customer_idref → partynonenoecommerce.useren claroThe matching contact, once the shopper is known
shipping_addresslongtextinternalsíecommerce.userenmascaradoDelivery address
billing_addresslongtextinternalsíecommerce.userenmascaradoBilling address when different from delivery
shipping_method_idref → ecommerce_shipping_methodnonenoecommerce.useren claroThe chosen way of delivery
discount_code_idref → ecommerce_discount_codenonenoecommerce.useren claroThe discount code used, if any
discount_codetextnonenoecommerce.useren claroThe code the shopper entered, as it is shown on the order
discount_use_idtextinternalsíecommerce.userenmascaradoWhich per-customer use counter this order counted against, so it can be given back
countrytextinternalsíecommerce.userenmascaradoTwo-letter country code of the delivery address, which decides the tax rate
tax_summarylongtextnonenoecommerce.useren claroThe tax lines of the order as JSON: name, rate in basis points, whether included in the prices, amount
stock_returnedboolnonenoecommerce.useren claroSet when the units of a cancelled, expired or refunded order were put back on the listings, so it happens once
reserved_untilnumbernonenoecommerce.useren claroUnix time until which an unpaid order holds its stock; after that it is cancelled and the stock goes back
payment_methodselect (manual, stripe, fake)nonenoecommerce.useren claroHow the shopper chose to pay: manual (bank transfer or invoice), stripe (card) or fake (demo)
placed_ondatenonenoecommerce.useren claroDay the order was placed (YYYY-MM-DD)
currencytextnonenoecommerce.useren claroISO 4217 currency code, for example EUR
subtotalmoneynonenoecommerce.useren claroSum of the lines at listing prices (minor currency units, computed by the shop at checkout)
discount_totalmoneynonenoecommerce.useren claroReduction from the discount code (minor currency units)
shipping_totalmoneynonenoecommerce.useren claroDelivery charge (minor currency units)
tax_totalmoneynonenoecommerce.useren claroAll tax on the order, both the part included in the prices and the part added on top (minor currency units)
totalmoneynonenoecommerce.useren claroAmount the shopper pays: lines, minus the discount, plus delivery, plus tax that was added on top (minor currency units)
payment_referencetextfinancialsíecommerce.userretenidoReference from the payment provider; never a card number
tracking_referencetextnonenoecommerce.useren claroCarrier tracking number
access_tokentextsecretnoecommerce.userretenidoSecret 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.useren claroFulfilment status: pending, paid, shipped, delivered, cancelled, refunded

ecommerce_order_line ​

One product line of a web order

Grupo de lectura: ecommerce.user. Grupo de escritura: ecommerce.user.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
order_idref → ecommerce_ordernonenoecommerce.useren claroThe order the line belongs to
product_idref → productnonenoecommerce.useren claroThe product ordered
listing_idref → ecommerce_listingnonenoecommerce.useren claroThe shop listing the line was ordered from
descriptiontextnonenoecommerce.useren claroProduct text as it was when ordered
quantitynumbernonenoecommerce.useren claroUnits ordered
unit_pricemoneynonenoecommerce.useren claroPrice per unit including tax (minor currency units)
subtotalmoneynonenoecommerce.useren claroLine total (minor currency units, entered not computed)
discount_amountmoneynonenoecommerce.useren claroPart of the order discount that falls on this line (minor currency units)
tax_nametextnonenoecommerce.useren claroName of the tax applied to this line
tax_rate_bpnumbernonenoecommerce.useren claroTax rate of this line in basis points
tax_amountmoneynonenoecommerce.useren claroTax on this line, included in the prices or added on top (minor currency units)

ecommerce_payment ​

A payment for a web order: which provider, its reference, the amount and what became of it. The shop never sees card data

Grupo de lectura: ecommerce.user. Grupo de escritura: ecommerce.manager.

CampoTipoClase de datosDatos personalesGrupoLos agentes venDescripción
order_idref → ecommerce_ordernonenoecommerce.useren claroThe order being paid
providerselect (manual, stripe, fake)nonenoecommerce.useren claroWho takes the payment: manual (bank transfer or invoice), stripe (Stripe Checkout) or fake (local demo)
external_idtextfinancialnoecommerce.userretenidoThe provider's reference for this payment, for example a Stripe Checkout Session id. Never a card number
checkout_urltextfinancialnoecommerce.userretenidoWhere the shopper pays, kept so the payment page can send them back to it while the payment is open
stateselect (open, succeeded, failed, expired, cancelled, refunded)nonenoecommerce.useren claroPayment status: open (waiting for the shopper), succeeded, failed, expired, cancelled, refunded
amountmoneynonenoecommerce.useren claroAmount to pay, set by the server from the order (minor currency units)
currencytextnonenoecommerce.useren claroISO 4217 currency code of the amount
refund_idtextfinancialnoecommerce.userretenidoThe provider's reference for the refund, once the payment was refunded
refunded_amountmoneynonenoecommerce.useren claroAmount returned to the shopper (minor currency units)
event_idslongtextnonenoecommerce.useren claroIds of the provider events already applied, as JSON, so a repeated notification changes nothing

Flujos de trabajo ​

ecommerce_order ​

AcciónMueveQuién puede ejecutarlaAprobación
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.managersí
ecommerce_order.refund_deliveredstate: delivered → refundedecommerce.managersí

ecommerce_payment ​

AcciónMueveQuién puede ejecutarlaAprobación
ecommerce_payment.mark_failedstate: open → failedecommerce.managerno
ecommerce_payment.cancelstate: open → cancelledecommerce.managerno

Grupos de permisos ​

Grupos que usa esta aplicación:

  • ecommerce.manager
  • ecommerce.user

Pasos con aprobación ​

Pasos que un agente solo puede proponer:

  • ecommerce_order.refund
  • ecommerce_order.refund_delivered

Qué pueden y qué no pueden hacer los agentes ​

Un agente puede leer, buscar, crear y actualizar registros de esta aplicación, y ejecutar las acciones que no requieren aprobación, dentro de los grupos de permisos de su token.

Solo puede proponer estos pasos, y una persona debe aprobarlos: ecommerce_order.refund, ecommerce_order.refund_delivered, ecommerce_category.delete, ecommerce_listing.delete, ecommerce_listing_image.delete, ecommerce_listing_translation.delete, ecommerce_shipping_method.delete, ecommerce_discount_code.delete, ecommerce_discount_use.delete, ecommerce_tax_rate.delete, ecommerce_order.delete, ecommerce_order_line.delete, ecommerce_payment.delete.

Los datos personales se enmascaran como tokens marcadores: ecommerce_discount_use.customer_hash, ecommerce_order.customer_email, ecommerce_order.customer_name, ecommerce_order.shipping_address, ecommerce_order.billing_address, ecommerce_order.discount_use_id, ecommerce_order.country.

Estos campos se retienen por completo y los agentes no los ven: ecommerce_order.payment_reference, ecommerce_order.access_token, ecommerce_payment.external_id, ecommerce_payment.checkout_url, ecommerce_payment.refund_id.

Dependencias ​

Cada dependencia indica las versiones que acepta. Las aplicaciones integradas se versionan con el núcleo, así que un requisito sobre ellas se comprueba con la versión del núcleo.

Al instalar esta aplicación desde el mercado también se instalan las dependencias que falten, en un único plan que se confirma una vez.

Instalación ​

Instálala desde la aplicación Customize (Marketplace) o desde la línea de comandos:

bash
obop modules install-from ecommerce

Requiere una base de datos y derechos de administrador.

Crea la tuya ​

La guía de módulos explica cómo se escriben aplicaciones como esta