Aufspaltung des Zahlungs-POC: Architektur- und Design-Entscheidungen
Auf dieser Seite werden die architektonischen Optionen hinter dem aufgeteilten Zahlungsnachweis des Konzepts erläutert. Lesen Sie es, bevor Sie die Build-Eingabeaufforderungen in dieser Reihe verwenden, damit Sie verstehen, wie jede Komponente strukturiert ist und wie Sie die Muster in Ihrem eigenen Projekt anpassen können.
Das Grundprinzip
Bei dem Machbarkeitsnachweis geht es nicht um die eleganteste Split-Zahlungsimplementierung. Es geht darum zu zeigen wie man ohne eine Big-Bang-Umschreibung mit der Umstellung der Commerce-Logik auf App Builder.
Die Regel, die durchgängig angewendet wird, lautet:
Wenn etwas synchron im Commerce-Anfragezyklus laufen muss oder Commerce-interne APIs aufrufen muss, die keine saubere externe Oberfläche haben, bleibt es in PHP. Alles andere wandert nach App Builder.
Was lebt in Commerce (PHP) und warum
1. Kreditantrag speichern: PlaceOrderPlugin
Store-Guthaben wird mit Magento\CustomerBalance\Api\BalanceManagementInterface::apply() auf den Warenkorb angewendet. Diese Methode funktioniert nur für einen aktiven Warenkorb. Der Warenkorb wird zum Zeitpunkt der Bestellung inaktiv. App Builder erhält das E/A Ereignis (nachdem die Bestellung aufgegeben wurde. Daher ist es nicht möglich, eine Gutschrift von App Builder zu beantragen.
Die Lektion Alles, was den Warenkorbstatus vor der Bestellplatzierung ändern muss, muss in Commerce ausgeführt werden. Es gibt keine Problemumgehung.
2. Synchroner Schwellenwertwächter: CheckoutPlugin
Die Prüfung des Bestellschwellenwerts von 100 USD muss den Kunden bei der Zahlungsstufe blockieren, bevor er Place Order auswählt. Die Antwort muss im Commerce-Anfragezyklus synchron sein. App Builder ist ereignisgesteuert und asynchron, sodass in diesem Moment kein sofortiger Fehler zurückgegeben werden kann.
App Builder auch validiert den Schwellenwert (als Audit), aber das Kundenerlebnis hängt davon ab, dass die Commerce-Prüfung zuerst ausgeführt wird.
3. Benutzerdefinierte REST-Endpunkte: webapi.xml und SplitPaymentManagement
The following endpoints must:
- Invoke
SplitInvoiceService(invoices that use the Commerce internal invoice service) - Invoke
ShipOrder::execute()(Commerce’s internal shipment service) - Update order state and status with Commerce’s order state machine
/V1/split-payment/orders/:id/cash-received und /V1/split-payment/orders/:id/cash-decline
There is no clean public REST layer for that behavior, so Commerce exposes the endpoints. App Builder calls them.
4. Split amounts on quote and order: observers and plugins
Commerce needs the split amounts (split_store_credit_amount, split_cash_amount, split_cash_status) on the order, both for the REST responses App Builder reads and for the Admin order view. The amounts are attached with extension attributes and are copied from the quote to the order in an observer on sales_model_service_quote_submit_before.
What lives in App Builder and why
1. Event-driven order processing: payment-orchestrator
After sales_order_place_before fires, App Builder receives the event. It re-validates the threshold (as an audit), records a cash pending comment on the order, and updates order status. None of that requires new PHP, only REST back into Commerce.
2. Cash acceptance: payment-accept
When an ERP (or an operator in the dashboard) confirms cash was received, payment-accept calls POST /V1/split-payment/orders/:id/cash-received. Invoice, shipment, and order status are handled in Commerce. App Builder is the trigger.
3. Cash decline: payment-decline
payment-decline calls POST /V1/split-payment/orders/:id/cash-decline and Commerce cancels the order. Same pattern as cash acceptance.
4. Operator dashboard: demo-dashboard
A self-contained HTML dashboard served from an App Builder web action. It fetches orders that are waiting on cash from Commerce REST and provides Accept / Decline actions that call the App Builder actions above. Commerce Admin ist nicht erforderlich.
Der Schwellenwert: zweimal absichtlich erzwungen
Customer at checkout
|
v
[Commerce: CheckoutPlugin] <- Synchronous, blocks immediately, user sees error
|
| (if somehow bypassed: direct API call, and so on)
v
[Order placed] -> I/O Event -> [App Builder: payment-orchestrator]
|
v
[evaluateThreshold()] <- Async audit, records failure comment
Commerce steuert den für Benutzende gerichteten Schutz; App Builder steuert die Prüfung nach der Platzierung. Das ist Absicht.
Der Store-Abspann: Warum es in PHP bleibt
What you might think would work (it does not):
Order placed -> I/O Event -> App Builder -> PUT /V1/carts/:id/store-credit
(Fails: cart is inactive after place order)
What actually works:
AroundPlaceOrder plugin
-> BalanceManagementInterface::apply($cartId, $amount) <- cart is still active
-> place order
-> order placed
-> I/O event: App Builder (store credit is already applied)
Die store-credit.js Datei im Orchestrator dokumentiert dies. Es ist ein No-op-Stub mit Kommentaren, die erklären, warum es nicht verwendet wird.
Erweiterungsattribute: der Kleber
Aufspaltungsbeträge bewegen sich durch das System bei Erweiterungsattributen:
Checkout JavaScript (Knockout)
| POST /V1/split-payment/set
v
SplitPaymentSession (PHP session)
| AroundPlaceOrder reads the session
v
CartInterface extension attributes
| `sales_model_service_quote_submit_before` observer
v
OrderInterface extension attributes -> `sales_order` flat columns
| I/O event payload includes these fields
v
App Builder `payment-orchestrator` reads the split amounts
Datenmodell
sales_orderflache Spalten, die dieses Modul hinzufügt
split_store_credit_amountsplit_cash_amountsplit_cash_statuspending, received oder declinedsplit_sc_invoice_idsplit_cash_invoice_idErweiterungsattribute (in CartInterface, OrderInterface und OrderPaymentInterface)
split_store_credit_amount(float)split_cash_amount(float)split_cash_status(Zeichenfolge)
Payload-Felder des I/O-Ereignisses
observer.sales_order_place_before wird in io_events.xml konfiguriert, um Folgendes in das Ereignis einzuschließen:
entity_id, quote_id, increment_id, subtotal,
split_store_credit_amount, split_cash_amount, split_cash_status
App Builder verwendet entity_id als Auftrags-ID und split_store_credit_amount und split_cash_amount für die Schwellenwertvalidierung.
Die fünf Randfälle des Konzeptnachweises umfassen
1. CapCustomerBalanceCollectPlugin
Der native Customer balance-Gesamt-Collector von Commerce kann zu viel anwenden (er kann den vollständigen verfügbaren Saldo sehen, nicht den sitzungsdeklarierten Aufspaltungsbetrag). Dieses Plug-in begrenzt den Betrag auf den in der Sitzung deklarierten Wert.
2. FixSplitPaymentGrandTotalPlugin
Nachdem das Store-Guthaben angewendet wurde, kann der Grand Total auf den bargeldlosen Betrag fallen. Die Checkout-JavaScript muss die Bestellsumme für die Aufspaltungsvalidierung () diese Änderung berechnen. Das Plug-in wird nach der Gesamterfassung ausgeführt und korrigiert die Anzeige, während der JavaScript grand_total nicht vertraut und den Wert aus Zwischensummensegmenten rekonstruiert.
3. FixInvoiceCustomerBalanceAfterTotalsPlugin
Wenn die Rechnungssummen zurückgezogen werden, kann die Gutschrift des Geschäfts zweimal vorgenommen werden. Dieses Plug-in korrigiert customer_balance_amount auf Rechnungen.
4. SplitPaymentZeroTotalPlugin
Nachdem die Gutschrift für den Store angewendet wurde, kann die Grand Total für den Warenkorb $0 sein (vollständige Gutschrift für den Store). Die Zero subtotal checkout von Commerce kann in diesem Fall Code blockieren. Dieses Plug-in ermöglicht COD, wenn der Barbetrag der Sitzung größer als 0 ist.
5. Erinnerung vor BalanceManagementInterface::apply() zitieren
apply() vergleicht den Betrag mit dem aktuellen Grand Total. Wenn die Summe bereits nur der Cash-Teil ist, kann apply() fehlschlagen oder die Obergrenze einschränken. PlaceOrderPlugin setzt die Gesamtreparatur vorübergehend aus, während der Saldo angewendet wird, mithilfe eines Sitzungs-Flags (beginBalanceApply / endBalanceApply).
Gerelateerde gesplitste betalingen POC-middelen
- Een POC voor gesplitste betalingen maken: App Builder- en AI-tools
- Een gesplitste betalingsconcepttest maken: volledige demo voor App Builder
- Betalingsconcepttest splitsen: beslissingen over architectuur en ontwerp
- Betalingsconcepttest splitsen: voorwaarden en omgeving instellen
- Gesplitste betalingsconcepttest: referentie omgevingsvariabelen
- POC van gesplitste betaling: Commerce module AI-prompt
- POC van gesplitste betaling: App Builder Orchestrator AI prompt
- POC gesplitst betaling: Experience Cloud UI-extensie AI-prompt
- Gesplitste betalingsconcepttest: test- en verificatiegids
- Gesplitste betalingsconcepttest: volgende stappen na conceptbewijs
- POC voor gesplitste betaling: zelfstudie snel referentie voor auteurs