POC van gesplitste betaling: App Builder Orchestrator AI prompt

Gebruik deze pagina om de volledige herinnering te kopiëren die het spleet-betaling-orchestrator project produceert: betalings-orchestrator I/O de consument van de Gebeurtenis, betaling-goedkeurt en betaling-daling Webacties, demo-dashboard, en de cliënt van Commerce REST.

Hoe deze herinnering te gebruiken

Kopieer alles van PROMPT START aan Eind van herinnering in Cursor (met Claude) of direct in Claude. Voer de vraag uit vanuit de map split-payment-orchestrator/ (de App Builder-projecthoofdmap).

Voordat u gaat werken

De vraag

PROMPT START

U genereert een volledige Adobe App Builder-toepassing voor het ordenen van gesplitste betalingen in Adobe Commerce. Deze toepassing ontvangt I/O-gebeurtenissen van Commerce, verwerkt gesplitste betalingsbeslissingen en roept via REST terug naar Commerce.

Project: split-payment-orchestrator
Runtime: Node.js 18
Zeer belangrijke gebiedsdelen: @adobe/aio-sdk ^6.0.0, got ^11.8.6, oauth-1.0a ^2.2.6

Genereer alle hieronder vermelde bestanden. De toepassing moet werken met Adobe I/O Runtime (aio app deploy).

Te genereren bestandsstructuur

split-payment-orchestrator/
├── package.json
├── app.config.yaml
├── .env.example
└── actions/
    ├── payment-orchestrator/
    │   ├── index.js         ← I/O Event entry point
    │   ├── commerce-client.js
    │   ├── threshold.js
    │   ├── cash-payment.js
    │   ├── order-update.js
    │   └── store-credit.js  ← Deprecated stub; kept for reference
    ├── payment-accept/
    │   └── index.js
    ├── payment-decline/
    │   └── index.js
    └── demo-dashboard/
        └── index.js

package.json

{
  "name": "split-payment-orchestrator",
  "version": "1.0.0",
  "private": true,
  "description": "Adobe App Builder action — split payment PoC orchestrator",
  "engines": { "node": ">=18" },
  "scripts": {
    "deploy": "NODE_OPTIONS=--disable-warning=DEP0040 aio app deploy",
    "aio": "NODE_OPTIONS=--disable-warning=DEP0040 aio"
  },
  "dependencies": {
    "@adobe/aio-sdk": "^6.0.0",
    "@adobe/exc-app": "^1.5.9",
    "got": "^11.8.6",
    "oauth-1.0a": "^2.2.6"
  }
}

app.config.yaml

Definieer vier acties in het split_payment_orchestrator -pakket:

payment-orchestrator

  • web: "no" (alleen I/O-gebeurtenistrigger — niet rechtstreeks aanroepbaar via HTTP)
  • runtime: nodejs:18
  • require-adobe-auth: true, final: true
  • Invoer van env: LOG_LEVEL, COMMERCE_BASE_URL, COMMERCE_CONSUMER_KEY, COMMERCE_CONSUMER_SECRET, COMMERCE_ACCESS_TOKEN, COMMERCE_ACCESS_TOKEN_SECRET, PAYMENT_THRESHOLD

payment-accept

  • web: "yes" (HTTP-webactie — aanroepbaar per dashboard of ERP)
  • runtime: nodejs:18
  • require-adobe-auth: true, final: true
  • Dezelfde Commerce-referentie-invoer (geen PAYMENT_THRESHOLD)

payment-decline

  • web: "yes"
  • runtime: nodejs:18
  • require-adobe-auth: true, final: true
  • Dezelfde Commerce-referentie-invoer

demo-dashboard

  • web: "yes"
  • runtime: nodejs:18
  • require-adobe-auth: false Het dashboard is openbaar toegankelijk (alleen beveiligd door DEMO_UI_SECRET indien ingesteld)
  • Invoer: alle Commerce-referenties + DEMO_UI_SECRET, DEMO_UI_BASE_URL

de registratie van Gebeurtenissen (onder events.registrations):

Split payment — sales order place before:
  description: Invokes payment-orchestrator when an order is about to be placed
  events_of_interest:
    - provider_metadata: dx_commerce_events
      event_codes:
        - com.adobe.commerce.observer.sales_order_place_before
  runtime_action: split_payment_orchestrator/payment-orchestrator

actions/payment-orchestrator/commerce-client.js

Shared OAuth 1.0a REST client for Adobe Commerce. Implementeert:

createCommerceClient(params, logger) — retourneert { request, baseUrl }

  • Leest COMMERCE_BASE_URL, COMMERCE_CONSUMER_KEY, COMMERCE_CONSUMER_SECRET, COMMERCE_ACCESS_TOKEN, COMMERCE_ACCESS_TOKEN_SECRET from params
  • Wordt gegenereerd wanneer referenties ontbreken
  • Gebruikt oauth-1.0a met HMAC-SHA256 (Node.js crypto.createHmac)
  • Gebruikt got@11 (niet got@12+ — het project gebruikt CJS) met prefixUrl = ${baseUrl}/rest/V1/
  • Hiermee voegt u Authorization header toe via beforeRequest haak
  • request(method, path, options) — normaliseert het pad (regelafstand stroken / ), retourneert { statusCode, body }
  • throwHttpErrors: false — genereert nooit 4xx/5xx; retourneert altijd de statuscode

actions/payment-orchestrator/threshold.js

evaluateThreshold({ orderTotal, storeCreditAmount, cashAmount, params, logger }) — retourneert { pass: boolean, reason: string }

Logica:

  1. Read params.PAYMENT_THRESHOLD; parseren als float; standaard ingesteld op 100 if missing, NaN, or ≤ 0
  2. If orderTotal > threshold: return { pass: false, reason: 'PAYMENT_THRESHOLD_EXCEEDED' }
  3. If Math.abs((storeCreditAmount + cashAmount) - orderTotal) > 0.02: return { pass: false, reason: 'SPLIT_AMOUNT_MISMATCH' }
  4. Anders: return { pass: true, reason: '' }

actions/payment-orchestrator/cash-payment.js

recordCashPending({ commerce, orderId, cashAmount, logger }) — retourneert { ok: boolean, error? }

  • Roept POST orders/${orderId}/comments aan met:

    code language-json
    {
      "statusHistory": {
        "comment": "Cash payment of $X.XX pending. Awaiting admin confirmation.",
        "entity_name": "order",
        "parent_id": "<orderId>",
        "is_visible_on_front": true,
        "is_customer_notified": false,
        "status": "pending_payment"
      }
    }
    
  • Retourneert { ok: true } op 2xx; retourneert { ok: false, error: { code, message } } anders

  • Wrapt in try/catch; retourneert foutobject, genereert nooit

actions/payment-orchestrator/order-update.js

updateOrderAfterOrchestration({ commerce, orderId, success, detail, logger }) — retourneert { ok: boolean, error? }

  • Indien success: een opmerking over de historie plaatsen "Split payment orchestration completed. Order awaiting cash confirmation."
  • Als !success: posts "Payment could not be processed. Please try again or contact support." — nooit detail opnemen in de voor de klant zichtbare opmerking; alleen intern detail registreren
  • Retourneert { ok: boolean, error? } — genereert nooit

actions/payment-orchestrator/store-credit.js

applyStoreCredit({ commerce, cartId, amount, logger }) — vervangen no-op-implementatie

Neem dit bestand op met een JSDoc @deprecated -kennisgeving waarin het volgende wordt uitgelegd:

De beheerder past geen opslagkrediet meer toe via REST. Winkelcreditering wordt toegepast bij het afrekenen in de Commerce PHP-module (PlaceOrderPlugin) met BalanceManagementInterface::apply() . Hiervoor is een actieve winkelwagentje vereist. Tegen de tijd dat App Builder de I/O-gebeurtenis ontvangt, is het winkelwagentje inactief. Dit bestand wordt ter referentie bewaard of voor aangepaste stromen waarbij winkelkrediet na bestelling wordt toegepast.

Houd een werkende implementatie (de zelfde vorm zoals andere modules) zodat kunnen de ontwikkelaars het patroon bestuderen, maar het duidelijk merken als niet gebruikt in de huidige stroom.

actions/payment-orchestrator/index.js

I/O-gebeurtenisitem. Implementeert async function main(params) .

de extractie van de lading:

Adobe Commerce I/O-gebeurtenissen kunnen de lading in verschillende vormen leveren. Extraheer het object voor de ordewaarde door deze paden op volgorde te controleren:

  1. params.__ow_body (parseer JSON-tekenreeks indien nodig) → .event.data.value
  2. params.data.value
  3. params.value
  4. params.body.event.data.value
  5. Terug naar params zelf

de extractie van het Gebied van waarde:

  • orderId = value.entity_id || value.id

  • orderTotal = parseFloat(value.grand_total ?? value.base_grand_total ?? value.subtotal ?? '0')

  • Hoeveelheden splitsen vanuit value.extension_attributes (zowel extension_attributes als extensionAttributes controleren):

    • storeCredit = parseFloat(ext.split_store_credit_amount ?? value.split_store_credit_amount ?? '0')
    • cash = parseFloat(ext.split_cash_amount ?? value.split_cash_amount ?? '0')

Stroom:

  1. Waarde extraheren; als orderId ontbreekt, logfout en retourwaarde { statusCode: 200, body: { ok: false, message: PUBLIC_ERROR } }
  2. Vraag evaluateThreshold(...) — als ontbreekt, registreer en terugkeer zelfde 200 reactie
  3. Aanroep createCommerceClient(params, logger) — indien mislukt, fout 200 retourneren
  4. Indien storeCredit > 0, werd het logboek dat krediet opslaat toegepast bij uitchecken (geen REST-aanroep nodig)
  5. Roep recordCashPending(...) aan — als dit mislukt, roept u updateOrderAfterOrchestration(..., success: false) aan en retourneert u de fout 200
  6. Roep updateOrderAfterOrchestration(..., success: true)
  7. Retourneren { statusCode: 200, body: { ok: true, message: 'processed' } }

Belangrijk: keer altijd terug statusCode: 200 — I/O Runtime zal niet-200 reacties opnieuw proberen, die dubbele ordeverwerking zou veroorzaken. Fouten worden in het lichaam gemeld.

PUBLIC_ERRORconstante: "Payment could not be processed. Please try again or contact support." — wordt gebruikt voor alle naar buiten gerichte foutberichten.

actions/payment-accept/index.js

HTTP-webactie. Roept POST /V1/split-payment/orders/:orderId/cash-received aan.

de resolutie van identiteitskaart van de Orde: Controle params.orderId, toen params.payload.orderId, toen params.__ow_body (ontleed JSON). Retourneer 400 als deze ontbreekt.

Stroom:

  1. Oplossen orderId; 400 retourneren indien ontbreekt
  2. De commerciële cliënt van het begin; terugkeer 500 als ontbreekt
  3. Roep POST split-payment/orders/${orderId}/cash-received aan met lege JSON-hoofdtekst
  4. Indien 2xx: return { statusCode: 200, body: { ok: true, orderId, message: 'accepted' } }
  5. Indien fout: log and return { statusCode: 200, body: { ok: false, message: PUBLIC_ERROR } }

actions/payment-decline/index.js

HTTP-webactie. Hetzelfde patroon als payment-accept , maar roept POST /V1/split-payment/orders/:orderId/cash-decline aan.

Retourneer { ok: true, orderId, message: 'declined' } bij succes.

actions/demo-dashboard/index.js

Onafhankelijk demo-operatordashboard. Hiermee wordt een HTML-dashboard weergegeven voor het aanbieden van lopende kasopdrachten en voor het activeren van acties voor accepteren/afwijzen. Dit is één webactie die zowel de HTML-gebruikersinterface als een JSON-API dient.

Veiligheid:

  • Optionele DEMO_UI_SECRET controle: als deze is ingesteld, hebt u voor alle aanvragen ?secret=<value> query-param of x-demo-secret header nodig. Retourneer 401 als deze ontbreekt/onjuist is.
  • Een waarschuwing vastleggen als DEMO_UI_SECRET niet is ingesteld (het dashboard is niet beveiligd)

Verpletterend (die op de methode van HTTP + weg/lichaam) wordt gebaseerd:

De handeling ontvangt alle aanvragen. Intentie bepalen uit:

  • params.__ow_method (GET/POST) en params.__ow_path of actieparams
  • GET zonder handeling → bedient het HTML-dashboard
  • GET met action=list param → return JSON list of pending orders
  • POST with action=accept and orderId → call payment-accept logic (of inline de Commerce REST-aanroep)
  • POST with action=decline and orderId → call payment-decline logic

het Ophalen van hangende orden:

  • Aanroep GET orders?searchCriteria[pageSize]=50 van Commerce REST
  • Filter naar bestellingen waarbij extension_attributes.split_cash_status === 'pending' AND-volgorde zich niet in een terminalstatus bevindt (complete, closed, canceled, cancelled)
  • Nieuwste eerst in geheugen sorteren
  • Maximaal 20 (configureerbaar via limit param)

HTML Dashboard:
Het dashboard is een HTML-tekenreeks die wordt geretourneerd met Content-Type: text/html . Zij moet:

  • Vermeld nog hangende kasorders in een tabel: Volgnummer (increment_id), entiteit_id, naam van klant, geldbedrag, bedrag van opslagkrediet, datum
  • Verstrek Accepteren en Weigeren knopen voor elke orde die het eigen API eindpunt van de actie roepen
  • Reacties met succes/fout inline tonen
  • Inclusief de knop Vernieuwen
  • Zorg ervoor dat de stijl voldoende is ingesteld om bruikbaar te zijn (minimale CSS is prima; geen externe CDN-afhankelijkheden om CORS-problemen in runtime te voorkomen)
  • Een waarschuwingsbanner weergeven als DEMO_UI_SECRET niet is ingesteld

Fout die in UI surft:
Wanneer een Commerce REST-aanroep mislukt, neemt u de HTTP-status op en een korte beschrijving van de Commerce-fouttekst (ontsmetten — HTML-tags verwijderen, afkappen tot 500 tekens). Geen referenties beschikbaar maken.

Response helpers:

function jsonResponse(statusCode, obj, extraHeaders = {}) { ... }
function htmlResponse(html) { ... }

.env.example

# Commerce REST base URL — no trailing slash
COMMERCE_BASE_URL=

# OAuth 1.0a integration credentials (Admin → System → Integrations)
COMMERCE_CONSUMER_KEY=
COMMERCE_CONSUMER_SECRET=
COMMERCE_ACCESS_TOKEN=
COMMERCE_ACCESS_TOKEN_SECRET=

# PoC threshold — must match split_payment/general/threshold in Commerce (default: 100)
PAYMENT_THRESHOLD=100

LOG_LEVEL=info

# Demo dashboard optional shared secret
DEMO_UI_SECRET=
DEMO_UI_BASE_URL=

Deploy Command

After generating all files, from the split-payment-orchestrator/ directory:

npm install
cp .env.example .env
# Edit .env with your credentials
aio app deploy

After deployment, note the action URLs printed by aio app deploy. The demo-dashboard URL is where you access the operator dashboard.

End of prompt

Gerelateerde gesplitste betalingen POC-middelen

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