POC de pagamento dividido: prompt do App Builder orchestrator AI
Use esta página para copiar o prompt completo que gera o projeto split-payment-orchestrator: o payment-orchestrator consumidor de Eventos de E/S, payment-accept e payment-deny ações da Web, o demo-dashboard e o cliente REST da Commerce.
Como usar este prompt
Copie tudo de PROMPT START para End of prompt no Cursor (com Claude) ou diretamente no Claude. Execute o prompt a partir do diretório split-payment-orchestrator/ (a raiz do projeto App Builder).
Antes de executar
- Concluir POC de pagamento dividido: pré-requisitos e configuração de ambiente.
- Tenha seu arquivo Split payment POC: environment variables reference and
.envpronto no projeto.
O prompt
INÍCIO DA SOLICITAÇÃO
Você está gerando um aplicativo completo do Adobe App Builder para orquestrar pagamentos parcelados no Adobe Commerce. Esse aplicativo recebe Eventos de E/S da Commerce, processa decisões de pagamento dividido e retorna chamadas para a Commerce via REST.
Projeto: split-payment-orchestrator
Tempo de execução: Node.js 18
Dependências de chave: @adobe/aio-sdk ^6.0.0, got ^11.8.6, oauth-1.0a ^2.2.6
Gere todos os arquivos listados abaixo. O aplicativo deve funcionar com o Adobe I/O Runtime (aio app deploy).
Estrutura de arquivo a ser gerada
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
Defina quatro ações no pacote split_payment_orchestrator:
payment-orchestrator
web: "no"(somente Gatilho de Evento de E/S — não pode ser chamado diretamente via HTTP)runtime: nodejs:18require-adobe-auth: true,final: true- Entradas do ambiente:
LOG_LEVEL,COMMERCE_BASE_URL,COMMERCE_CONSUMER_KEY,COMMERCE_CONSUMER_SECRET,COMMERCE_ACCESS_TOKEN,COMMERCE_ACCESS_TOKEN_SECRET,PAYMENT_THRESHOLD
payment-accept
web: "yes"(Ação da Web HTTP — chamada pelo painel ou ERP)runtime: nodejs:18require-adobe-auth: true,final: true- Mesmas entradas de credencial do Commerce (sem
PAYMENT_THRESHOLD)
payment-decline
web: "yes"runtime: nodejs:18require-adobe-auth: true,final: true- Same Commerce credential inputs
demo-dashboard
web: "yes"runtime: nodejs:18require-adobe-auth: false← Dashboard is publicly accessible (protected only byDEMO_UI_SECRETif set)- Inputs: all Commerce credentials +
DEMO_UI_SECRET,DEMO_UI_BASE_URL
Events registration (under 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. Implements:
createCommerceClient(params, logger) — returns { request, baseUrl }
- Reads
COMMERCE_BASE_URL,COMMERCE_CONSUMER_KEY,COMMERCE_CONSUMER_SECRET,COMMERCE_ACCESS_TOKEN,COMMERCE_ACCESS_TOKEN_SECRETfromparams - Throws if any credential is missing
- Uses
oauth-1.0awithHMAC-SHA256(Node.jscrypto.createHmac) - Uses
got@11(notgot@12+— the project uses CJS) withprefixUrl = ${baseUrl}/rest/V1/ - Adds
Authorizationheader viabeforeRequesthook request(method, path, options)— normalizes the path (strips leading/), returns{ statusCode, body }throwHttpErrors: false— never throws on 4xx/5xx; always returns the status code
actions/payment-orchestrator/threshold.js
evaluateThreshold({ orderTotal, storeCreditAmount, cashAmount, params, logger }) — returns { pass: boolean, reason: string }
Logic:
- Read
params.PAYMENT_THRESHOLD; parse as float; default to100if missing, NaN, or ≤ 0 - If
orderTotal > threshold: return{ pass: false, reason: 'PAYMENT_THRESHOLD_EXCEEDED' } - If
Math.abs((storeCreditAmount + cashAmount) - orderTotal) > 0.02: return{ pass: false, reason: 'SPLIT_AMOUNT_MISMATCH' } - Otherwise: return
{ pass: true, reason: '' }
actions/payment-orchestrator/cash-payment.js
recordCashPending({ commerce, orderId, cashAmount, logger }) — returns { ok: boolean, error? }
-
Calls
POST orders/${orderId}/commentswith: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" } } -
Returns
{ ok: true }on 2xx; returns{ ok: false, error: { code, message } }otherwise -
Wraps in try/catch; returns error object, never throws
actions/payment-orchestrator/order-update.js
updateOrderAfterOrchestration({ commerce, orderId, success, detail, logger }) — returns { ok: boolean, error? }
- Se
success: postou um comentário de histórico"Split payment orchestration completed. Order awaiting cash confirmation." - Se
!success: postagens"Payment could not be processed. Please try again or contact support."— nunca incluadetailno comentário visível ao cliente; registredetailapenas internamente - Retorna
{ ok: boolean, error? }— nunca lança
actions/payment-orchestrator/store-credit.js
applyStoreCredit({ commerce, cartId, amount, logger }) — implementação no-op obsoleta
Inclua este arquivo com um aviso JSDoc @deprecated explicando:
O orquestrador não aplica mais crédito de armazenamento via REST. O crédito de armazenamento é aplicado no check-out no módulo Commerce PHP (
PlaceOrderPlugin) usandoBalanceManagementInterface::apply(), que requer um carrinho ativo. Quando a App Builder recebe o evento de I/O, o carrinho fica inativo. Esse arquivo é mantido para referência ou para fluxos personalizados em que o crédito da loja é aplicado após o pedido.
Manter uma implementação em funcionamento (mesma forma que outros módulos) para que os desenvolvedores possam estudar o padrão, mas marcá-lo claramente como não usado no fluxo atual.
actions/payment-orchestrator/index.js
Ponto de entrada do evento de E/S. Implementa async function main(params).
Extração de carga:
Os Eventos do Adobe Commerce I/O podem fornecer a carga de várias formas. Extraia o objeto de valor da ordem verificando esses caminhos em ordem:
params.__ow_body(analisar cadeia de caracteres JSON se necessário) →.event.data.valueparams.data.valueparams.valueparams.body.event.data.value- Voltar para o próprio
params
Extração de campo do valor:
-
orderId = value.entity_id || value.id -
orderTotal = parseFloat(value.grand_total ?? value.base_grand_total ?? value.subtotal ?? '0') -
Dividir valores de
value.extension_attributes(verificarextension_attributeseextensionAttributes):storeCredit = parseFloat(ext.split_store_credit_amount ?? value.split_store_credit_amount ?? '0')cash = parseFloat(ext.split_cash_amount ?? value.split_cash_amount ?? '0')
Fluxo:
- Extrair valor; se
orderIdestiver ausente, registrar erro e retornar{ statusCode: 200, body: { ok: false, message: PUBLIC_ERROR } } - Chamar
evaluateThreshold(...)— se falhar, registrar e retornar a mesma resposta 200 - Chamada
createCommerceClient(params, logger)— se falhar, retornar o erro 200 - Se
storeCredit > 0, registrar que o crédito de armazenamento foi aplicado no check-out (nenhuma chamada REST é necessária) - Chamada
recordCashPending(...)— se falhar, chamaupdateOrderAfterOrchestration(..., success: false)e retorna o erro 200 - Call
updateOrderAfterOrchestration(..., success: true) - Return
{ statusCode: 200, body: { ok: true, message: 'processed' } }
Important: Always return statusCode: 200 — I/O Runtime will retry non-200 responses, which would cause duplicate order processing. Errors are reported in the body.
PUBLIC_ERRORconstant: "Payment could not be processed. Please try again or contact support." — used for all external-facing error messages.
actions/payment-accept/index.js
HTTP web action. Calls POST /V1/split-payment/orders/:orderId/cash-received.
Order ID resolution: Check params.orderId, then params.payload.orderId, then params.__ow_body (parsed JSON). Return 400 if missing.
Fluxo:
- Resolve
orderId; return 400 if missing - Init commerce client; return 500 if fails
- Call
POST split-payment/orders/${orderId}/cash-receivedwith empty JSON body - If 2xx: return
{ statusCode: 200, body: { ok: true, orderId, message: 'accepted' } } - If error: log and return
{ statusCode: 200, body: { ok: false, message: PUBLIC_ERROR } }
actions/payment-decline/index.js
HTTP web action. Same pattern as payment-accept but calls POST /V1/split-payment/orders/:orderId/cash-decline.
Return { ok: true, orderId, message: 'declined' } on success.
actions/demo-dashboard/index.js
Self-contained demo operator dashboard. Serves an HTML dashboard for listing pending cash orders and triggering accept/decline actions. This is a single web action that serves both the HTML UI and a JSON API.
Security:
- Optional
DEMO_UI_SECRETcheck: if set, require?secret=<value>query param orx-demo-secretheader on all requests. Return 401 if missing/wrong. - Log a warning if
DEMO_UI_SECRETis not set (dashboard is unprotected)
Roteamento (com base no método HTTP + caminho/corpo):
A ação recebe todas as solicitações. Determinar intenção de:
params.__ow_method(GET/POST) eparams.__ow_pathou parâmetros de açãoGETsem nenhuma ação → servir o painel do HTMLGETcom o parâmetroaction=list→ retornar a lista JSON de pedidos pendentesPOSTcomaction=accepteorderId→ chame a lógicapayment-accept(ou incorpore a chamada REST do Commerce)POSTcomaction=declineeorderId→ chame a lógicapayment-decline
Buscando pedidos pendentes:
- Chamada
GET orders?searchCriteria[pageSize]=50do Commerce REST - Filtrar para ordens nas quais
extension_attributes.split_cash_status === 'pending'E ordem não estão em um estado terminal (complete,closed,canceled,cancelled) - Classificar primeiro mais recente na memória
- Retornar até 20 (configurável por meio do parâmetro
limit)
Painel do HTML:
O painel é uma cadeia de caracteres do HTML retornada com Content-Type: text/html. Ele deve:
- Listar ordens de pagamento à vista pendentes em uma tabela: Nº da Ordem (increment_id), entity_id, nome do cliente, valor de pagamento à vista, valor de crédito de armazenamento, data
- Forneça os botões Aceitar e Recusar para cada ordem que chama o ponto de extremidade de API da própria ação
- Mostrar respostas de sucesso/erro em linha
- Incluir um botão de atualização
- Ser estilizado o suficiente para ser utilizável (o CSS mínimo é adequado; não há dependências externas de CDN para evitar problemas com o CORS no tempo de execução)
- Mostrar um banner de aviso se
DEMO_UI_SECRETnão estiver definido
Erro ao exibir na interface do usuário:
Quando uma chamada REST do Commerce falhar, inclua o status HTTP e uma breve descrição do corpo do erro do Commerce (limpar — retirar as tags do HTML, truncar para 500 caracteres). Não exponha as credenciais.
Auxiliares de resposta:
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=
Implantar Comando
Após gerar todos os arquivos, no diretório split-payment-orchestrator/:
npm install
cp .env.example .env
# Edit .env with your credentials
aio app deploy
Após a implantação, observe as URLs de ação impressas por aio app deploy. A URL demo-dashboard é onde você acessa o painel do operador.
Fim da solicitação
Related split payment POC resources
- Criar uma POC de pagamento dividido: ferramentas do App Builder e da IA
- Criar uma POC de pagamento dividido: demonstração completa do App Builder
- POC de pagamento dividido: decisões de arquitetura e design
- POC de pagamento dividido: pré-requisitos e configuração de ambiente
- POC de pagamento dividido: referência de variáveis de ambiente
- Split payment POC: Commerce module AI prompt
- POC de pagamento dividido: prompt do App Builder orchestrator AI
- POC de pagamento dividido: prompt da IA de extensão da interface do usuário do Experience Cloud
- POC de pagamento dividido: guia de teste e verificação
- POC de pagamento dividido: próximas etapas após a prova de conceito
- Split payment POC: tutorial quick reference for authors