Split payment POC: testing and verification guide
This guide walks you through verifying that every component works correctly, in the order they should be tested. Start from the bottom (Commerce module) and work up (App Builder).
Step 1 — Verify Commerce Module Installation
After running bin/magento setup:upgrade and bin/magento setup:di:compile:
# Confirm module is enabled
bin/magento module:status Client_SplitPayment
# Confirm db_schema columns were added
bin/magento doctrine:schema:validate
# or check directly:
mysql -u <user> -p <dbname> -e "DESCRIBE sales_order;" | grep split
Expected output: four columns starting with split_ visible in sales_order.
Step 2 — Verify Commerce Admin Configuration
In Commerce Admin:
- Stores > Configuration > Sales > Payment Methods — confirm Cash On Delivery is enabled with title
Cash - Stores > Configuration > Customers > Customer Configuration > Store Credit Options — confirm enabled
- Confirm your test customer has store credit: Customers > All Customers > [customer] > Store Credit
Step 3 — Verify REST Endpoints Are Accessible
Use curl to confirm the endpoints respond (they will reject unauthorized requests, but a 401 confirms they’re routed correctly):
# Should return 401 (not 404) — endpoint exists but requires auth
curl -X POST https://your-store.example.com/rest/V1/split-payment/orders/1/cash-received
# Should return 200 or session-based response — anonymous endpoint
curl -X POST https://your-store.example.com/rest/V1/split-payment/set \
-H "Content-Type: application/json" \
-d '{"storeCreditAmount": 0, "cashAmount": 0}'
Step 4 — Test the Checkout UI
-
Log in to the storefront as your test customer (who has store credit)
-
Add a product to cart (total under $100 after shipping + tax)
-
Proceed to checkout
-
At the payment step, select Cash (or Cash On Delivery)
-
Verify the split payment fields appear:
- Your store credit balance shown
- Cash amount field pre-filled with the order total
- “Store credit toward this order” field showing $0.00 (since cash = full order total)
-
Reduce the cash amount (e.g., enter $10 for a $50 order)
-
Verify the store credit portion updates to $40.00
-
Verify the message appears:
"The remaining $40.00 will automatically be applied from your store credit."
Test validation:
- Enter a cash amount greater than the order total → error message
- Enter a cash amount that requires more store credit than available → error message
- Enter cash = 0 → error (or store credit covers entire order)
Step 5 — Test Threshold Guard
- Add products totaling more than $100 (subtotal + shipping + tax > $100)
- Proceed to checkout, select Cash
- Attempt to place the order
- Verify the error message appears:
"Payment could not be processed. Please try again or contact support." - Verify the cart is preserved (customer can still adjust cart and try again)
Step 6 — Place a Test Split Payment Order
- Build a cart under $100 (logged in customer with store credit)
- Select Cash at checkout
- Enter a cash amount less than the order total (e.g., $10 of a $45 order)
- Confirm the store credit message appears
- Click Place Order
After order placement, verify in Commerce Admin:
-
Order is in
pending_paymentstatus -
Order has two history comments:
"Cash payment of $X.XX pending. Awaiting admin confirmation."(from App Builderpayment-orchestrator)"Split payment orchestration completed. Order awaiting cash confirmation."(from App Builder)
-
The split payment amounts are visible in the order payment block
If no App Builder comments appear: Check App Builder action logs with
aio app logs. The event may not have fired or the action may have an error.
Step 7 — Test Accept via Simulation Script
The simulation script is the fastest way to test the accept/decline flow without the full operator UI.
cd commerce-checkout-starter-kit
cp commerce-backend-ui-1/.env.simulation.example commerce-backend-ui-1/.env.simulation
# Edit .env.simulation with your credentials
# List recent orders (find your test order entity_id)
node commerce-backend-ui-1/scripts/simulate-split-payment.mjs list
# Show split payment fields for a specific order
node commerce-backend-ui-1/scripts/simulate-split-payment.mjs show 42
# Accept the cash payment
node commerce-backend-ui-1/scripts/simulate-split-payment.mjs accept 42
After accept, verify in Commerce Admin order view:
- Order status is
processing - History comment:
"Cash payment of $X.XX received." - Cash invoice created (visible in Invoices tab)
- Shipment created (visible in Shipments tab, if applicable)
- History comment:
"Split payment: cash portion invoiced #XXXXXXXX." - History comment:
"Split payment: shipment created after cash was accepted (App Builder / API)."
Step 8 — Test Decline via Simulation Script
Place another test order (same setup as Step 6), then:
node commerce-backend-ui-1/scripts/simulate-split-payment.mjs decline <orderId>
After decline, verify in Commerce Admin:
- Order status is
canceled - History comment:
"Cash payment declined (simulated fraud check)." split_cash_status=declined
Step 9 — Test the Demo Dashboard
After deploying the split-payment-orchestrator, aio app deploy prints the action URLs.
Open the demo-dashboard URL in a browser:
https://[runtime-host]/api/v1/web/split_payment_orchestrator/demo-dashboard
If DEMO_UI_SECRET is set:
https://[runtime-host]/api/v1/web/split_payment_orchestrator/demo-dashboard?secret=<your-secret>
With a pending order:
- The dashboard should show the order in the pending list
- Click Accept → order should move to
processingin Commerce - Place another order; click Decline → order should be
canceledin Commerce
Step 10 — Test App Builder Action Logs
# Follow logs in real-time
aio app logs --tail
# Or view last invocations
aio runtime activation list --limit 10
aio runtime activation logs <activation-id>
For the payment-orchestrator, look for:
[INFO] Split payment orchestration finished { orderId: '42' }
For payment-accept or payment-decline:
[INFO] Cash payment accepted on Commerce via REST { orderId: '42' }
Common Issues and Fixes
“The signature is invalid” from Commerce OAuth
Cause: Clock skew between App Builder runtime and Commerce, or an OAuth signing bug.
Fix:
- Confirm
COMMERCE_BASE_URLhas no trailing slash - Confirm the four OAuth credentials are for an activated integration
- Test with the simulation script first — if the script works but App Builder doesn’t, it’s likely an env variable not loaded (check
aio app deployoutput for missing env vars)
Split payment fields not appearing in checkout
Cause: LayoutProcessorPlugin injection paths don’t match your checkout layout.
Fix:
- Check the browser console for RequireJS errors loading
Client_SplitPayment/js/view/payment/split-payment - Check
bin/magento setup:static-content:deploycompleted successfully - Flush cache:
bin/magento cache:flush - If your theme has a custom checkout, the
LayoutProcessorPluginpath to inject the component may need adjustment
Store credit not applying / “Payment could not be processed” at place order
Cause: Usually one of the edge case plugins not working correctly.
Check:
- Is
SplitPaymentSessionreturning the correct amounts? Add temporary debug logging inPlaceOrderPlugin - Is
FixSplitPaymentGrandTotalPluginrunning and affecting the quote total beforeBalanceManagementInterface::apply()is called? ThebeginBalanceApply()flag should suppress it. - Is the customer balance module enabled in Commerce?
App Builder action receives event but orderId is missing
Cause: The io_events.xml field list doesn’t include entity_id, or the event payload shape changed.
Fix:
- Confirm
io_events.xmlincludesentity_idin the field list - In the action, log
JSON.stringify(params)temporarily to see the full payload shape - Check that the
extractValue()function is finding the right nesting level
Orders don’t show in demo dashboard
Cause: Commerce REST orders search criteria not returning orders, or split_cash_status field not in the REST response.
Fix:
- Confirm
OrderRepositoryPluginis loading extension attributes correctly - Test directly:
GET /rest/V1/orders?searchCriteria[pageSize]=5and check ifextension_attributes.split_cash_statusappears in the response - Check that
extension_attributes.xmlis correctly declaring thesplit_cash_statusattribute onOrderInterface
Verification Checklist
- [ ]
split_*columns visible insales_ordertable - [ ] REST endpoints return 401 (not 404) when called without auth
- [ ] Split payment UI renders at checkout when Cash is selected
- [ ] Validation messages work (overpayment, insufficient credit)
- [ ] Threshold guard blocks orders > $100
- [ ] Placed order has
pending_paymentstatus and App Builder comments - [ ]
simulate-split-payment.mjs listshows the test order with split amounts - [ ]
simulate-split-payment.mjs accept <id>moves order toprocessingwith invoice and shipment - [ ]
simulate-split-payment.mjs decline <id>cancels the order - [ ] Demo dashboard lists pending orders and accept/decline work from the UI