feat(acp): Agentic Commerce Protocol as a master-native plugin - #775
Open
pozylon wants to merge 5 commits into
Open
feat(acp): Agentic Commerce Protocol as a master-native plugin#775pozylon wants to merge 5 commits into
pozylon wants to merge 5 commits into
Conversation
Port the ACP checkout integration (originally built on v4.8.x) onto master's IPlugin/PluginRegistry model. - New packages/plugins/src/acp/ standalone IPlugin: checkout-session, product-feed and .well-known endpoints as declarative WHATWG routes; outbound order webhooks wired in onRegister; PSP-agnostic handler + adapter allowlist. Registers no payment adapter — it drives services.orders.checkoutOrder through the configured provider. - Extend the Stripe adapter (adapter.ts/stripe.ts) with the ACP Shared Payment Token charge + agent-payment evidence capture (persisted on the order payment info). SPT stays pinned to Stripe 2026-04-22.preview; the base client stays on stable 2026-08-26.dahlia. - Register ACPPlugin in presets/all.ts (self-gates when UNCHAINED_ACP_API_KEY is unset). Idempotency + webhook dedupe remain in-process (durable cluster-wide storage is a payment-system-wide follow-up). Build + lint green; ACP unit tests (7) + full plugins suite (115) pass.
Exercise the ACP plugin end-to-end against the live engine (HTTP -> guest cart -> order -> serializer): well-known discovery, auth (bearer/API-Version/Idempotency-Key), session create/get/update/cancel + terminal state, idempotent replay + conflict, complete validation, and the product feed. Enables ACP in .env.tests and points the provider at the already-registered cryptopay GENERIC adapter — the SPT charge needs real Stripe creds, but the session lifecycle is adapter-agnostic (this also exercises the PSP-agnostic path).
Guarded on STRIPE_SECRET (like plugins-stripe.test.js): mints a real test SPT via Stripe's test-helper (/v1/test_helpers/shared_payment/granted_tokens, 2026-04-22.preview), completes an ACP checkout with it, and asserts the order confirms with the payment PAID (pi_ transaction) and the agent-payment evidence trail (token id + SPT api version) persisted on the order payment. Inert in the hermetic CI default (STRIPE_SECRET empty).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the Agentic Commerce Protocol (ACP
2026-04-17) checkout integration to master as a self-contained plugin — the checkout-session surface, product feed,.well-knowndiscovery doc, signed outbound order webhooks, and a Stripe Shared Payment Token (SPT) delegated-charge path with agent-payment evidence capture.The integration was originally built on
v4.8.x. Because master diverged from v4.8.x back at v4.6.1 (211 commits) and re-architected the plugin system, this is a re-implementation against master's model, not a port of the old files.Architecture (master-native)
packages/plugins/src/acp/— a standaloneIPlugin. Endpoints are declarative WHATWGroutes(Request→Response, mounted once for both Express and Fastify via the@whatwg-nodebridge); outbound order webhooks wire inonRegister.services.orders.checkoutOrder({ paymentContext })through whichever provider is configured. Nothing in the ACP layer assumes Stripe: the delegated token flows generically aspaymentContext.{acpToken, acpHandlerId}, and PSP-specific handling lives in the adapter. A config-driven allowlist (ACP_PAYMENT_ADAPTER_KEYS) + handler advertisement (ACP_PAYMENT_HANDLER_*) make adding PayPal/Adyen a pure adapter add.payment/stripe/adapter.ts+stripe.ts) with the SPT charge + an evidence trail (delegated-token reference, resulting charge id, API version, timestamp) persisted on the order paymentinfofor merchant-of-record dispute defense. SPT is pinned to Stripe2026-04-22.preview; the base client stays on master's stable2026-08-26.dahlia.presets/all.ts— self-gates viaonRegister, so it stays inert untilUNCHAINED_ACP_API_KEYis set.Endpoints
POST /acp/checkout_sessions·GET|POST /acp/checkout_sessions/:id·POST /acp/checkout_sessions/:id/{complete,cancel}·GET /acp/feed.jsonl·GET /.well-known/acp.jsonEvery request requires
Authorization: Bearer+API-Version: 2026-04-17; every POST also requiresIdempotency-Key.Validation
tsc --buildgreen (from a confirmed-green clean-master baseline)Deferred (intentional)
Notes
packages/plugins/src/acp/README.mdfor the full config surface.