@reactionary/commercetools 0.10.35 → 0.10.36

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.
package/README.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  This library was generated with [Nx](https://nx.dev).
4
4
 
5
+ ## Payment custom fields
6
+
7
+ Payments created by `checkout.addPaymentInstruction` use the
8
+ `reactionaryPaymentCustomFields` custom type, which must define:
9
+
10
+ | Field | Type | Purpose |
11
+ | --- | --- | --- |
12
+ | `commerceToolsCartId` | String | The checkout (cart) the payment belongs to. |
13
+ | `reactionaryProtocolData` | String | The payment's protocol channel, a JSON object exchanged with the payment extensions in both directions. |
14
+
15
+ `reactionaryProtocolData` is how provider-specific payment data travels
16
+ without reactionary knowing the provider:
17
+
18
+ - **Inbound:** `addPaymentInstruction` writes the instruction's `protocolData`
19
+ into it (only when non-empty) — for example the delegated payment tokens of
20
+ UCP/ACP agents (`delegated_payment_token`, `ucp_payment_credential`).
21
+ - **Outbound:** a payment API extension (e.g. the Stripe one) consumes the keys
22
+ it understands, then replaces the content with its results (e.g.
23
+ `stripe_clientSecret`, `stripe_status`), which also removes any token.
24
+ - **Reading back:** the checkout factory flattens the JSON object into the
25
+ payment instruction's `protocolData` entries.
26
+
5
27
  ## Building
6
28
 
7
29
  Run `nx build commercetools` to build the library.
@@ -8,6 +8,7 @@ var __decorateClass = (decorators, target, key, kind) => {
8
8
  if (kind && result) __defProp(target, key, result);
9
9
  return result;
10
10
  };
11
+ import { PROTOCOL_DATA_FIELD, serializeProtocolData } from "../core/payment-protocol-data.js";
11
12
  import {
12
13
  CheckoutMutationAddPaymentInstructionSchema,
13
14
  CheckoutMutationFinalizeCheckoutSchema,
@@ -205,7 +206,10 @@ class CommercetoolsCheckoutCapability extends CheckoutCapability {
205
206
  key: "reactionaryPaymentCustomFields"
206
207
  },
207
208
  fields: {
208
- commerceToolsCartId: payload.checkout.key
209
+ commerceToolsCartId: payload.checkout.key,
210
+ // Protocol data (e.g. agentic delegated payment tokens) is passed
211
+ // verbatim for the project's payment extensions to interpret.
212
+ ...payload.paymentInstruction.protocolData.length > 0 ? { [PROTOCOL_DATA_FIELD]: serializeProtocolData(payload.paymentInstruction.protocolData) } : {}
209
213
  }
210
214
  }
211
215
  }
@@ -0,0 +1,26 @@
1
+ const PROTOCOL_DATA_FIELD = "reactionaryProtocolData";
2
+ function serializeProtocolData(entries) {
3
+ return JSON.stringify(Object.fromEntries(entries.map((entry) => [entry.key, entry.value])));
4
+ }
5
+ function parseProtocolDataField(value) {
6
+ if (typeof value !== "string" || value.length === 0) {
7
+ return [];
8
+ }
9
+ try {
10
+ const parsed = JSON.parse(value);
11
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
12
+ return [];
13
+ }
14
+ return Object.entries(parsed).map(([key, entry]) => ({
15
+ key,
16
+ value: typeof entry === "string" ? entry : JSON.stringify(entry)
17
+ }));
18
+ } catch {
19
+ return [];
20
+ }
21
+ }
22
+ export {
23
+ PROTOCOL_DATA_FIELD,
24
+ parseProtocolDataField,
25
+ serializeProtocolData
26
+ };
@@ -1,3 +1,4 @@
1
+ import { PROTOCOL_DATA_FIELD, parseProtocolDataField } from "../../core/payment-protocol-data.js";
1
2
  import {
2
3
  CheckoutItemSchema
3
4
  } from "@reactionary/core";
@@ -180,10 +181,9 @@ class CommercetoolsCheckoutFactory {
180
181
  name: paymentName || method || "Unknown"
181
182
  };
182
183
  const customData = data.custom?.fields || {};
183
- const protocolData = Object.keys(customData).map((key) => ({
184
- key,
185
- value: customData[key]
186
- }));
184
+ const protocolData = Object.keys(customData).flatMap(
185
+ (key) => key === PROTOCOL_DATA_FIELD ? parseProtocolDataField(customData[key]) : [{ key, value: customData[key] }]
186
+ );
187
187
  let status = "pending";
188
188
  if (data.transactions && data.transactions.length > 0) {
189
189
  const lastTransaction = data.transactions[data.transactions.length - 1];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactionary/commercetools",
3
- "version": "0.10.35",
3
+ "version": "0.10.36",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./src/index.d.ts",
@@ -9,7 +9,7 @@
9
9
  "url": "git+https://github.com/Solteq/reactionary.git"
10
10
  },
11
11
  "dependencies": {
12
- "@reactionary/core": "0.10.35",
12
+ "@reactionary/core": "0.10.36",
13
13
  "zod": "4.1.9",
14
14
  "@commercetools/ts-client": "^4.9.1",
15
15
  "@commercetools/platform-sdk": "^8.25.0",
@@ -0,0 +1,18 @@
1
+ /**
2
+ * A payment's protocol channel: one JSON custom field on the
3
+ * `reactionaryPaymentCustomFields` type, exchanged in both directions with the
4
+ * project's payment API extensions. reactionary writes a payment instruction's
5
+ * protocol data into it; extensions consume what they understand (e.g. agent
6
+ * payment tokens) and write their results back (e.g. a Stripe client secret).
7
+ * One declared field carries arbitrary keys, which separate custom fields could
8
+ * not: commercetools rejects undeclared fields.
9
+ */
10
+ export declare const PROTOCOL_DATA_FIELD = "reactionaryProtocolData";
11
+ export declare function serializeProtocolData(entries: Array<{
12
+ key: string;
13
+ value: string;
14
+ }>): string;
15
+ export declare function parseProtocolDataField(value: unknown): Array<{
16
+ key: string;
17
+ value: string;
18
+ }>;