POC van gesplitste betaling: Commerce module AI-prompt

Op deze pagina kunt u de volledige vraag kopiëren die de module Client_SplitPayment in-process (REST, session handling, Checkout en Admin ) genereert voor de proefdruk van gesplitste betalingen. Operator-workflow blijft in App Builder.

Hoe deze herinnering te gebruiken

Kopieer alles van PROMPT START aan Eind van herinnering in Cursor (met Claude) of direct in Claude. Voer dit uit vanaf de basis van uw Commerce-project of een map waar de AI bestanden kan maken.

Aanpassen voordat u begint

  • Vervang Client door de werkelijke naam van de leverancier.
  • Wijzig SplitPayment als u een andere modulenaam wilt.
  • Als de site een aangepast thema gebruikt, moet de indeling XML en de indeling JavaScript-paden mogelijk worden gewijzigd.
  • Als uw Cash on delivery -methode een andere code gebruikt dan cashondelivery , moet u de update payment-method-helper.js uitvoeren.

De vraag

PROMPT START

U genereert een volledige, productieklaar Adobe Commerce 2.4.5+ in-process module voor een gesplitste betalingsfunctie. Deze module is de dunne PHP adapter die het juiste REST oppervlak belicht en de juiste gegevens op de juiste momenten in de Commerce levenscyclus koppelt. Alle operatorworkflowlogica woont in Adobe App Builder (niet in deze module).

identiteit van de Module:

  • Leverancier: Client
  • Module: SplitPayment
  • Volledige naam: Client_SplitPayment
  • Naamruimte: Client\SplitPayment
  • Locatie: app/code/Client/SplitPayment/
  • Afhankelijkheden: 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.

Te genereren bestandsstructuur

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):

Kolom
Type
Nullable
Opmerking
split_store_credit_amount
decimal(12,4)
ja
Store credit portion
split_cash_amount
decimal(12,4)
ja
Cash portion due
split_cash_status
varchar(32)
ja
pending / received / declined
split_sc_invoice_id
int zonder teken
ja
Store credit invoice entity ID
split_cash_invoice_id
int zonder teken
ja
Cash invoice entity ID

Genereer ook de db_schema_whitelist.json voor deze kolommen.

​2. Kenmerken van extensie (etc/extension_attributes.xml)

Voeg split_store_credit_amount (float), split_cash_amount (float), split_cash_status (string) toe aan:

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

3. REST Endpoints (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 drie de kaarten aan Client\SplitPayment\Api\SplitPaymentManagementInterface.

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

Abonneren op observer.sales_order_place_before en velden opnemen:
entity_id, quote_id, increment_id, subtotal, split_store_credit_amount, split_cash_amount, split_cash_status

​5. SplitPaymentSession — Sessiewrapper

Hiermee worden gedeclareerde gesplitste bedragen opgeslagen in de betalingssessie. Moet zichtbaar zijn:

  • setAmounts(float $storeCredit, float $cash): void
  • getAmounts(): array — retourneert ['store_credit' => float, 'cash' => float]
  • clear(): void
  • beginBalanceApply(): void — hiermee stelt u een markering in die de plug-in voor het totaalaantal oplossingen onderdrukt tijdens de toepassing voor winkelkrediet
  • endBalanceApply(): void
  • isBalanceApplyInProgress(): bool

6. SplitPaymentManagement — REST Controller

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

  • Hiermee valideert u het winkelwagentje van de huidige sessie (door numerieke en gemaskerde aanhalingstekens te vergelijken)
  • Hoeveelheden opslaan in SplitPaymentSession
  • Retourneert true bij succes; generiek bericht LocalizedException bij mislukken.

markCashReceived(int $orderId): bool

  • Laadt de volgorde met entity_id
  • Valideert split_cash_status === 'pending'
  • Stelt de status in op received , status op processing
  • Voegt een historieopmerking toe: "Cash payment of $X.XX received."
  • Roept SplitInvoiceService::createCashPortionInvoice($orderId)
  • Voegt een opmerking toe met de increment ID van de contante factuur.
  • Roept createShipmentIfPossible($orderId) — maakt een verzending met behulp van ShipOrder::execute() als er items zijn die kunnen worden verzonden
  • Retourneert true; generieke code LocalizedException voor elke fout.

markCashDeclined(int $orderId): bool

  • Volgorde wordt geladen
  • Valideert split_cash_status === 'pending'
  • Valideert $order->canCancel()
  • Stelt de status in op declined , voegt de volgende opmerking toe: "Cash payment declined (simulated fraud check)."
  • Opgeslagen volgorde
  • Roept OrderManagement::cancel($orderId)
  • Retourneert true; generieke code LocalizedException wordt gegenereerd bij een fout

​7. PlaceOrderPlugin — aroundPlaceOrder op QuoteManagement

Dit is de meest kritieke insteekmodule. Runs aroundPlaceOrder:

  1. Het aanhalingsteken laden; indien niet actief, roep $proceed() onmiddellijk aan
  2. Lezen SplitPaymentSession::getAmounts()
  3. Indien customer_balance_amount_used > 0 in het aanhalingsteken, roep dan BalanceManagementInterface::remove($cartId) (handle LocalizedException — log and rethrow as generic message)
  4. Aanroep recollectQuoteForBalanceOperation() — laadt aanhalingsteken, aanroepen collectTotals() , slaat op (binnen beginBalanceApply() / endBalanceApply() om de algemene insteekmodule voor totale reparatie te onderdrukken)
  5. Indien $storeCredit > 0 , roep BalanceManagementInterface::apply($cartId, $storeCredit) (handle failure)
  6. Aanhalingsteken opnieuw laden; extensiekenmerken instellen: split_store_credit_amount, split_cash_amount, split_cash_status = 'pending'
  7. payment->additional_information['client_split_payment'] opslaan als ['store_credit' => x, 'cash' => y]
  8. Aanhalingsteken opslaan
  9. Aanroep $proceed(), id van vastlegvolgorde
  10. Roep SplitPaymentSession::clear()
  11. ID van retourorder

​8. CopySplitPaymentToOrder — Waarnemer op sales_model_service_quote_submit_before

Leest gesplitste bedragen van session → payment additional_information → quote extensiekenmerken (in die prioritaire orde). Schrijft split_store_credit_amount , split_cash_amount , split_cash_status = 'pending' naar het orderobject.

​9. AutoInvoiceStoreCreditOnOrderPlace — Waarnemer op sales_order_place_after

Als de order na plaatsing van de order een creditbedrag van de winkel heeft (split_store_credit_amount > 0), roept u SplitInvoiceService::createStoreCreditPortionInvoice($orderId) aan om het gedeelte van het winkelkrediet onmiddellijk te factureren.

10. SplitInvoiceService

createStoreCreditPortionInvoice(int $orderId): ?int
Creates an invoice for the store credit portion only. Sets customer_balance_amount on the invoice to the store credit amount. Registers and saves the invoice. Returns the invoice entity ID or null on failure (log; do not rethrow).

createCashPortionInvoice(int $orderId): ?int
Creates an invoice for the cash portion (the remaining order items/amounts not covered by the SC invoice). Registers and saves. Returns entity ID or null on failure.

11. CheckoutPlugin — on PaymentInformationManagement

Plugin on Magento\Checkout\Model\PaymentInformationManagement::savePaymentInformationAndPlaceOrder. Before proceeding:

  • Load the quote from the checkout session
  • Get the configured threshold: Magento\Framework\App\Config\ScopeConfigInterface::getValue('split_payment/general/threshold'), default 100
  • If $quote->getGrandTotal() > $threshold, throw LocalizedException('Payment could not be processed. Please try again or contact support.')

12. CapCustomerBalanceCollectPlugin — on Customerbalance total

After the native customer balance total collect runs, cap customer_balance_amount_used to SplitPaymentSession::getAmounts()['store_credit']. This prevents Commerce from over-applying the full customer balance when the customer has declared a smaller store credit portion.

13. FixSplitPaymentGrandTotalPlugin — on Quote\Address\Total\Grand

After grand total collect: if a split payment session exists and isBalanceApplyInProgress() is false, set the quote grand total to the session cash amount. This makes the checkout UI show only what is due in cash.

14. FixInvoiceCustomerBalanceAfterTotalsPlugin — on Sales\Model\Order\Invoice

After invoice totals are collected, if the invoice’s associated order has a split_sc_invoice_id, correct the customer_balance_amount on the invoice to prevent double-application of store credit.

15. SplitPaymentZeroTotalPlugin — on Payment\Model\Checks\ZeroTotal

Allow COD payment when SplitPaymentSession::getAmounts()['cash'] > 0, even if the quote grand total is $0 (because store credit covers the entire order).

16. LayoutProcessorPlugin — on Checkout\Block\Checkout\LayoutProcessor

After the layout is processed:

  • Injecteer de component Client_SplitPayment/js/view/payment/split-payment in de additional onderliggende items van de component betaalmethode cashondelivery op components.checkout.children.steps.children.billing-step.children.payment.children.renders.children.offline-payments.children.cashondelivery.children.additional
  • Verwijder de UI-component voor native winkelkrediet (customerBalance, useStoreCredit) uit de betalingsstap — de gesplitste betalingscomponent is eigenaar van de display/toepassing van het winkelkrediet.

​17. OrderRepositoryPlugin — op OrderRepositoryInterface

Na get() en getList() kunt u de extensiekenmerken van de volgorde uitvouwen op basis van de vlakke sales_order kolommen ( split_store_credit_amount , split_cash_amount , split_cash_status ).

​18. AdminSplitPaymentTitlePlugin — op Payment\Block\Info

Als getTitle() de waarde cashondelivery heeft en de betalingsmethode een gesplitste betaling heeft, voegt u " (Split: Cash $X.XX + Store Credit $Y.YY)" toe aan de titel.

​19. OrderPaymentPlugin — op Sales\Block\Adminhtml\Order\Payment

Voeg in _beforeToHtml of via afterToHTML de gesplitste betalingsgegevens (kasbedrag, crediteringsbedrag, status) toe aan het betalingsblok HTML in de Commerce Admin-orderweergave.

20. Storefront Store Credit Balance Controller

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

Retourneert JSON: {"balance": float, "logged_in": bool}. Als de klant niet is aangemeld, wordt {"balance": 0, "logged_in": false} geretourneerd. De balans wordt gelezen uit Magento\CustomerBalance\Model\Balance .

Registreer de front-end route in etc/frontend/routes.xml met frontName="splitpayment".

​21. KnockoutJS-component uitchecken — split-payment.js

A uiComponent dat:

  • Detecteert wanneer de betalingsmethode cashondelivery is geselecteerd (quote.paymentMethod.subscribe)
  • Laadt het saldo van de winkelcreditering van de klant via GET /splitpayment/checkout/storecreditbalance
  • Vult het veld voor het contante bedrag vooraf met het volledige totaalbedrag van de bestelling (berekend vanaf total_segments exclusief grand_total en customerbalance — gebruikt grand_total nooit rechtstreeks, omdat het kan worden ingesteld op het resterende geld)
  • Terwijl de klant de invoer van het contante bedrag wijzigt: berekent de benodigde opslagkredieten = totaal bestellen - contant; valideert; posten naar POST /V1/split-payment/set
  • Toont validatieberichten voor: cash > ordertotaal, onvoldoende opslagkrediet, niet aangemeld
  • Hiermee wordt een succesbericht weergegeven wanneer een geldige splitsing wordt ingevoerd: "The remaining $X.XX will automatically be applied from your store credit."
  • Herstelt wanneer een andere betalingsmethode is geselecteerd (adverteert {storeCreditAmount: 0, cashAmount: 0} om sessie te wissen)

22. cashondelivery-method.js

Breidt Magento_OfflinePayments/js/view/payment/offline-payments uit. Gebruikt payment-method-helper.js om de code van de cash methode te ontdekken. Hiermee wordt split-payment -component geregistreerd in het additional -gebied.

23. payment-method-helper.js

Nut retourneert getCashMethodCode() — controleert window.checkoutConfig.paymentMethods for cashondelivery; valt terug naar checkmo indien nodig.

​24. cashondelivery.html Sjabloon

Standaard COD-sjabloon maar bevat <!-- ko foreach: getRegion('additional') --> -gebied, zodat de onderliggende component voor gesplitste betaling kan worden weergegeven.

​25. split-payment.html Sjabloon

KnockoutJS-sjabloon voor de gesplitste betalingsvelden:

  • Weergave creditsaldo van winkel beschikbaar
  • Invoer van geldbedrag (nummer, stap 0.01)
  • Weergave crediteringsgedeelte opslaan (alleen-lezen)
  • Creditbericht voor winkel automatisch toepassen (wordt weergegeven wanneer splitsing geldig is en winkelkrediet > 0)
  • Foutbericht voor validatie

26. requirejs-config.js

Kaarten

  • Client_SplitPayment/js/view/payment/split-payment → de component
  • Client_SplitPayment/js/view/payment/cashondelivery-method → De COD-overschrijving
  • Client_SplitPayment/js/model/payment-method-helper → de helper

27. etc/config.xml

Standaardwaarden voor systeemconfiguratie:

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

Opmerkingen bij de kritieke implementatie

de credittoepassing van de Opslag moet BalanceManagementInterface gebruiken, niet directe modelmanipulatie. BalanceManagementInterface::apply() verwerkt de sessie, validatie en herberekening van winkelwagentjes automatisch.

PlaceOrderPluginmoet aroundPlaceOrder gebruiken (niet beforePlaceOrder). Het winkelkrediet moet worden toegepast terwijl het winkelwagentje nog actief is en dat moet worden gegarandeerd voordat $proceed() wordt aangeroepen.

het patroon van de zittingsvlag voor beginBalanceApply / endBalanceApply is kritiek. Zonder deze waarde wordt FixSplitPaymentGrandTotalPlugin uitgevoerd tijdens collectTotals() binnen de saldobewerking en wordt het totaal-generaal ingesteld op het resterende geld, waardoor BalanceManagementInterface::apply() zal mislukken of het krediet zal beperken.

stelt nooit interne foutendetails aan de klant bloot. Alle catch -blokken die naar REST-reacties gaan, moeten LocalizedException('Payment could not be processed. Please try again or contact support.') genereren.

entity_idis the numeric database ID. REST calls from App Builder always use entity_id, not increment_id.

SplitInvoiceServiceshould catch and log errors rather than propagate them. Invoice creation failure should not cancel an already-placed order — log the failure and let the Admin handle it manually.

Na het genereren van bestanden

Run these commands in the Commerce project root:

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

Einde van vraag

Gerelateerde gesplitste betalingen POC-middelen

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