# Technische Referenz für POS-Rabatte

Diese Seite dokumentiert, wie WCPOS vom Kassierer vorgenommene Preisüberschreibungen auf Positionsebene handhabt — wie sie gespeichert werden, wie sie mit WooCommerce-Gutscheinen zusammenwirken und welche Filter verfügbar sind. Die Benutzerdokumentation finden Sie unter [Warenkorb-Rabatte](/de/pos/cart/discounts.md) und [Gutscheine](/de/coupons/.md).

## Speicherung von POS-Preisüberschreibungen[​](#how-pos-price-overrides-are-stored "Direkter Link zu Speicherung von POS-Preisüberschreibungen")

Wenn ein Kassierer den Preis einer Position im POS festlegt oder ändert, werden die Stückpreise im Positionsmetafeld `_woocommerce_pos_data` als JSON gespeichert:

```
{

  "price": "16.00",

  "regular_price": "18.00",

  "tax_status": "taxable"

}
```

Bei sonstigen (benutzerdefinierten) Produkten kann dieses Metafeld zusätzlich die Felder `virtual`, `downloadable` und `categories` enthalten, die bei der Gutscheinvalidierung verwendet werden.

Dieses Metafeld ist die maßgebliche Quelle für die Stückpreise der Position. Der von WooCommerce gespeicherte Wert `subtotal` der Position wird aus `price * qty` abgeleitet (unter Berücksichtigung von Steuerberechnung und Rundung). Der gespeicherte `total`-Wert kann niedriger ausfallen, wenn Gutscheinrabatte angewendet werden. Für stückgenaue Preise sollten daher immer `_woocommerce_pos_data.price` und `regular_price` ausgelesen werden.

## Zwischensummen-Modell (v1.9.0+)[​](#subtotal-model-v190 "Direkter Link zu Zwischensummen-Modell (v1.9.0+)")

Ab v1.9.0 orientiert sich WCPOS an der nativen Angebotspreissemantik von WooCommerce:

* `line_item.subtotal = price * qty`, wobei `price` der POS-Preis ist (nach einer eventuellen Überschreibung).
* `line_item.total = subtotal - coupon_discount_for_line`.
* `order.discount_total` gibt ausschließlich **Gutscheinrabatte** wieder, nicht POS-Preisüberschreibungen.

Dies entspricht der Behandlung eines reduzierten Produkts durch WooCommerce: Der `sale_price` wird zur Zwischensumme, und `discount_total` ist für Gutscheine reserviert. Es gibt keine separate "POS-Rabatt"-Zeile in der Bestellung.

Migration von Versionen vor 1.9.0

Frühere Versionen sendeten `subtotal = regular_price * qty`, was dazu führte, dass WooCommerce `discount_total = subtotal - total` berechnete und POS-Preisüberschreibungen als Rabatt einbezog. Dies wurde geändert, da es mit der Gutscheinberechnung kollidierte: `recalculate_coupons()` verwendet `subtotal` als Basispreis, sodass Gutscheine gegen den Originalpreis berechnet wurden und fehlerhafte Gesamtbeträge ergaben.

Der bisherige serverseitige Workaround – ein `woocommerce_order_item_get_subtotal`-Filter, der während `recalculate_coupons()` aktiv war – wurde in v1.9.0 entfernt. Die vollständige Historie ist im [ADR](https://github.com/wcpos/wiki/blob/main/architecture/decisions/2026-04-08-subtotal-parity.md) dokumentiert.

## Verhalten bei Gutschein-Interaktion[​](#coupon-interaction-behaviour "Direkter Link zu Verhalten bei Gutschein-Interaktion")

Gutscheinunterstützung ist eine Funktion von [WCPOS Pro](https://wcpos.com/pro). Wenn ein Gutschein auf eine Bestellung mit POS-rabattierten Artikeln angewendet wird:

1. Der Gutschein wird auf Basis des **POS-rabattierten Preises** (der Wert in `_woocommerce_pos_data.price`) berechnet, nicht auf Basis des ursprünglichen `regular_price`.
2. Wenn ein Gutschein entfernt wird, kehrt die Position zu ihrem POS-rabattierten Preis zurück.

### Verhalten von `exclude_sale_items`[​](#exclude_sale_items-behaviour "Direkter Link zu exclude_sale_items-behaviour")

POS-rabattierte Artikel werden von WooCommerce als „im Angebot“ behandelt, wenn `_woocommerce_pos_data.price < regular_price`. Gutscheine mit aktivierter Option `exclude_sale_items` überspringen sie daher, konsistent mit der Behandlung regulärer Angebotspreise durch WooCommerce.

Wenn Sie ein anderes Verhalten benötigen, siehe den Filter `woocommerce_pos_item_is_on_sale` weiter unten.

## Verfügbare Filter[​](#available-filters "Direkter Link zu Verfügbare Filter")

### `woocommerce_pos_item_is_on_sale`[​](#woocommerce_pos_item_is_on_sale "Direkter Link zu woocommerce_pos_item_is_on_sale")

Überschreiben Sie, ob ein POS-rabattierter Artikel zum Zweck der Gutscheinvalidierung als „im Angebot“ gilt.

```
add_filter( 'woocommerce_pos_item_is_on_sale', function ( $is_on_sale, $product, $item, $pos_data ) {

    // Allow coupons with exclude_sale_items to apply to POS-discounted items

    return false;

}, 10, 4 );
```

**Parameter:**

| Parameter     | Typ                     | Beschreibung                                                           |
| ------------- | ----------------------- | ---------------------------------------------------------------------- |
| `$is_on_sale` | `bool`                  | Ob der Artikel als im Angebot gilt (Standard: `price < regular_price`) |
| `$product`    | `WC_Product`            | Das Produktobjekt                                                      |
| `$item`       | `WC_Order_Item_Product` | Die Bestellposition                                                    |
| `$pos_data`   | `array`                 | Das dekodierte `_woocommerce_pos_data`-JSON                            |

## REST-API-Endpunkt[​](#rest-api-endpoint "Direkter Link zu REST-API-Endpunkt")

Der Gutschein-REST-Endpunkt befindet sich im **kostenlosen Plugin** unter `/wp-json/wcpos/v1/coupons`, sodass beim Abfragen von Gutscheinen im POS niemals ein 404-Fehler auftritt — auch auf Websites ohne installiertes WCPOS Pro. Die benutzerseitige Gutscheinfunktion selbst erfordert jedoch Pro.

Der Controller erweitert `WC_REST_Coupons_Controller` um POS-spezifische Ergänzungen:

* UUID-Verarbeitung für Offline-First-Synchronisation
* `access_woocommerce_pos`-Berechtigung für Berechtigungsprüfungen
* Optimierter Bulk-ID-Abfragepfad, wenn `posts_per_page=-1` und `fields=id` (oder `fields=id,date_modified_gmt`) angefordert werden

## Belegdaten-Bereitstellung[​](#receipt-data-exposure "Direkter Link zu Belegdaten-Bereitstellung")

Der Belegdaten-Builder (`Receipt_Data_Builder`) stellt bereit:

* `lines[].discounts`, `lines[].discounts_incl`, `lines[].discounts_excl` — Rabattbetrag pro Position, berechnet als `subtotal - total`. Ab v1.9.0 spiegelt dies bei POS-Preisüberschreibungen **ausschließlich Gutscheinrabatte** wider, da `subtotal === total` gilt, wenn kein Gutschein angewendet wird.
* `totals.discount_total`, `totals.discount_total_incl`, `totals.discount_total_excl` — Gutscheinrabatt-Gesamtbetrag auf Bestellebene aus `WC_Order::get_discount_total()`.
* `discounts[]` — Array von Gutschein-Positionen mit `label`, `code` und `total`.

Die mit Unterstrich präfixierten Metadaten der Position (einschließlich `_woocommerce_pos_data`) werden von `lines[].meta` aus `Receipt_Data_Builder::get_item_meta_pairs()` herausgefiltert, sodass `regular_price` für Vorlagen nicht direkt verfügbar ist. Falls Sie die Differenz zwischen regulärem Preis und POS-Preis auf Belegen anzeigen möchten, fordern Sie dies über den [Support](https://wcpos.com/support) an.

## Verwandte Themen[​](#related "Direkter Link zu Verwandte Themen")

* [Warenkorb-Rabatte](/de/pos/cart/discounts.md) — Benutzerhandbuch für kassenbasierte Rabatte
* [Gutscheine](/de/coupons/.md) — Benutzerhandbuch für WooCommerce-Gutscheine im POS (Pro)
