@financedistrict/saleor-agentic-commerce-nextjs 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Agentic Commerce Configuration
3
+ *
4
+ * Creates and configures the agentic commerce instance that route handlers
5
+ * and middleware use. Merchants call createAgenticCommerce() once in their
6
+ * storefront code and export the instance.
7
+ */
8
+ import { SaleorClient, PaymentHandlerRegistry, type PaymentHandlerAdapter, type FormatterContext } from "@financedistrict/saleor-agentic-commerce-core";
9
+ export type AgenticCommerceConfig = {
10
+ /** Saleor GraphQL API URL (e.g., "https://api.store.com/graphql/") */
11
+ saleorApiUrl: string;
12
+ /** Saleor App Token with MANAGE_CHECKOUTS, MANAGE_ORDERS permissions */
13
+ saleorAuthToken: string;
14
+ /** Default Saleor channel slug */
15
+ channel?: string;
16
+ /** Storefront public URL (e.g., "https://store.com") */
17
+ storefrontUrl: string;
18
+ /** Store display name */
19
+ storeName: string;
20
+ /** Store description */
21
+ storeDescription?: string;
22
+ /** UCP protocol version (default: "2026-04-08") */
23
+ ucpVersion?: string;
24
+ /** ACP protocol version (default: "2026-01-30") */
25
+ acpVersion?: string;
26
+ /** API key for ACP Bearer token authentication */
27
+ acpApiKey?: string;
28
+ /** Payment handler adapters to register */
29
+ paymentHandlers?: PaymentHandlerAdapter[];
30
+ };
31
+ export type AgenticCommerceInstance = {
32
+ saleorClient: SaleorClient;
33
+ paymentHandlers: PaymentHandlerRegistry;
34
+ formatterContext: FormatterContext;
35
+ config: Required<Pick<AgenticCommerceConfig, "storefrontUrl" | "storeName" | "ucpVersion" | "acpVersion">> & Pick<AgenticCommerceConfig, "storeDescription" | "acpApiKey">;
36
+ };
37
+ export declare function createAgenticCommerce(config: AgenticCommerceConfig): AgenticCommerceInstance;
38
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EAEtB,MAAM,+CAA+C,CAAA;AAMtD,MAAM,MAAM,qBAAqB,GAAG;IAClC,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAA;IACpB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAA;IACvB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAA;IACrB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,wBAAwB;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2CAA2C;IAC3C,eAAe,CAAC,EAAE,qBAAqB,EAAE,CAAA;CAC1C,CAAA;AAMD,MAAM,MAAM,uBAAuB,GAAG;IACpC,YAAY,EAAE,YAAY,CAAA;IAC1B,eAAe,EAAE,sBAAsB,CAAA;IACvC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,qBAAqB,EAAE,eAAe,GAAG,WAAW,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC,GACxG,IAAI,CAAC,qBAAqB,EAAE,kBAAkB,GAAG,WAAW,CAAC,CAAA;CAChE,CAAA;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,uBAAuB,CA6C5F"}
package/dist/config.js ADDED
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Agentic Commerce Configuration
3
+ *
4
+ * Creates and configures the agentic commerce instance that route handlers
5
+ * and middleware use. Merchants call createAgenticCommerce() once in their
6
+ * storefront code and export the instance.
7
+ */
8
+ import { SaleorClient, PaymentHandlerRegistry, } from "@financedistrict/saleor-agentic-commerce-core";
9
+ export function createAgenticCommerce(config) {
10
+ // Validate required config
11
+ if (!config.saleorApiUrl)
12
+ throw new Error("saleorApiUrl is required");
13
+ if (!config.saleorAuthToken)
14
+ throw new Error("saleorAuthToken is required");
15
+ if (!config.storefrontUrl)
16
+ throw new Error("storefrontUrl is required");
17
+ if (!config.storeName)
18
+ throw new Error("storeName is required");
19
+ const ucpVersion = config.ucpVersion || "2026-04-08";
20
+ const acpVersion = config.acpVersion || "2026-01-30";
21
+ // Create Saleor client
22
+ const saleorClient = new SaleorClient({
23
+ apiUrl: config.saleorApiUrl,
24
+ authToken: config.saleorAuthToken,
25
+ channel: config.channel,
26
+ });
27
+ // Create and populate payment handler registry
28
+ const paymentHandlers = new PaymentHandlerRegistry();
29
+ for (const handler of config.paymentHandlers || []) {
30
+ paymentHandlers.registerAdapter(handler);
31
+ }
32
+ // Create formatter context
33
+ const formatterContext = {
34
+ storeName: config.storeName,
35
+ storefrontUrl: config.storefrontUrl,
36
+ ucpVersion,
37
+ acpVersion,
38
+ paymentHandlers,
39
+ };
40
+ return {
41
+ saleorClient,
42
+ paymentHandlers,
43
+ formatterContext,
44
+ config: {
45
+ storefrontUrl: config.storefrontUrl,
46
+ storeName: config.storeName,
47
+ storeDescription: config.storeDescription,
48
+ ucpVersion,
49
+ acpVersion,
50
+ acpApiKey: config.acpApiKey,
51
+ },
52
+ };
53
+ }
54
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,YAAY,EACZ,sBAAsB,GAIvB,MAAM,+CAA+C,CAAA;AAyCtD,MAAM,UAAU,qBAAqB,CAAC,MAA6B;IACjE,2BAA2B;IAC3B,IAAI,CAAC,MAAM,CAAC,YAAY;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;IACrE,IAAI,CAAC,MAAM,CAAC,eAAe;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAC3E,IAAI,CAAC,MAAM,CAAC,aAAa;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;IACvE,IAAI,CAAC,MAAM,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAE/D,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,YAAY,CAAA;IACpD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,YAAY,CAAA;IAEpD,uBAAuB;IACvB,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;QACpC,MAAM,EAAE,MAAM,CAAC,YAAY;QAC3B,SAAS,EAAE,MAAM,CAAC,eAAe;QACjC,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAA;IAEF,+CAA+C;IAC/C,MAAM,eAAe,GAAG,IAAI,sBAAsB,EAAE,CAAA;IACpD,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,eAAe,IAAI,EAAE,EAAE,CAAC;QACnD,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;IAC1C,CAAC;IAED,2BAA2B;IAC3B,MAAM,gBAAgB,GAAqB;QACzC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,UAAU;QACV,UAAU;QACV,eAAe;KAChB,CAAA;IAED,OAAO;QACL,YAAY;QACZ,eAAe;QACf,gBAAgB;QAChB,MAAM,EAAE;YACN,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,UAAU;YACV,UAAU;YACV,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @financedistrict/saleor-agentic-commerce-nextjs
3
+ *
4
+ * Drop-in Next.js integration for Saleor agentic commerce.
5
+ * Provides route handlers, middleware, and configuration.
6
+ */
7
+ export { createAgenticCommerce } from "./config.js";
8
+ export type { AgenticCommerceConfig, AgenticCommerceInstance } from "./config.js";
9
+ export { createUcpRoutes } from "./routes/ucp-routes.js";
10
+ export { createAcpRoutes } from "./routes/acp-routes.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACnD,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAEjF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @financedistrict/saleor-agentic-commerce-nextjs
3
+ *
4
+ * Drop-in Next.js integration for Saleor agentic commerce.
5
+ * Provides route handlers, middleware, and configuration.
6
+ */
7
+ export { createAgenticCommerce } from "./config.js";
8
+ export { createUcpRoutes } from "./routes/ucp-routes.js";
9
+ export { createAcpRoutes } from "./routes/acp-routes.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAGnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * UCP Header Middleware
3
+ *
4
+ * Parses and validates UCP-specific headers from incoming requests.
5
+ * Used by route handlers to extract agent profile, request IDs,
6
+ * and idempotency keys.
7
+ */
8
+ /**
9
+ * Parsed UCP request headers.
10
+ */
11
+ export type UcpRequestHeaders = {
12
+ /** Agent profile URL from UCP-Agent header */
13
+ agentProfile: string | null;
14
+ /** Request ID for tracing */
15
+ requestId: string | null;
16
+ /** Idempotency key for state-modifying operations */
17
+ idempotencyKey: string | null;
18
+ /** Content digest for body verification */
19
+ contentDigest: string | null;
20
+ };
21
+ /**
22
+ * Extract UCP-specific headers from a request.
23
+ *
24
+ * UCP-Agent header format: profile="https://agent.example/.well-known/ucp"
25
+ */
26
+ export declare function parseUcpHeaders(request: Request): UcpRequestHeaders;
27
+ /**
28
+ * Validate that required UCP headers are present for state-modifying operations.
29
+ * Returns an error message if validation fails, null if OK.
30
+ */
31
+ export declare function validateUcpHeaders(headers: UcpRequestHeaders, options?: {
32
+ requireAgent?: boolean;
33
+ requireIdempotency?: boolean;
34
+ }): string | null;
35
+ /**
36
+ * Create standard UCP response headers.
37
+ */
38
+ export declare function ucpResponseHeaders(requestId?: string | null): Record<string, string>;
39
+ //# sourceMappingURL=ucp-headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ucp-headers.d.ts","sourceRoot":"","sources":["../../src/middleware/ucp-headers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,8CAA8C;IAC9C,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,6BAA6B;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,qDAAqD;IACrD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,2CAA2C;IAC3C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,CAgBnE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAO,GACrE,MAAM,GAAG,IAAI,CAQf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQpF"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * UCP Header Middleware
3
+ *
4
+ * Parses and validates UCP-specific headers from incoming requests.
5
+ * Used by route handlers to extract agent profile, request IDs,
6
+ * and idempotency keys.
7
+ */
8
+ /**
9
+ * Extract UCP-specific headers from a request.
10
+ *
11
+ * UCP-Agent header format: profile="https://agent.example/.well-known/ucp"
12
+ */
13
+ export function parseUcpHeaders(request) {
14
+ const agentHeader = request.headers.get("UCP-Agent");
15
+ let agentProfile = null;
16
+ if (agentHeader) {
17
+ // Parse RFC 8941 Dictionary format: profile="url"
18
+ const match = agentHeader.match(/profile="([^"]+)"/);
19
+ agentProfile = match ? match[1] : agentHeader;
20
+ }
21
+ return {
22
+ agentProfile,
23
+ requestId: request.headers.get("Request-Id") || request.headers.get("X-Request-Id"),
24
+ idempotencyKey: request.headers.get("Idempotency-Key"),
25
+ contentDigest: request.headers.get("Content-Digest"),
26
+ };
27
+ }
28
+ /**
29
+ * Validate that required UCP headers are present for state-modifying operations.
30
+ * Returns an error message if validation fails, null if OK.
31
+ */
32
+ export function validateUcpHeaders(headers, options = {}) {
33
+ if (options.requireAgent && !headers.agentProfile) {
34
+ return "UCP-Agent header is required";
35
+ }
36
+ if (options.requireIdempotency && !headers.idempotencyKey) {
37
+ return "Idempotency-Key header is required";
38
+ }
39
+ return null;
40
+ }
41
+ /**
42
+ * Create standard UCP response headers.
43
+ */
44
+ export function ucpResponseHeaders(requestId) {
45
+ const headers = {
46
+ "Content-Type": "application/json",
47
+ };
48
+ if (requestId) {
49
+ headers["Request-Id"] = requestId;
50
+ }
51
+ return headers;
52
+ }
53
+ //# sourceMappingURL=ucp-headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ucp-headers.js","sourceRoot":"","sources":["../../src/middleware/ucp-headers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IACpD,IAAI,YAAY,GAAkB,IAAI,CAAA;IAEtC,IAAI,WAAW,EAAE,CAAC;QAChB,kDAAkD;QAClD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAA;QACpD,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAA;IAC/C,CAAC;IAED,OAAO;QACL,YAAY;QACZ,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QACnF,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QACtD,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;KACrD,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA0B,EAC1B,UAAoE,EAAE;IAEtE,IAAI,OAAO,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAClD,OAAO,8BAA8B,CAAA;IACvC,CAAC;IACD,IAAI,OAAO,CAAC,kBAAkB,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC1D,OAAO,oCAAoC,CAAA;IAC7C,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAyB;IAC1D,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;KACnC,CAAA;IACD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAA;IACnC,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * ACP Route Handlers
3
+ *
4
+ * Creates Next.js App Router route handlers for all ACP endpoints.
5
+ * Based on ACP spec version 2026-01-30.
6
+ * https://github.com/agentic-commerce-protocol/agentic-commerce-protocol/tree/main/spec/2026-01-30
7
+ *
8
+ * Endpoints:
9
+ * - POST /api/acp/checkout_sessions — Create checkout session
10
+ * - POST /api/acp/checkout_sessions/[id] — Update checkout session
11
+ * - GET /api/acp/checkout_sessions/[id] — Get checkout session
12
+ * - POST /api/acp/checkout_sessions/[id]/complete — Complete checkout session
13
+ * - POST /api/acp/checkout_sessions/[id]/cancel — Cancel checkout session
14
+ *
15
+ * Usage:
16
+ * ```ts
17
+ * // src/lib/agentic-commerce.ts
18
+ * export const agenticCommerce = createAgenticCommerce({ ... })
19
+ * export const acpRoutes = createAcpRoutes(agenticCommerce)
20
+ *
21
+ * // src/app/api/acp/checkout_sessions/route.ts
22
+ * export { POST } from '@/lib/agentic-commerce'
23
+ * ```
24
+ */
25
+ import type { AgenticCommerceInstance } from "../config.js";
26
+ export type AcpRouteHandlers = {
27
+ /** POST /api/acp/checkout_sessions */
28
+ checkoutSessions: {
29
+ POST: (request: Request) => Promise<Response>;
30
+ };
31
+ /** GET, POST /api/acp/checkout_sessions/[id] */
32
+ checkoutSession: {
33
+ GET: (request: Request, context: {
34
+ params: Promise<{
35
+ id: string;
36
+ }>;
37
+ }) => Promise<Response>;
38
+ POST: (request: Request, context: {
39
+ params: Promise<{
40
+ id: string;
41
+ }>;
42
+ }) => Promise<Response>;
43
+ };
44
+ /** POST /api/acp/checkout_sessions/[id]/complete */
45
+ checkoutSessionComplete: {
46
+ POST: (request: Request, context: {
47
+ params: Promise<{
48
+ id: string;
49
+ }>;
50
+ }) => Promise<Response>;
51
+ };
52
+ /** POST /api/acp/checkout_sessions/[id]/cancel */
53
+ checkoutSessionCancel: {
54
+ POST: (request: Request, context: {
55
+ params: Promise<{
56
+ id: string;
57
+ }>;
58
+ }) => Promise<Response>;
59
+ };
60
+ };
61
+ export declare function createAcpRoutes(instance: AgenticCommerceInstance): AcpRouteHandlers;
62
+ //# sourceMappingURL=acp-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acp-routes.d.ts","sourceRoot":"","sources":["../../src/routes/acp-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAUH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAE3D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,sCAAsC;IACtC,gBAAgB,EAAE;QAChB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;KAC9C,CAAA;IACD,gDAAgD;IAChD,eAAe,EAAE;QACf,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,OAAO,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;QAC1F,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,OAAO,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;KAC5F,CAAA;IACD,oDAAoD;IACpD,uBAAuB,EAAE;QACvB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,OAAO,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;KAC5F,CAAA;IACD,kDAAkD;IAClD,qBAAqB,EAAE;QACrB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,OAAO,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;KAC5F,CAAA;CACF,CAAA;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,uBAAuB,GAAG,gBAAgB,CA6RnF"}
@@ -0,0 +1,274 @@
1
+ /**
2
+ * ACP Route Handlers
3
+ *
4
+ * Creates Next.js App Router route handlers for all ACP endpoints.
5
+ * Based on ACP spec version 2026-01-30.
6
+ * https://github.com/agentic-commerce-protocol/agentic-commerce-protocol/tree/main/spec/2026-01-30
7
+ *
8
+ * Endpoints:
9
+ * - POST /api/acp/checkout_sessions — Create checkout session
10
+ * - POST /api/acp/checkout_sessions/[id] — Update checkout session
11
+ * - GET /api/acp/checkout_sessions/[id] — Get checkout session
12
+ * - POST /api/acp/checkout_sessions/[id]/complete — Complete checkout session
13
+ * - POST /api/acp/checkout_sessions/[id]/cancel — Cancel checkout session
14
+ *
15
+ * Usage:
16
+ * ```ts
17
+ * // src/lib/agentic-commerce.ts
18
+ * export const agenticCommerce = createAgenticCommerce({ ... })
19
+ * export const acpRoutes = createAcpRoutes(agenticCommerce)
20
+ *
21
+ * // src/app/api/acp/checkout_sessions/route.ts
22
+ * export { POST } from '@/lib/agentic-commerce'
23
+ * ```
24
+ */
25
+ import { formatAcpCheckoutSession, formatAcpCompleteResponse, formatAcpError, acpToSaleorAddress, metadataToRecord, recordToMetadataInput, } from "@financedistrict/saleor-agentic-commerce-core";
26
+ export function createAcpRoutes(instance) {
27
+ const { saleorClient, paymentHandlers, formatterContext, config } = instance;
28
+ function acpError(code, message, status) {
29
+ return Response.json(formatAcpError({ code, message, httpStatus: status }), { status });
30
+ }
31
+ function validateApiKey(request) {
32
+ if (!config.acpApiKey)
33
+ return true; // No key configured = open access
34
+ const auth = request.headers.get("Authorization");
35
+ return auth === `Bearer ${config.acpApiKey}`;
36
+ }
37
+ function endpointBaseUrl(request) {
38
+ const url = new URL(request.url);
39
+ return `${url.origin}/api/acp`;
40
+ }
41
+ /**
42
+ * Shared helper: prepare payment handlers and store metadata on checkout.
43
+ * Returns the final checkout with updated metadata.
44
+ */
45
+ async function preparePaymentAndRefetch(checkoutId, checkout, baseUrl) {
46
+ const totalAmount = Math.round(checkout.totalPrice.gross.amount * 100);
47
+ const metadata = metadataToRecord(checkout.privateMetadata);
48
+ const prepareResults = await paymentHandlers.prepareCheckoutPayment({
49
+ checkoutId,
50
+ total: totalAmount,
51
+ currencyCode: checkout.totalPrice.gross.currency,
52
+ checkoutBaseUrl: `${baseUrl}/checkout_sessions`,
53
+ storeName: config.storeName,
54
+ checkoutMetadata: metadata,
55
+ });
56
+ const metadataUpdates = recordToMetadataInput(prepareResults);
57
+ if (metadataUpdates.length > 0) {
58
+ await saleorClient.updatePrivateMetadata(checkoutId, metadataUpdates);
59
+ }
60
+ const updatedCheckout = await saleorClient.getCheckout(checkoutId);
61
+ return updatedCheckout.ok ? updatedCheckout.data : checkout;
62
+ }
63
+ return {
64
+ // =====================================================
65
+ // Create Checkout — POST /api/acp/checkout_sessions
66
+ // =====================================================
67
+ checkoutSessions: {
68
+ async POST(request) {
69
+ if (!validateApiKey(request)) {
70
+ return acpError("unauthorized", "Invalid or missing API key", 401);
71
+ }
72
+ let body;
73
+ try {
74
+ body = await request.json();
75
+ }
76
+ catch {
77
+ return acpError("invalid_body", "Request body must be valid JSON", 400);
78
+ }
79
+ const lineItems = body.line_items;
80
+ if (!Array.isArray(lineItems) || lineItems.length === 0) {
81
+ return acpError("missing", "line_items array is required", 400);
82
+ }
83
+ // Map ACP line items to Saleor checkout lines
84
+ // ACP spec: line_items[].item.id, line_items[].quantity
85
+ const lines = lineItems.map((li) => ({
86
+ variantId: li.item?.id || li.id,
87
+ quantity: li.quantity || 1,
88
+ }));
89
+ // Extract buyer info
90
+ const email = body.buyer?.email;
91
+ // Extract fulfillment address from fulfillment_details
92
+ const shippingAddress = body.fulfillment_details?.address
93
+ ? acpToSaleorAddress(body.fulfillment_details.address)
94
+ : undefined;
95
+ const billingAddress = body.billing_address
96
+ ? acpToSaleorAddress(body.billing_address)
97
+ : undefined;
98
+ // Create Saleor checkout
99
+ const checkoutResult = await saleorClient.createCheckout({
100
+ lines,
101
+ email,
102
+ shippingAddress,
103
+ billingAddress,
104
+ });
105
+ if (!checkoutResult.ok) {
106
+ return acpError("checkout_create_failed", checkoutResult.error, 422);
107
+ }
108
+ const baseUrl = endpointBaseUrl(request);
109
+ const finalCheckout = await preparePaymentAndRefetch(checkoutResult.data.id, checkoutResult.data, baseUrl);
110
+ const session = formatAcpCheckoutSession(formatterContext, finalCheckout);
111
+ return Response.json(session, { status: 201 });
112
+ },
113
+ },
114
+ // =====================================================
115
+ // Get/Update Checkout Session
116
+ // =====================================================
117
+ checkoutSession: {
118
+ async GET(request, context) {
119
+ if (!validateApiKey(request)) {
120
+ return acpError("unauthorized", "Invalid or missing API key", 401);
121
+ }
122
+ const { id } = await context.params;
123
+ const result = await saleorClient.getCheckout(id);
124
+ if (!result.ok)
125
+ return acpError("not_found", result.error, 404);
126
+ const session = formatAcpCheckoutSession(formatterContext, result.data);
127
+ return Response.json(session);
128
+ },
129
+ // ACP spec: Update uses POST (not PUT)
130
+ async POST(request, context) {
131
+ if (!validateApiKey(request)) {
132
+ return acpError("unauthorized", "Invalid or missing API key", 401);
133
+ }
134
+ const { id } = await context.params;
135
+ let body;
136
+ try {
137
+ body = await request.json();
138
+ }
139
+ catch {
140
+ return acpError("invalid_body", "Request body must be valid JSON", 400);
141
+ }
142
+ // Update buyer email
143
+ if (body.buyer?.email) {
144
+ const result = await saleorClient.updateCheckoutEmail(id, body.buyer.email);
145
+ if (!result.ok)
146
+ return acpError("invalid", result.error, 422);
147
+ }
148
+ // Update fulfillment details (address)
149
+ if (body.fulfillment_details?.address) {
150
+ const addr = acpToSaleorAddress(body.fulfillment_details.address);
151
+ const result = await saleorClient.updateCheckoutShippingAddress(id, addr);
152
+ if (!result.ok)
153
+ return acpError("invalid", result.error, 422);
154
+ }
155
+ // Update billing address
156
+ if (body.billing_address) {
157
+ const addr = acpToSaleorAddress(body.billing_address);
158
+ const result = await saleorClient.updateCheckoutBillingAddress(id, addr);
159
+ if (!result.ok)
160
+ return acpError("invalid", result.error, 422);
161
+ }
162
+ // Update selected fulfillment option
163
+ if (body.selected_fulfillment_options && Array.isArray(body.selected_fulfillment_options)) {
164
+ const selected = body.selected_fulfillment_options[0];
165
+ if (selected?.option_id) {
166
+ const result = await saleorClient.updateCheckoutDeliveryMethod(id, selected.option_id);
167
+ if (!result.ok)
168
+ return acpError("invalid", result.error, 422);
169
+ }
170
+ }
171
+ // Update line items if provided
172
+ if (body.line_items && Array.isArray(body.line_items)) {
173
+ const lines = body.line_items.map((li) => ({
174
+ variantId: li.item?.id || li.id,
175
+ quantity: li.quantity || 1,
176
+ }));
177
+ const result = await saleorClient.updateCheckoutLines(id, lines);
178
+ if (!result.ok)
179
+ return acpError("invalid", result.error, 422);
180
+ }
181
+ // Re-fetch and prepare payment
182
+ const checkoutResult = await saleorClient.getCheckout(id);
183
+ if (!checkoutResult.ok)
184
+ return acpError("not_found", checkoutResult.error, 404);
185
+ const baseUrl = endpointBaseUrl(request);
186
+ const finalCheckout = await preparePaymentAndRefetch(id, checkoutResult.data, baseUrl);
187
+ const session = formatAcpCheckoutSession(formatterContext, finalCheckout);
188
+ return Response.json(session);
189
+ },
190
+ },
191
+ // =====================================================
192
+ // Complete Checkout — returns full session + order
193
+ // =====================================================
194
+ checkoutSessionComplete: {
195
+ async POST(request, context) {
196
+ if (!validateApiKey(request)) {
197
+ return acpError("unauthorized", "Invalid or missing API key", 401);
198
+ }
199
+ const { id } = await context.params;
200
+ let body;
201
+ try {
202
+ body = await request.json();
203
+ }
204
+ catch {
205
+ return acpError("invalid_body", "Request body must be valid JSON", 400);
206
+ }
207
+ // ACP spec payment_data: { handler_id, instrument: { type, credential: { type, token } }, billing_address? }
208
+ const paymentData = body.payment_data;
209
+ if (!paymentData) {
210
+ return acpError("missing", "payment_data is required", 400);
211
+ }
212
+ // Update billing address if provided
213
+ if (paymentData.billing_address) {
214
+ const addr = acpToSaleorAddress(paymentData.billing_address);
215
+ await saleorClient.updateCheckoutBillingAddress(id, addr);
216
+ }
217
+ // Fetch checkout for metadata
218
+ const checkoutResult = await saleorClient.getCheckout(id);
219
+ if (!checkoutResult.ok)
220
+ return acpError("not_found", checkoutResult.error, 404);
221
+ const checkout = checkoutResult.data;
222
+ const metadata = metadataToRecord(checkout.privateMetadata);
223
+ // Determine the payment handler to use
224
+ const handlerId = paymentData.handler_id || "xyz.fd.prism_payment";
225
+ // Extract credential from instrument
226
+ const credential = paymentData.instrument?.credential || paymentData.credential;
227
+ // Settle payment via the appropriate handler
228
+ const settleResult = await paymentHandlers.settlePayment({
229
+ checkoutId: id,
230
+ handlerId,
231
+ credential,
232
+ checkoutMetadata: metadata,
233
+ });
234
+ if (!settleResult.success) {
235
+ return acpError("payment_declined", settleResult.error || "Payment settlement failed", 422);
236
+ }
237
+ // Complete checkout in Saleor
238
+ const orderResult = await saleorClient.completeCheckout(id);
239
+ if (!orderResult.ok)
240
+ return acpError("processing_error", orderResult.error, 422);
241
+ // Return full session with completed status + order
242
+ const response = formatAcpCompleteResponse(formatterContext, checkout, orderResult.data);
243
+ return Response.json(response);
244
+ },
245
+ },
246
+ // =====================================================
247
+ // Cancel Checkout — returns full session with canceled status
248
+ // =====================================================
249
+ checkoutSessionCancel: {
250
+ async POST(request, context) {
251
+ if (!validateApiKey(request)) {
252
+ return acpError("unauthorized", "Invalid or missing API key", 401);
253
+ }
254
+ const { id } = await context.params;
255
+ // Verify checkout exists
256
+ const result = await saleorClient.getCheckout(id);
257
+ if (!result.ok)
258
+ return acpError("not_found", result.error, 404);
259
+ // Mark as canceled via metadata
260
+ await saleorClient.updatePrivateMetadata(id, [
261
+ { key: "acp_canceled", value: "true" },
262
+ { key: "acp_canceled_at", value: new Date().toISOString() },
263
+ ]);
264
+ // Return full session with canceled status
265
+ const session = formatAcpCheckoutSession(formatterContext, result.data);
266
+ return Response.json({
267
+ ...session,
268
+ status: "canceled",
269
+ });
270
+ },
271
+ },
272
+ };
273
+ }
274
+ //# sourceMappingURL=acp-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acp-routes.js","sourceRoot":"","sources":["../../src/routes/acp-routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * UCP Route Handlers
3
+ *
4
+ * Creates Next.js App Router route handlers for all UCP endpoints.
5
+ * Based on UCP spec version 2026-04-08.
6
+ * https://ucp.dev/2026-04-08/specification/overview
7
+ *
8
+ * Endpoints:
9
+ * - GET /.well-known/ucp — Discovery profile
10
+ * - POST /api/ucp/checkout-sessions — Create checkout
11
+ * - GET /api/ucp/checkout-sessions/[id] — Get checkout
12
+ * - PUT /api/ucp/checkout-sessions/[id] — Update checkout
13
+ * - POST /api/ucp/checkout-sessions/[id]/complete — Complete checkout
14
+ * - POST /api/ucp/checkout-sessions/[id]/cancel — Cancel checkout
15
+ * - GET /api/ucp/orders/[id] — Get order
16
+ *
17
+ * Usage:
18
+ * ```ts
19
+ * // src/lib/agentic-commerce.ts
20
+ * export const agenticCommerce = createAgenticCommerce({ ... })
21
+ * export const ucpRoutes = createUcpRoutes(agenticCommerce)
22
+ *
23
+ * // src/app/.well-known/ucp/route.ts
24
+ * export { GET } from '@/lib/agentic-commerce'
25
+ * ```
26
+ */
27
+ import type { AgenticCommerceInstance } from "../config.js";
28
+ export type UcpRouteHandlers = {
29
+ /** GET /.well-known/ucp */
30
+ discovery: {
31
+ GET: (request: Request) => Promise<Response>;
32
+ };
33
+ /** POST /api/ucp/checkout-sessions */
34
+ checkoutSessions: {
35
+ POST: (request: Request) => Promise<Response>;
36
+ };
37
+ /** GET, PUT /api/ucp/checkout-sessions/[id] */
38
+ checkoutSession: {
39
+ GET: (request: Request, context: {
40
+ params: Promise<{
41
+ id: string;
42
+ }>;
43
+ }) => Promise<Response>;
44
+ PUT: (request: Request, context: {
45
+ params: Promise<{
46
+ id: string;
47
+ }>;
48
+ }) => Promise<Response>;
49
+ };
50
+ /** POST /api/ucp/checkout-sessions/[id]/complete */
51
+ checkoutSessionComplete: {
52
+ POST: (request: Request, context: {
53
+ params: Promise<{
54
+ id: string;
55
+ }>;
56
+ }) => Promise<Response>;
57
+ };
58
+ /** POST /api/ucp/checkout-sessions/[id]/cancel */
59
+ checkoutSessionCancel: {
60
+ POST: (request: Request, context: {
61
+ params: Promise<{
62
+ id: string;
63
+ }>;
64
+ }) => Promise<Response>;
65
+ };
66
+ /** GET /api/ucp/orders/[id] */
67
+ order: {
68
+ GET: (request: Request, context: {
69
+ params: Promise<{
70
+ id: string;
71
+ }>;
72
+ }) => Promise<Response>;
73
+ };
74
+ };
75
+ export declare function createUcpRoutes(instance: AgenticCommerceInstance): UcpRouteHandlers;
76
+ //# sourceMappingURL=ucp-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ucp-routes.d.ts","sourceRoot":"","sources":["../../src/routes/ucp-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAYH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAE3D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,2BAA2B;IAC3B,SAAS,EAAE;QACT,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;KAC7C,CAAA;IACD,sCAAsC;IACtC,gBAAgB,EAAE;QAChB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;KAC9C,CAAA;IACD,+CAA+C;IAC/C,eAAe,EAAE;QACf,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,OAAO,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;QAC1F,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,OAAO,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;KAC3F,CAAA;IACD,oDAAoD;IACpD,uBAAuB,EAAE;QACvB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,OAAO,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;KAC5F,CAAA;IACD,kDAAkD;IAClD,qBAAqB,EAAE;QACrB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,OAAO,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;KAC5F,CAAA;IACD,+BAA+B;IAC/B,KAAK,EAAE;QACL,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,OAAO,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;KAC3F,CAAA;CACF,CAAA;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,uBAAuB,GAAG,gBAAgB,CA6RnF"}
@@ -0,0 +1,281 @@
1
+ /**
2
+ * UCP Route Handlers
3
+ *
4
+ * Creates Next.js App Router route handlers for all UCP endpoints.
5
+ * Based on UCP spec version 2026-04-08.
6
+ * https://ucp.dev/2026-04-08/specification/overview
7
+ *
8
+ * Endpoints:
9
+ * - GET /.well-known/ucp — Discovery profile
10
+ * - POST /api/ucp/checkout-sessions — Create checkout
11
+ * - GET /api/ucp/checkout-sessions/[id] — Get checkout
12
+ * - PUT /api/ucp/checkout-sessions/[id] — Update checkout
13
+ * - POST /api/ucp/checkout-sessions/[id]/complete — Complete checkout
14
+ * - POST /api/ucp/checkout-sessions/[id]/cancel — Cancel checkout
15
+ * - GET /api/ucp/orders/[id] — Get order
16
+ *
17
+ * Usage:
18
+ * ```ts
19
+ * // src/lib/agentic-commerce.ts
20
+ * export const agenticCommerce = createAgenticCommerce({ ... })
21
+ * export const ucpRoutes = createUcpRoutes(agenticCommerce)
22
+ *
23
+ * // src/app/.well-known/ucp/route.ts
24
+ * export { GET } from '@/lib/agentic-commerce'
25
+ * ```
26
+ */
27
+ import { formatUcpProfile, formatUcpCheckoutSession, formatUcpCompleteResponse, formatUcpOrder, formatUcpError, ucpToSaleorAddress, metadataToRecord, recordToMetadataInput, } from "@financedistrict/saleor-agentic-commerce-core";
28
+ export function createUcpRoutes(instance) {
29
+ const { saleorClient, paymentHandlers, formatterContext, config } = instance;
30
+ function ucpError(code, content, status) {
31
+ return Response.json(formatUcpError({ ucpVersion: config.ucpVersion, code, content }), { status });
32
+ }
33
+ function endpointBaseUrl(request) {
34
+ const url = new URL(request.url);
35
+ return `${url.origin}/api/ucp`;
36
+ }
37
+ /**
38
+ * Shared helper: prepare payment handlers and store metadata on checkout.
39
+ * Returns the final checkout with updated metadata.
40
+ */
41
+ async function preparePaymentAndRefetch(checkoutId, checkout, baseUrl) {
42
+ const totalAmount = Math.round(checkout.totalPrice.gross.amount * 100);
43
+ const metadata = metadataToRecord(checkout.privateMetadata);
44
+ const prepareResults = await paymentHandlers.prepareCheckoutPayment({
45
+ checkoutId,
46
+ total: totalAmount,
47
+ currencyCode: checkout.totalPrice.gross.currency,
48
+ checkoutBaseUrl: `${baseUrl}/checkout-sessions`,
49
+ storeName: config.storeName,
50
+ checkoutMetadata: metadata,
51
+ });
52
+ const metadataUpdates = recordToMetadataInput(prepareResults);
53
+ if (metadataUpdates.length > 0) {
54
+ await saleorClient.updatePrivateMetadata(checkoutId, metadataUpdates);
55
+ }
56
+ const updatedCheckout = await saleorClient.getCheckout(checkoutId);
57
+ return updatedCheckout.ok ? updatedCheckout.data : checkout;
58
+ }
59
+ return {
60
+ // =====================================================
61
+ // Discovery — GET /.well-known/ucp
62
+ // =====================================================
63
+ discovery: {
64
+ async GET(request) {
65
+ const baseUrl = endpointBaseUrl(request);
66
+ const profile = await formatUcpProfile(formatterContext, baseUrl);
67
+ return Response.json(profile, {
68
+ headers: {
69
+ "Cache-Control": "public, max-age=300",
70
+ "Content-Type": "application/json",
71
+ },
72
+ });
73
+ },
74
+ },
75
+ // =====================================================
76
+ // Create Checkout Session — POST /api/ucp/checkout-sessions
77
+ // =====================================================
78
+ checkoutSessions: {
79
+ async POST(request) {
80
+ let body;
81
+ try {
82
+ body = await request.json();
83
+ }
84
+ catch {
85
+ return ucpError("invalid_body", "Request body must be valid JSON", 400);
86
+ }
87
+ const lineItems = body.line_items;
88
+ if (!Array.isArray(lineItems) || lineItems.length === 0) {
89
+ return ucpError("missing_line_items", "line_items array is required", 400);
90
+ }
91
+ // Map UCP line items to Saleor checkout lines
92
+ const lines = lineItems.map((item) => ({
93
+ variantId: item.item?.id || item.id,
94
+ quantity: item.quantity || 1,
95
+ }));
96
+ // Extract buyer email
97
+ const email = body.buyer?.email;
98
+ // Extract fulfillment address from fulfillment.methods[0].destinations[0]
99
+ const fulfillmentDest = body.fulfillment?.methods?.[0]?.destinations?.[0];
100
+ const shippingAddress = fulfillmentDest
101
+ ? ucpToSaleorAddress(fulfillmentDest)
102
+ : undefined;
103
+ // Create Saleor checkout
104
+ const checkoutResult = await saleorClient.createCheckout({
105
+ lines,
106
+ email,
107
+ shippingAddress,
108
+ });
109
+ if (!checkoutResult.ok) {
110
+ return ucpError("checkout_create_failed", checkoutResult.error, 422);
111
+ }
112
+ const baseUrl = endpointBaseUrl(request);
113
+ const finalCheckout = await preparePaymentAndRefetch(checkoutResult.data.id, checkoutResult.data, baseUrl);
114
+ const session = formatUcpCheckoutSession(formatterContext, finalCheckout);
115
+ return Response.json(session, { status: 201 });
116
+ },
117
+ },
118
+ // =====================================================
119
+ // Get/Update Checkout Session
120
+ // =====================================================
121
+ checkoutSession: {
122
+ async GET(request, context) {
123
+ const { id } = await context.params;
124
+ const result = await saleorClient.getCheckout(id);
125
+ if (!result.ok)
126
+ return ucpError("checkout_not_found", result.error, 404);
127
+ const session = formatUcpCheckoutSession(formatterContext, result.data);
128
+ return Response.json(session);
129
+ },
130
+ async PUT(request, context) {
131
+ const { id } = await context.params;
132
+ let body;
133
+ try {
134
+ body = await request.json();
135
+ }
136
+ catch {
137
+ return ucpError("invalid_body", "Request body must be valid JSON", 400);
138
+ }
139
+ // Update buyer email
140
+ if (body.buyer?.email) {
141
+ const result = await saleorClient.updateCheckoutEmail(id, body.buyer.email);
142
+ if (!result.ok)
143
+ return ucpError("email_update_failed", result.error, 422);
144
+ }
145
+ // Update fulfillment: extract destination address and selected option
146
+ if (body.fulfillment?.methods) {
147
+ const method = body.fulfillment.methods[0];
148
+ if (method) {
149
+ // Update shipping address from destination
150
+ const dest = method.destinations?.[0];
151
+ if (dest) {
152
+ const addr = ucpToSaleorAddress(dest);
153
+ const result = await saleorClient.updateCheckoutShippingAddress(id, addr);
154
+ if (!result.ok)
155
+ return ucpError("shipping_address_update_failed", result.error, 422);
156
+ }
157
+ // Update delivery method from selected option
158
+ const selectedOptionId = method.groups?.[0]?.selected_option_id;
159
+ if (selectedOptionId) {
160
+ const result = await saleorClient.updateCheckoutDeliveryMethod(id, selectedOptionId);
161
+ if (!result.ok)
162
+ return ucpError("delivery_method_update_failed", result.error, 422);
163
+ }
164
+ }
165
+ }
166
+ // Update line items if provided
167
+ if (body.line_items && Array.isArray(body.line_items)) {
168
+ const lines = body.line_items.map((item) => ({
169
+ variantId: item.item?.id || item.id,
170
+ quantity: item.quantity || 1,
171
+ }));
172
+ const result = await saleorClient.updateCheckoutLines(id, lines);
173
+ if (!result.ok)
174
+ return ucpError("items_update_failed", result.error, 422);
175
+ }
176
+ // Re-fetch and prepare payment
177
+ const checkoutResult = await saleorClient.getCheckout(id);
178
+ if (!checkoutResult.ok)
179
+ return ucpError("checkout_not_found", checkoutResult.error, 404);
180
+ const baseUrl = endpointBaseUrl(request);
181
+ const finalCheckout = await preparePaymentAndRefetch(id, checkoutResult.data, baseUrl);
182
+ const session = formatUcpCheckoutSession(formatterContext, finalCheckout);
183
+ return Response.json(session);
184
+ },
185
+ },
186
+ // =====================================================
187
+ // Complete Checkout Session
188
+ // =====================================================
189
+ checkoutSessionComplete: {
190
+ async POST(request, context) {
191
+ const { id } = await context.params;
192
+ let body;
193
+ try {
194
+ body = await request.json();
195
+ }
196
+ catch {
197
+ return ucpError("invalid_body", "Request body must be valid JSON", 400);
198
+ }
199
+ // Extract payment instrument
200
+ const payment = body.payment;
201
+ if (!payment?.instruments || !Array.isArray(payment.instruments)) {
202
+ return ucpError("missing_payment", "payment.instruments array is required", 400);
203
+ }
204
+ const selectedInstrument = payment.instruments.find((i) => i.selected) || payment.instruments[0];
205
+ if (!selectedInstrument) {
206
+ return ucpError("no_instrument_selected", "At least one payment instrument must be provided", 400);
207
+ }
208
+ // Fetch checkout for metadata
209
+ const checkoutResult = await saleorClient.getCheckout(id);
210
+ if (!checkoutResult.ok)
211
+ return ucpError("checkout_not_found", checkoutResult.error, 404);
212
+ const checkout = checkoutResult.data;
213
+ const metadata = metadataToRecord(checkout.privateMetadata);
214
+ // Update billing address if provided on instrument
215
+ if (selectedInstrument.billing_address) {
216
+ const addr = ucpToSaleorAddress(selectedInstrument.billing_address);
217
+ await saleorClient.updateCheckoutBillingAddress(id, addr);
218
+ }
219
+ // Settle payment via the appropriate handler
220
+ const settleResult = await paymentHandlers.settlePayment({
221
+ checkoutId: id,
222
+ handlerId: selectedInstrument.handler_id,
223
+ credential: selectedInstrument.credential,
224
+ checkoutMetadata: metadata,
225
+ });
226
+ if (!settleResult.success) {
227
+ return ucpError("payment_failed", settleResult.error || "Payment settlement failed", 422);
228
+ }
229
+ // Complete checkout in Saleor
230
+ const orderResult = await saleorClient.completeCheckout(id);
231
+ if (!orderResult.ok)
232
+ return ucpError("checkout_complete_failed", orderResult.error, 422);
233
+ // Return checkout session with completed status and order confirmation
234
+ const orderConfirmation = {
235
+ id: orderResult.data.id,
236
+ label: orderResult.data.number ?? undefined,
237
+ permalink_url: `${config.storefrontUrl}/orders/${orderResult.data.id}`,
238
+ };
239
+ const response = formatUcpCompleteResponse(formatterContext, checkout, orderConfirmation);
240
+ return Response.json(response);
241
+ },
242
+ },
243
+ // =====================================================
244
+ // Cancel Checkout Session
245
+ // =====================================================
246
+ checkoutSessionCancel: {
247
+ async POST(_request, context) {
248
+ const { id } = await context.params;
249
+ // Verify checkout exists
250
+ const result = await saleorClient.getCheckout(id);
251
+ if (!result.ok)
252
+ return ucpError("checkout_not_found", result.error, 404);
253
+ // Mark as canceled via metadata
254
+ await saleorClient.updatePrivateMetadata(id, [
255
+ { key: "ucp_canceled", value: "true" },
256
+ { key: "ucp_canceled_at", value: new Date().toISOString() },
257
+ ]);
258
+ // Return full checkout session with canceled status
259
+ const session = formatUcpCheckoutSession(formatterContext, result.data);
260
+ return Response.json({
261
+ ...session,
262
+ status: "canceled",
263
+ });
264
+ },
265
+ },
266
+ // =====================================================
267
+ // Get Order
268
+ // =====================================================
269
+ order: {
270
+ async GET(request, context) {
271
+ const { id } = await context.params;
272
+ const result = await saleorClient.getOrder(id);
273
+ if (!result.ok)
274
+ return ucpError("order_not_found", result.error, 404);
275
+ const order = formatUcpOrder(formatterContext, result.data);
276
+ return Response.json(order);
277
+ },
278
+ },
279
+ };
280
+ }
281
+ //# sourceMappingURL=ucp-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ucp-routes.js","sourceRoot":"","sources":["../../src/routes/ucp-routes.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@financedistrict/saleor-agentic-commerce-nextjs",
3
+ "version": "0.1.0",
4
+ "description": "Drop-in Next.js route handlers that expose your Saleor storefront to AI shopping agents via UCP and ACP protocols.",
5
+ "author": "Finance District <dev@fd.xyz>",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./routes/*": {
16
+ "types": "./dist/routes/*.d.ts",
17
+ "default": "./dist/routes/*.js"
18
+ },
19
+ "./middleware/*": {
20
+ "types": "./dist/middleware/*.d.ts",
21
+ "default": "./dist/middleware/*.js"
22
+ },
23
+ "./package.json": "./package.json"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "package.json",
28
+ "README.md",
29
+ "LICENSE"
30
+ ],
31
+ "scripts": {
32
+ "build": "tsc",
33
+ "dev": "tsc --watch",
34
+ "clean": "rm -rf dist"
35
+ },
36
+ "keywords": [
37
+ "saleor",
38
+ "saleor-sdk",
39
+ "saleor-app",
40
+ "nextjs",
41
+ "next-js",
42
+ "app-router",
43
+ "route-handler",
44
+ "agentic-commerce",
45
+ "ai-commerce",
46
+ "ai-agent",
47
+ "ai-shopping",
48
+ "ucp",
49
+ "acp",
50
+ "universal-commerce-protocol",
51
+ "agentic-commerce-protocol",
52
+ "headless-commerce",
53
+ "storefront",
54
+ "commerce-api",
55
+ "checkout",
56
+ "shopping-agent",
57
+ "autonomous-agent"
58
+ ],
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "https://github.com/financedistrict-platform/saleor-agentic-commerce.git",
62
+ "directory": "packages/nextjs"
63
+ },
64
+ "homepage": "https://github.com/financedistrict-platform/saleor-agentic-commerce#readme",
65
+ "bugs": {
66
+ "url": "https://github.com/financedistrict-platform/saleor-agentic-commerce/issues"
67
+ },
68
+ "dependencies": {
69
+ "@financedistrict/saleor-agentic-commerce-core": "workspace:*"
70
+ },
71
+ "devDependencies": {
72
+ "typescript": "^5.3.0"
73
+ }
74
+ }