@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).
|
|
184
|
-
key,
|
|
185
|
-
|
|
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.
|
|
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.
|
|
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
|
+
}>;
|