Aufspaltung des Zahlungs-POC: Commerce-Modul-KI-Eingabeaufforderung

Verwenden Sie diese Seite, um die vollständige Eingabeaufforderung zu kopieren, die das Client_SplitPayment Modul „In-Process“ generiert: REST, Sitzungsbehandlung, Checkout und Admin für den Konzeptnachweis für aufgeteilte Zahlungen. Der Benutzer-Workflow verbleibt in App Builder.

So verwenden Sie diese Eingabeaufforderung

Kopieren Sie alles von PROMPT START bis Ende der Eingabeaufforderung nach Cursor (mit Claude) oder direkt nach Claude. Führen Sie sie aus dem Stammverzeichnis Ihres Commerce-Projekts oder aus einem Verzeichnis aus, in dem die API Dateien erstellen kann.

Vor der Ausführung anpassen

  • Ersetzen Sie Client durch den tatsächlichen Anbieternamen.
  • Ändern Sie SplitPayment, wenn Sie einen anderen Modulnamen verwenden möchten.
  • Wenn die Site ein benutzerdefiniertes Design verwendet, müssen die Layout-XML- und RequireJS-Pfade möglicherweise geändert werden.
  • Wenn Ihre Cash on delivery einen anderen Code als cashondelivery verwendet, aktualisieren Sie payment-method-helper.js.

Die Eingabeaufforderung

PROMPT START

Sie generieren ein vollständiges, produktionsfähiges Adobe Commerce 2.4.5+ In-Process-Modul für eine Split-Payment-Funktion. Dieses Modul ist der dünne PHP-Adapter, der die richtige REST-Oberfläche bereitstellt und die richtigen Daten zum richtigen Zeitpunkt im Commerce-Lebenszyklus anbringt. Die gesamte Workflow-Logik des Benutzers lebt in Adobe App Builder (nicht in diesem Modul).

Modulidentität:

  • Anbieter: Client
  • Modul: SplitPayment
  • Vollständiger Name: Client_SplitPayment
  • Namespace: Client\SplitPayment
  • Speicherort: app/code/Client/SplitPayment/
  • Abhängigkeiten: Magento_Checkout, Magento_CustomerBalance, Magento_Sales, Magento_Quote, Magento_WebApi, Magento_AdobeCommerceEventsClient

Generate every file listed in the file structure below. Do not omit any file. Use declare(strict_types=1) in all PHP files.

Zu erzeugende Dateistruktur

app/code/Client/SplitPayment/
├── registration.php
├── composer.json
├── Api/
│   ├── Data/SplitPaymentInterface.php
│   └── SplitPaymentManagementInterface.php
├── Block/
│   └── Order/SplitPaymentInfo.php
├── Controller/
│   └── Checkout/StoreCreditBalance.php
├── etc/
│   ├── acl.xml
│   ├── config.xml
│   ├── db_schema.xml
│   ├── db_schema_whitelist.json
│   ├── di.xml
│   ├── events.xml
│   ├── extension_attributes.xml
│   ├── io_events.xml
│   ├── module.xml
│   ├── webapi.xml
│   └── frontend/
│       └── routes.xml
├── Model/
│   ├── SplitPaymentData.php
│   ├── SplitPaymentManagement.php
│   ├── Service/
│   │   └── SplitInvoiceService.php
│   └── Session/
│       └── SplitPaymentSession.php
├── Observer/
│   ├── AutoInvoiceStoreCreditOnOrderPlace.php
│   └── CopySplitPaymentToOrder.php
├── Plugin/
│   ├── CheckoutPlugin.php
│   ├── OrderRepositoryPlugin.php
│   ├── PlaceOrderPlugin.php
│   ├── Adminhtml/
│   │   └── OrderPaymentPlugin.php
│   ├── Checkout/
│   │   └── LayoutProcessorPlugin.php
│   ├── CustomerBalance/
│   │   └── CapCustomerBalanceCollectPlugin.php
│   ├── Payment/
│   │   ├── Block/
│   │   │   └── AdminSplitPaymentTitlePlugin.php
│   │   └── Checks/
│   │       └── SplitPaymentZeroTotalPlugin.php
│   ├── Quote/
│   │   └── FixSplitPaymentGrandTotalPlugin.php
│   └── Sales/
│       └── FixInvoiceCustomerBalanceAfterTotalsPlugin.php
├── Setup/
│   └── Patch/
│       └── Data/
│           └── AddSplitPaymentOrderAttribute.php
└── view/
    └── frontend/
        ├── requirejs-config.js
        ├── layout/
        │   └── sales_order_view.xml
        ├── templates/
        │   └── order/
        │       └── split-payment-info.phtml
        └── web/
            ├── js/
            │   ├── model/
            │   │   └── payment-method-helper.js
            │   └── view/
            │       └── payment/
            │           ├── cashondelivery-method.js
            │           └── split-payment.js
            └── template/
                └── payment/
                    ├── cashondelivery.html
                    └── split-payment.html

Behavioral Specifications

1. Database Schema (etc/db_schema.xml)

Add these columns to sales_order (resource: sales):

Spalte
Typ
Nullable
Comment
split_store_credit_amount
decimal(12,4)
yes
Store credit portion
split_cash_amount
decimal(12,4)
yes
Cash portion due
split_cash_status
varchar(32)
yes
pending / received / declined
split_sc_invoice_id
int unsigned
yes
Store credit invoice entity ID
split_cash_invoice_id
int unsigned
yes
Cash invoice entity ID

Generieren Sie auch die db_schema_whitelist.json für diese Spalten.

​2. Erweiterungsattribute (etc/extension_attributes.xml)

Fügen Sie split_store_credit_amount (float), split_cash_amount (float), split_cash_status (string) zu hinzu:

  • Magento\Quote\Api\Data\CartInterface
  • Magento\Sales\Api\Data\OrderInterface
  • Magento\Sales\Api\Data\OrderPaymentInterface

​3. REST-Endpunkte (etc/webapi.xml)

POST /V1/split-payment/set              → anonymous (session-scoped)
POST /V1/split-payment/orders/:orderId/cash-received  → Magento_Sales::actions
POST /V1/split-payment/orders/:orderId/cash-decline   → Magento_Sales::cancel

Alle drei sind Client\SplitPayment\Api\SplitPaymentManagementInterface zugeordnet.

​4. I/O-Ereignisse (etc/io_events.xml)

observer.sales_order_place_before abonnieren und Felder einschließen:
entity_id, quote_id, increment_id, subtotal, split_store_credit_amount, split_cash_amount, split_cash_status

​5. SplitPaymentSession — Sitzungs-Wrapper

Speichert deklarierte aufgeteilte Beträge in der Kassensitzung. Muss Folgendes offenlegen:

  • setAmounts(float $storeCredit, float $cash): void
  • getAmounts(): array — gibt ['store_credit' => float, 'cash' => float] zurück
  • clear(): void
  • beginBalanceApply(): void - Legt eine Markierung fest, die das Plug-in „Grand Total Fix“ während des Antrags auf Gutschrift speichern unterdrückt
  • endBalanceApply(): void
  • isBalanceApplyInProgress(): bool

​6. SplitPaymentManagement — REST-Controller

setSplitPayment(float $storeCreditAmount, float $cashAmount, ?string $cartId = null): bool

  • Validiert den Warenkorb, der zur aktuellen Sitzung gehört (durch Vergleich numerischer und maskierter Anführungszeichen-IDs)
  • Speichert Beträge in SplitPaymentSession
  • Gibt bei Erfolg true zurück; gibt bei Fehlschlag LocalizedException mit allgemeiner Meldung aus.

markCashReceived(int $orderId): bool

  • Lädt Reihenfolge nach entity_id
  • Validiert split_cash_status === 'pending'
  • Setzt Status auf received, Status auf processing
  • Fügt einen Verlaufskommentar hinzu: "Cash payment of $X.XX received."
  • Aufrufe SplitInvoiceService::createCashPortionInvoice($orderId)
  • Fügt einen Kommentar mit der Inkrement-ID der Kassenrechnung hinzu
  • Anrufe createShipmentIfPossible($orderId) - Erstellt eine Lieferung mit ShipOrder::execute(), wenn versandfähige Artikel vorhanden sind
  • Gibt true zurück; gibt bei einem Fehler eine generische LocalizedException aus.

markCashDeclined(int $orderId): bool

  • Ladereihenfolge
  • Validiert split_cash_status === 'pending'
  • Validiert $order->canCancel()
  • Setzt den Status auf declined, fügt Kommentar hinzu: "Cash payment declined (simulated fraud check)."
  • Speichert die Bestellung
  • Aufrufe OrderManagement::cancel($orderId)
  • Gibt true zurück; löst bei einem Fehler eine generische LocalizedException aus

​7. PlaceOrderPlugin — aroundPlaceOrder auf QuoteManagement

Dies ist das wichtigste Plug-in. Ausführungen aroundPlaceOrder:

  1. Angebot laden; falls nicht aktiv, sofort $proceed() aufrufen
  2. SplitPaymentSession::getAmounts() lesen
  3. Wenn das Angebot customer_balance_amount_used > 0 wird, rufen Sie BalanceManagementInterface::remove($cartId) auf (LocalizedException behandeln — als allgemeine Nachricht protokollieren und erneut auslösen)
  4. recollectQuoteForBalanceOperation() aufrufen — lädt Angebot, ruft collectTotals() auf, speichert (innerhalb von beginBalanceApply() / endBalanceApply(), um das Plug-in für die Gesamtreparatur zu unterdrücken)
  5. Falls $storeCredit > 0, BalanceManagementInterface::apply($cartId, $storeCredit) aufrufen (Fehler beheben)
  6. Angebot neu laden; Erweiterungsattribute festlegen: split_store_credit_amount, split_cash_amount, split_cash_status = 'pending'
  7. payment->additional_information['client_split_payment'] als ['store_credit' => x, 'cash' => y] speichern
  8. Zitat speichern
  9. $proceed(), ID der Erfassungsreihenfolge
  10. SplitPaymentSession::clear()
  11. Kennung der Rücksendung

​8. CopySplitPaymentToOrder — Beobachter auf sales_model_service_quote_submit_before

Liest aufgeteilte Beträge aus Sitzungs- → Zahlungs-Zusatzinformationen → Angebotserweiterungsattributen (in dieser Prioritätsreihenfolge). Schreibt split_store_credit_amount, split_cash_amount, split_cash_status = 'pending' in das Bestellobjekt.

​9. AutoInvoiceStoreCreditOnOrderPlace — Beobachter auf sales_order_place_after

Wenn der Auftrag nach der Auftragserteilung über einen Store-Guthabenbetrag (split_store_credit_amount > 0) verfügt, rufen Sie SplitInvoiceService::createStoreCreditPortionInvoice($orderId) an, um den Store-Guthabenanteil sofort zu fakturieren.

10. SplitInvoiceService

createStoreCreditPortionInvoice(int $orderId): ?int
Erstellt eine Rechnung nur für den Gutschriftanteil des Geschäfts. Setzt customer_balance_amount auf der Rechnung auf den Gutschriftsbetrag. Registriert und speichert die Rechnung. Gibt bei einem Fehler die Rechnungsentitäts-ID oder null aus (Protokoll; nicht erneut auslösen).

createCashPortionInvoice(int $orderId): ?int
Erstellt eine Rechnung für den Baranteil (die verbleibenden Auftragspositionen/Beträge, die nicht von der SC-Rechnung abgedeckt sind). Registriert und speichert. Gibt bei einem Fehler die Entitäts-ID oder null zurück.

​11. CheckoutPluginPaymentInformationManagement

Plug-in auf Magento\Checkout\Model\PaymentInformationManagement::savePaymentInformationAndPlaceOrder. Bevor Sie fortfahren:

  • Laden des Angebots aus der Checkout-Sitzung
  • Abrufen des konfigurierten Schwellenwerts: Magento\Framework\App\Config\ScopeConfigInterface::getValue('split_payment/general/threshold'), 100
  • Wenn $quote->getGrandTotal() > $threshold, werfen Sie LocalizedException('Payment could not be processed. Please try again or contact support.')

​12. CapCustomerBalanceCollectPlugin — auf Customerbalance Gesamtbetrag

Nach der Ausführung des nativen Sammelvorgangs für den Kundensaldo ist die Obergrenze auf customer_balance_amount_used zu SplitPaymentSession::getAmounts()['store_credit']. Dadurch wird verhindert, dass Commerce den gesamten Kundensaldo überzieht, wenn der Kunde einen kleineren Anteil des Filialguthabens angegeben hat.

​13. FixSplitPaymentGrandTotalPluginQuote\Address\Total\Grand

Nach der Gesamterhebung der Gesamtsumme: Wenn eine Aufspaltungszahlungssitzung vorhanden ist und isBalanceApplyInProgress() „false“ ist, setzen Sie die Gesamtsumme des Angebots auf den Barbetrag der Sitzung. Dadurch wird in der Benutzeroberfläche an der Kasse nur angezeigt, was in bar fällig ist.

​14. FixInvoiceCustomerBalanceAfterTotalsPluginSales\Model\Order\Invoice

Wenn die zugehörige Bestellung der Rechnung nach dem Einzug der Rechnungssummen einen split_sc_invoice_id aufweist, korrigieren Sie die customer_balance_amount auf der Rechnung, um eine doppelte Zuordnung der Warenkorbgutschrift zu verhindern.

​15. SplitPaymentZeroTotalPluginPayment\Model\Checks\ZeroTotal

Nachnahme bei SplitPaymentSession::getAmounts()['cash'] > 0 zulassen, auch wenn die Gesamtsumme des Angebots 0 USD beträgt (da die gesamte Bestellung durch eine Gutschrift im Geschäft abgedeckt ist).

​16. LayoutProcessorPluginCheckout\Block\Checkout\LayoutProcessor

Nachdem das Layout verarbeitet wurde:

  • Fügen Sie die Client_SplitPayment/js/view/payment/split-payment Komponente in die additional untergeordneten Elemente der Komponente cashondelivery Zahlungsmethode unter components.checkout.children.steps.children.billing-step.children.payment.children.renders.children.offline-payments.children.cashondelivery.children.additional ein.
  • Entfernen Sie die native UI-Komponente „Store-Guthaben“ (customerBalance, useStoreCredit) aus dem Zahlungsschritt - die Split-Zahlungskomponente steuert die Anzeige/Anwendung der Store-Guthaben

​17. OrderRepositoryPluginOrderRepositoryInterface

Hydrieren Sie nach dem get() und getList() die Erweiterungsattribute der Bestellung aus den flachen sales_order (split_store_credit_amount, split_cash_amount, split_cash_status).

​18. AdminSplitPaymentTitlePluginPayment\Block\Info

Wenn nach getTitle() Rückgabe die Zahlungsmethode cashondelivery ist und die Bestellung eine aufgeteilte Zahlung aufweist, hängen Sie " (Split: Cash $X.XX + Store Credit $Y.YY)" an den Titel an.

​19. OrderPaymentPluginSales\Block\Adminhtml\Order\Payment

Hängen Sie in _beforeToHtml oder über „afterToHtml“ die aufgeteilten Zahlungsdetails (Barbetrag, Kreditbetrag speichern, Status) an den Zahlungsblock “HTML” in der Commerce Admin-Auftragsansicht an.

​20. Storefront Store-Guthabencontroller

Controller/Checkout/StoreCreditBalance.php — Strecke: GET /splitpayment/checkout/storecreditbalance

Gibt JSON zurück: {"balance": float, "logged_in": bool}. Wenn der Kunde nicht angemeldet ist, gibt {"balance": 0, "logged_in": false} zurück. Liest den Saldo aus Magento\CustomerBalance\Model\Balance.

Registrieren Sie die Frontend-Route in etc/frontend/routes.xml bei frontName="splitpayment".

​21. Checkout-KnockoutJS-Komponente — split-payment.js

Eine uiComponent, die:

  • Ermittelt, wann die cashondelivery Zahlungsmethode ausgewählt ist (quote.paymentMethod.subscribe)
  • Lädt den Speicherguthaben-Saldo des Kunden über GET /splitpayment/checkout/storecreditbalance
  • Füllen Sie das Feld Barbetrag mit der vollständigen Bestellsumme vorab aus (berechnet aus total_segments ohne grand_total und customerbalance - verwendet grand_total nie direkt, da dies auf den Barrest gesetzt werden kann).
  • Wenn der Kunde die Eingabe des Barbetrags ändert: Berechnet den erforderlichen Warenkredit = Bestellsumme − Bargeld; validiert; Beiträge zu POST /V1/split-payment/set
  • Zeigt Validierungsnachrichten für: Bargeld > Bestellsumme, unzureichende Speichergutschrift, nicht angemeldet
  • Zeigt eine Erfolgsmeldung an, wenn eine gültige Aufspaltung eingegeben wird: "The remaining $X.XX will automatically be applied from your store credit."
  • Wird zurückgesetzt, wenn eine andere Zahlungsmethode ausgewählt wird (veröffentlicht {storeCreditAmount: 0, cashAmount: 0}, um die Sitzung zu löschen)

22. cashondelivery-method.js

Erweitert Magento_OfflinePayments/js/view/payment/offline-payments. Verwendet payment-method-helper.js zur Erkennung des Bargeldmethodencodes. Registers split-payment component in its additional region.

23. payment-method-helper.js

Utility returning getCashMethodCode() — checks window.checkoutConfig.paymentMethods for cashondelivery; falls back to checkmo if needed.

24. cashondelivery.html Template

Standard COD template but includes <!-- ko foreach: getRegion('additional') --> region so the split payment child component can render.

25. split-payment.html Template

KnockoutJS template for the split payment fields:

  • Available store credit balance display
  • Cash amount input (number, step 0.01)
  • Store credit portion display (read-only)
  • Auto-apply store credit message (shown when split is valid and store credit > 0)
  • Validation error message

26. requirejs-config.js

Maps:

  • Client_SplitPayment/js/view/payment/split-payment → the component
  • Client_SplitPayment/js/view/payment/cashondelivery-method → the COD override
  • Client_SplitPayment/js/model/payment-method-helper → the helper

27. etc/config.xml

Default system config values:

<split_payment>
  <general>
    <threshold>100</threshold>
    <enabled>1</enabled>
  </general>
</split_payment>

Critical Implementation Notes

Store credit application must use BalanceManagementInterface, not direct model manipulation. BalanceManagementInterface::apply() handles the session, validation, and cart recalculation atomically.

PlaceOrderPluginmust use aroundPlaceOrder (not beforePlaceOrder). The store credit must be applied while the cart is still active, and that must be guaranteed before $proceed() is called.

The session flag pattern for beginBalanceApply / endBalanceApply is critical. Without it, FixSplitPaymentGrandTotalPlugin runs during collectTotals() inside the balance operation and sets grand total to the cash remainder, causing BalanceManagementInterface::apply() to fail or cap the credit.

Never expose internal error details to the customer. All catch blocks that surface to REST responses must throw LocalizedException('Payment could not be processed. Please try again or contact support.').

entity_idist die numerische Datenbank-ID. REST-Aufrufe aus App Builder verwenden immer entity_id, nicht increment_id.

SplitInvoiceServicesollten Fehler erfassen und protokollieren, anstatt sie zu propagieren. Fehlgeschlagene Rechnungserstellung sollte eine bereits platzierte Bestellung nicht stornieren - protokollieren Sie den Fehler und lassen Sie ihn vom Administrator manuell bearbeiten.

Nach dem Generieren von Dateien

Führen Sie diese Befehle im Commerce-Projektstamm aus:

bin/magento module:enable Client_SplitPayment
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f
bin/magento cache:flush

Ende der Eingabeaufforderung

Gerelateerde gesplitste betalingen POC-middelen

recommendation-more-help
commerce-learn-help-home