@itpay/cli 0.1.2 → 0.1.4
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 +9 -6
- package/bin/itp +104 -31
- package/docs/agent/buyer/cart-checkout.json +9 -5
- package/docs/agent/buyer/catalog-search.json +1 -0
- package/docs/agent/buyer/human-claim-ui.json +1 -0
- package/docs/agent/buyer/product-recommendation.json +1 -0
- package/docs/agent/buyer/quickstart.json +2 -0
- package/docs/agent/buyer/vault-agent-read.json +1 -0
- package/package.json +1 -1
- package/skills/itpay-buyer/SKILL.md +18 -5
package/README.md
CHANGED
|
@@ -34,16 +34,18 @@ openclaw
|
|
|
34
34
|
Default API endpoint:
|
|
35
35
|
|
|
36
36
|
```text
|
|
37
|
-
|
|
37
|
+
https://dev.api.itpay.ai
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
Override it for
|
|
40
|
+
Override it for local development, staging, or production:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
export ITPAY_API_BASE=
|
|
44
|
-
export
|
|
43
|
+
export ITPAY_API_BASE=http://127.0.0.1:18080
|
|
44
|
+
export ITPAY_CORE_API_BASE=http://127.0.0.1:18080
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
Production release will switch the package default to `https://api.itpay.ai`.
|
|
48
|
+
|
|
47
49
|
## Repository Layout
|
|
48
50
|
|
|
49
51
|
```text
|
|
@@ -184,10 +186,11 @@ node ./bin/itp --version
|
|
|
184
186
|
|
|
185
187
|
## Basic User Flow
|
|
186
188
|
|
|
187
|
-
|
|
189
|
+
The default endpoint is the AWS dev backend. Set API endpoint only when testing
|
|
190
|
+
local or another environment:
|
|
188
191
|
|
|
189
192
|
```bash
|
|
190
|
-
export ITPAY_API_BASE=
|
|
193
|
+
export ITPAY_API_BASE=http://127.0.0.1:18080
|
|
191
194
|
```
|
|
192
195
|
|
|
193
196
|
For the current buyer commerce flow, search the catalog, create a cart/checkout,
|
package/bin/itp
CHANGED
|
@@ -8,8 +8,8 @@ import { execFileSync } from "node:child_process";
|
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import QRCode from "qrcode";
|
|
10
10
|
|
|
11
|
-
const VERSION = "0.1.
|
|
12
|
-
const DEFAULT_API_BASE = process.env.ITPAY_API_BASE || process.env.ITPAY_CORE_BASE_URL || "
|
|
11
|
+
const VERSION = "0.1.4";
|
|
12
|
+
const DEFAULT_API_BASE = process.env.ITPAY_API_BASE || process.env.ITPAY_CORE_API_BASE || process.env.ITPAY_CORE_BASE_URL || "https://dev.api.itpay.ai";
|
|
13
13
|
const CONFIG_DIR = path.join(os.homedir(), ".itp");
|
|
14
14
|
const CONFIG_PATH = path.join(CONFIG_DIR, "config.json");
|
|
15
15
|
const STATE_PATH = path.join(CONFIG_DIR, "state.json");
|
|
@@ -198,9 +198,9 @@ async function main() {
|
|
|
198
198
|
"buyer catalog search --query 企业工商 --category business_data_api --provider itpay_enterprise_data --json",
|
|
199
199
|
"buyer catalog get --variant var_pubg_couple_skin_cny20 --json",
|
|
200
200
|
"buyer cart create --variant var_pubg_couple_skin_cny20 --json",
|
|
201
|
-
"buyer cart create --
|
|
201
|
+
"buyer cart create --variant var_itpay_enterprise_fuzzy_search_cny01 --input company_name=京东 --json",
|
|
202
202
|
"buyer cart show <cart_id> --json",
|
|
203
|
-
"buyer cart add <cart_id> --variant var_itpay_enterprise_fuzzy_search_cny01 --quantity 1 --json",
|
|
203
|
+
"buyer cart add <cart_id> --variant var_itpay_enterprise_fuzzy_search_cny01 --input company_name=美团 --quantity 1 --json",
|
|
204
204
|
"buyer cart remove <cart_id> --line <cart_line_item_id> --json",
|
|
205
205
|
"buyer shelf manifest --json",
|
|
206
206
|
"buyer shelf snapshot --version <catalog_version> --json",
|
|
@@ -715,11 +715,12 @@ async function buyer(command, rest, flags) {
|
|
|
715
715
|
const checkoutID = flags.checkout || flags.checkout_id || positional(rest, 1) || readState().last_core_checkout_id;
|
|
716
716
|
if (!checkoutID) throw new Error("checkout_id is required");
|
|
717
717
|
const checkout = await getBuyerCheckout(checkoutID, flags);
|
|
718
|
-
await maybeClaimBuyerSessionForCheckout(checkout, flags);
|
|
718
|
+
const claimedSession = await maybeClaimBuyerSessionForCheckout(checkout, flags);
|
|
719
719
|
output(buyerRunOutput({
|
|
720
720
|
status: checkout.delivery_status || checkout.status,
|
|
721
721
|
checkout,
|
|
722
722
|
delivery: checkout.delivery,
|
|
723
|
+
buyer_session: buyerSessionClaimStatus(claimedSession),
|
|
723
724
|
agent_next_actions: deliveryAwareAgentNextActions(checkout),
|
|
724
725
|
optional_agent_read_grant: optionalAgentReadGrantHint(checkout.checkout_id, checkout)
|
|
725
726
|
}));
|
|
@@ -759,15 +760,21 @@ async function buyer(command, rest, flags) {
|
|
|
759
760
|
}
|
|
760
761
|
}));
|
|
761
762
|
return;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
const claimedSession = await maybeClaimBuyerSessionForCheckout(checkout, flags);
|
|
766
|
+
if (checkout.payment_intent_id) {
|
|
767
|
+
const intent = await getBuyerPaymentIntent(checkout.payment_intent_id, flags);
|
|
768
|
+
await renderItPayPaymentAction(intent, flags);
|
|
769
|
+
output(buyerRunOutput({
|
|
770
|
+
status: intent.status === "verified" ? "payment_verified" : "waiting_user_payment",
|
|
771
|
+
checkout,
|
|
772
|
+
payment_intent: intent,
|
|
773
|
+
buyer_session: buyerSessionClaimStatus(claimedSession),
|
|
774
|
+
agent_next_actions: intent.agent_next_actions || checkout.agent_next_actions || ["wait_payment"]
|
|
775
|
+
}));
|
|
776
|
+
return;
|
|
762
777
|
}
|
|
763
|
-
}
|
|
764
|
-
await maybeClaimBuyerSessionForCheckout(checkout, flags);
|
|
765
|
-
if (checkout.payment_intent_id) {
|
|
766
|
-
const intent = await getBuyerPaymentIntent(checkout.payment_intent_id, flags);
|
|
767
|
-
await renderItPayPaymentAction(intent, flags);
|
|
768
|
-
output(buyerRunOutput({ status: intent.status === "verified" ? "payment_verified" : "waiting_user_payment", checkout, payment_intent: intent, agent_next_actions: intent.agent_next_actions || checkout.agent_next_actions || ["wait_payment"] }));
|
|
769
|
-
return;
|
|
770
|
-
}
|
|
771
778
|
if (checkout.agent_next_actions?.includes("create_payment_intent") || checkout.next_required_action === "create_payment_intent") {
|
|
772
779
|
const intent = await createBuyerPaymentIntent(checkout.checkout_id, flags);
|
|
773
780
|
await renderItPayPaymentAction(intent, flags);
|
|
@@ -778,6 +785,7 @@ async function buyer(command, rest, flags) {
|
|
|
778
785
|
status: checkout.delivery_status || checkout.status,
|
|
779
786
|
checkout,
|
|
780
787
|
delivery: checkout.delivery,
|
|
788
|
+
buyer_session: buyerSessionClaimStatus(claimedSession),
|
|
781
789
|
agent_next_actions: deliveryAwareAgentNextActions(checkout),
|
|
782
790
|
optional_agent_read_grant: optionalAgentReadGrantHint(checkout.checkout_id, checkout)
|
|
783
791
|
}));
|
|
@@ -838,11 +846,12 @@ async function buyer(command, rest, flags) {
|
|
|
838
846
|
if (subcommand === "grants") {
|
|
839
847
|
const action = rest[1] && !String(rest[1]).startsWith("--") ? rest[1] : "list";
|
|
840
848
|
if (action === "list") {
|
|
841
|
-
await ensureBuyerSessionForVaultAccess(flags);
|
|
849
|
+
const claimedSession = await ensureBuyerSessionForVaultAccess(flags);
|
|
842
850
|
const grants = await listBuyerAgentReadGrants(flags);
|
|
843
851
|
output(buyerRunOutput({
|
|
844
852
|
status: "agent_read_grants",
|
|
845
853
|
...grants,
|
|
854
|
+
buyer_session: buyerSessionClaimStatus(claimedSession),
|
|
846
855
|
agent_next_actions: grants.agent_readable_grants?.length ? ["read_agent_grant_view"] : ["wait_for_human_agent_read_grant"]
|
|
847
856
|
}));
|
|
848
857
|
return;
|
|
@@ -1320,6 +1329,20 @@ async function maybeClaimBuyerSessionFromAuthAction(action, flags = {}) {
|
|
|
1320
1329
|
}
|
|
1321
1330
|
}
|
|
1322
1331
|
|
|
1332
|
+
function buyerSessionClaimStatus(claimed = null) {
|
|
1333
|
+
const config = readConfig();
|
|
1334
|
+
const hasSession = Boolean(readSessionToken());
|
|
1335
|
+
if (!claimed && !hasSession) return undefined;
|
|
1336
|
+
return {
|
|
1337
|
+
status: "buyer_session_saved",
|
|
1338
|
+
session_stored: true,
|
|
1339
|
+
buyer_account_id: claimed?.buyer_account_id || config.account_id || null,
|
|
1340
|
+
agent_device_id: claimed?.agent_device_id || config.device_id || null,
|
|
1341
|
+
token_included: false,
|
|
1342
|
+
agent_next_actions: ["reuse_buyer_session", "list_agent_read_grants"]
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1323
1346
|
async function maybeClaimBuyerSessionForCheckout(checkout, flags = {}) {
|
|
1324
1347
|
if (!checkout?.checkout_id) return null;
|
|
1325
1348
|
if (readSessionToken()) return null;
|
|
@@ -1358,18 +1381,46 @@ async function ensureBuyerSessionForVaultAccess(flags = {}) {
|
|
|
1358
1381
|
}
|
|
1359
1382
|
|
|
1360
1383
|
function parseBuyerAuthActionURL(action) {
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1384
|
+
if (!action || typeof action !== "object") return {};
|
|
1385
|
+
let authSessionID = String(action.auth_session_id || "").trim();
|
|
1386
|
+
if (!authSessionID && String(action.id || "").startsWith("auth_")) {
|
|
1387
|
+
authSessionID = String(action.id).trim();
|
|
1388
|
+
}
|
|
1389
|
+
let displayToken = "";
|
|
1390
|
+
let sourceURL = "";
|
|
1391
|
+
for (const rawURL of buyerAuthActionCandidateURLs(action)) {
|
|
1392
|
+
try {
|
|
1393
|
+
const parsed = new URL(rawURL);
|
|
1394
|
+
const token = parsed.searchParams.get("display_token") || "";
|
|
1395
|
+
if (token && !displayToken) displayToken = token;
|
|
1396
|
+
const match = parsed.pathname.match(/(?:^|\/)(?:v1\/buyer\/auth-sessions|auth)\/([^/?#]+)(?:\/|$)/);
|
|
1397
|
+
if (match && !authSessionID) authSessionID = decodeURIComponent(match[1]);
|
|
1398
|
+
if (!sourceURL && (match || token)) sourceURL = rawURL;
|
|
1399
|
+
if (authSessionID && displayToken) break;
|
|
1400
|
+
} catch {
|
|
1401
|
+
// Ignore non-URL display entries.
|
|
1402
|
+
}
|
|
1372
1403
|
}
|
|
1404
|
+
return { authSessionID, displayToken, sourceURL };
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
function buyerAuthActionCandidateURLs(action) {
|
|
1408
|
+
const urls = [];
|
|
1409
|
+
for (const key of ["url", "web_url", "auth_url", "oauth_start_url", "mobile_wallet_url"]) {
|
|
1410
|
+
if (action?.[key]) urls.push(String(action[key]));
|
|
1411
|
+
}
|
|
1412
|
+
const presentationDisplay = action?.presentation?.display;
|
|
1413
|
+
if (Array.isArray(presentationDisplay)) {
|
|
1414
|
+
for (const entry of presentationDisplay) {
|
|
1415
|
+
if (entry?.url) urls.push(String(entry.url));
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
if (Array.isArray(action?.display)) {
|
|
1419
|
+
for (const entry of action.display) {
|
|
1420
|
+
if (entry?.url) urls.push(String(entry.url));
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
return urls;
|
|
1373
1424
|
}
|
|
1374
1425
|
|
|
1375
1426
|
function rememberCoreAuthAction(checkoutID, action) {
|
|
@@ -1383,9 +1434,9 @@ function rememberCoreAuthAction(checkoutID, action) {
|
|
|
1383
1434
|
next[checkoutID] = {
|
|
1384
1435
|
kind: "auth_qr",
|
|
1385
1436
|
id: action.id || action.auth_session_id || parsed.authSessionID,
|
|
1386
|
-
auth_session_id:
|
|
1387
|
-
url: action.url,
|
|
1388
|
-
web_url: action.web_url || action.url,
|
|
1437
|
+
auth_session_id: parsed.authSessionID,
|
|
1438
|
+
url: action.url || parsed.sourceURL,
|
|
1439
|
+
web_url: action.web_url || action.url || parsed.sourceURL,
|
|
1389
1440
|
expires_at: action.expires_at || null,
|
|
1390
1441
|
saved_at: new Date().toISOString()
|
|
1391
1442
|
};
|
|
@@ -1519,7 +1570,7 @@ function isBuyerDeliveryComplete(result) {
|
|
|
1519
1570
|
}
|
|
1520
1571
|
|
|
1521
1572
|
function buyerRunOutput(value = {}) {
|
|
1522
|
-
return stripInternalBuyerFields({
|
|
1573
|
+
return normalizeBuyerMoneyFields(stripInternalBuyerFields({
|
|
1523
1574
|
schema_version: "itp.buyer.v1",
|
|
1524
1575
|
docs: value.docs || buyerDocsFor(value),
|
|
1525
1576
|
...value,
|
|
@@ -1528,7 +1579,29 @@ function buyerRunOutput(value = {}) {
|
|
|
1528
1579
|
claim_token_included: false,
|
|
1529
1580
|
provider_raw_payload_included: false
|
|
1530
1581
|
}
|
|
1531
|
-
});
|
|
1582
|
+
}));
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
function normalizeBuyerMoneyFields(value) {
|
|
1586
|
+
if (Array.isArray(value)) return value.map((item) => normalizeBuyerMoneyFields(item));
|
|
1587
|
+
if (!value || typeof value !== "object") return value;
|
|
1588
|
+
const next = {};
|
|
1589
|
+
for (const [key, item] of Object.entries(value)) {
|
|
1590
|
+
next[key] = normalizeBuyerMoneyFields(item);
|
|
1591
|
+
}
|
|
1592
|
+
if (
|
|
1593
|
+
typeof next.amount === "number" &&
|
|
1594
|
+
Number.isFinite(next.amount) &&
|
|
1595
|
+
typeof next.currency === "string" &&
|
|
1596
|
+
next.currency.trim()
|
|
1597
|
+
) {
|
|
1598
|
+
const currency = next.currency.trim().toUpperCase();
|
|
1599
|
+
next.amount_minor = Number.isInteger(next.amount) ? next.amount : Math.round(next.amount);
|
|
1600
|
+
next.amount_major = Number((next.amount_minor / 100).toFixed(2));
|
|
1601
|
+
next.display_amount = `${currency} ${(next.amount_minor / 100).toFixed(2)}`;
|
|
1602
|
+
next.amount_unit = "minor";
|
|
1603
|
+
}
|
|
1604
|
+
return next;
|
|
1532
1605
|
}
|
|
1533
1606
|
|
|
1534
1607
|
function buyerDocsFor(value = {}) {
|
|
@@ -3634,7 +3707,7 @@ function coreURL(pathname, flags = {}) {
|
|
|
3634
3707
|
}
|
|
3635
3708
|
|
|
3636
3709
|
function coreApiBase(flags = {}) {
|
|
3637
|
-
const base = flags.api_base || flags.core_api_base || process.env.ITPAY_API_BASE || process.env.ITPAY_CORE_API_BASE || process.env.ITPAY_CORE_BASE_URL || "
|
|
3710
|
+
const base = flags.api_base || flags.core_api_base || process.env.ITPAY_API_BASE || process.env.ITPAY_CORE_API_BASE || process.env.ITPAY_CORE_BASE_URL || "https://dev.api.itpay.ai";
|
|
3638
3711
|
return String(base).replace(/\/$/, "");
|
|
3639
3712
|
}
|
|
3640
3713
|
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"intent": "add one more selected UCP Variant.id to an existing cart before checkout",
|
|
56
|
-
"command": "itp buyer cart add <cart_id> --variant <variant_id> --quantity 1 --json",
|
|
57
|
-
"success_signal": "response.cart.cart_id is unchanged
|
|
56
|
+
"command": "itp buyer cart add <cart_id> --variant <variant_id> --input key=value --quantity 1 --json",
|
|
57
|
+
"success_signal": "response.cart.cart_id is unchanged; response.cart.line_items either includes a new line for different input/settings or increments quantity for an identical line"
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
60
|
"intent": "remove one line from an existing cart before checkout",
|
|
@@ -77,12 +77,15 @@
|
|
|
77
77
|
"Before cart creation, inspect product metadata input_schema_json and collect every required input field. Do not wait until after payment to ask for required query inputs.",
|
|
78
78
|
"Enterprise fuzzy search requires input.company_name. This can be a keyword, brand, short name, or partial company name supplied by the user, such as 京东.",
|
|
79
79
|
"Enterprise precise lookup requires input.company_name_or_credit_no. This must be a complete China mainland registered company name or unified social credit code. If the user only provides a brand/short name, resolve the exact name first or use fuzzy search before precise lookup.",
|
|
80
|
-
"Use --input key=value for service-specific inputs. For multiple lines, prefer separate cart add commands
|
|
80
|
+
"Use --input key=value for service-specific inputs. For multiple query lines, prefer separate cart add commands so each line locks its own input.",
|
|
81
|
+
"Cart line identity includes variant, offer, price, provider product, and normalized input. Only a completely identical line should merge by increasing quantity.",
|
|
82
|
+
"If the same variant has a different company_name, company_name_or_credit_no, page number, setting, or any other input value, it must remain a separate cart line.",
|
|
81
83
|
"Before checkout create, confirm buyer email is available for secure delivery. If it is missing, ask the human for the email before checkout; do not guess or use a placeholder.",
|
|
82
84
|
"Use cart_id as the checkout handoff.",
|
|
83
|
-
"Use buyer cart show whenever you need current cart contents. Do not rely on chat memory for cart state.",
|
|
85
|
+
"Use buyer cart show before changing an existing cart and whenever you need current cart contents. Do not rely on chat memory for cart state.",
|
|
84
86
|
"Use buyer cart add/remove before checkout when the user changes their mind. After checkout is created, treat the cart as locked.",
|
|
85
87
|
"Do not override cart line_items during checkout.",
|
|
88
|
+
"Cart, checkout, and catalog JSON money fields use minor units. For CNY, amount=10 or expected_amount=10 means CNY 0.10. Tell humans the display_amount or converted major-unit amount, never interpret amount as yuan.",
|
|
86
89
|
"If the user asks for several compatible products, add them to one cart and create one checkout. Do not split into separate checkouts unless ItPay rejects the cart or says split checkout is required.",
|
|
87
90
|
"If the same cart is retried, expect the same checkout unless contact/client reference changes.",
|
|
88
91
|
"The backend revalidates catalog, price, and delivery requirements.",
|
|
@@ -91,7 +94,8 @@
|
|
|
91
94
|
"Do not tell the user auth_qr is a completed payment or payment proof.",
|
|
92
95
|
"For first purchase, show the ItPay auth entry as one human orchestration entry; after provider OAuth callback the same checkout exposes payment.",
|
|
93
96
|
"After showing auth_qr, poll checkout or run buyer checkout resume until identity_status becomes identity_resolved and payment_intent_id appears.",
|
|
94
|
-
"When auth completes, CLI should claim and store the buyer session so a repeat purchase by the same agent/device can skip auth."
|
|
97
|
+
"When auth completes, CLI should claim and store the buyer session so a repeat purchase by the same agent/device can skip auth.",
|
|
98
|
+
"If checkout status/resume returns buyer_session.status=buyer_session_saved, the agent is now bound to that buyer account on this device. Continue with payment, delivery polling, or buyer vault commands; do not ask the human for a buyer session token."
|
|
95
99
|
],
|
|
96
100
|
"forbidden": [
|
|
97
101
|
"Use the UCP cart and buyer checkout commands for external-agent tests.",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"Use stable categories: business_data_api, business_verification_api, identity_verification_api, phone_verification_api, risk_compliance_api, location_weather_api, finance_data_api.",
|
|
48
48
|
"Use safe facets such as --use-case, --input-facet, --output-facet, --sensitivity-level, --delivery-mode, and --provider.",
|
|
49
49
|
"Use product and variant metadata to explain options in user language.",
|
|
50
|
+
"Money values from catalog JSON use minor units. For CNY, amount=10 means CNY 0.10, not CNY 10. Prefer display_amount when present, or divide amount/amount_minor by 100 before telling the user.",
|
|
50
51
|
"For products with requires_human_input=true, do not ask for identity numbers or phone numbers in chat; rely on ItPay human authorization/input.",
|
|
51
52
|
"Do not create checkout until the user intent maps to one selected variant or the user confirms a cart."
|
|
52
53
|
],
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"The agent may explain that ItPay intentionally separates agent operations from raw secret access.",
|
|
32
32
|
"If the human wants the agent to analyze or use the delivered result, ask them to click 'Give to Agent / 一键给 Agent' in the ItPay page and confirm with Passkey.",
|
|
33
33
|
"After the human grants access, the agent should discover the grant with `itp buyer vault grants list --checkout <checkout_id> --json`; do not ask the human to paste the grant id. The CLI restores the buyer agent session from the checkout auth handoff when possible.",
|
|
34
|
+
"If `buyer vault grants list` returns buyer_session.status=buyer_session_saved, the agent should proceed with the returned grant list; the saved session is intentionally not printed.",
|
|
34
35
|
"If the human later wants the agent to install or use something, wait for an explicit human-granted install/capability flow."
|
|
35
36
|
],
|
|
36
37
|
"forbidden": [
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
],
|
|
29
29
|
"agent_rules": [
|
|
30
30
|
"Map user intent to the variant description and price.",
|
|
31
|
+
"Catalog JSON money fields use minor units. For CNY, amount=10 means CNY 0.10 and amount=50 means CNY 0.50. Use display_amount when present, or divide by 100 before explaining price to the user.",
|
|
31
32
|
"For API products, explain what the API checks or returns, quota unit, sensitivity level, required human input, and whether Passkey/WebAuthn reveal is required.",
|
|
32
33
|
"If metadata says agent_may_view_raw_result=false, tell the user secure delivery/reveal is human-first and do not request the raw result.",
|
|
33
34
|
"For enterprise fuzzy search, tell the user the required input is a company keyword/short name/brand. The user can say something broad like 京东; the service is designed to return candidates.",
|
|
@@ -39,10 +39,12 @@
|
|
|
39
39
|
"Use --json for every ItPay command.",
|
|
40
40
|
"Search and explain options before buying unless the user already named a variant.",
|
|
41
41
|
"Add the selected UCP Variant.id to cart; do not bypass cart for CORE-028 flows.",
|
|
42
|
+
"When explaining prices, remember ItPay JSON money fields use minor units. For CNY, amount=10 means CNY 0.10. Prefer display_amount when present.",
|
|
42
43
|
"Before checkout, make sure a buyer delivery email is available. If no email is known from the current buyer context, ask the human for it before creating checkout.",
|
|
43
44
|
"Do not invent, guess, or use a placeholder email. Secure delivery and account/order access depend on the buyer email.",
|
|
44
45
|
"For first purchase, show auth_qr as the ItPay first-purchase entry: the human first approves provider login/registration/profile sharing, then ItPay should continue the same checkout to payment.",
|
|
45
46
|
"After showing auth_qr, keep running/resuming the same checkout unless the human explicitly asks you to pause. Do not stop merely because a QR was displayed.",
|
|
47
|
+
"When a buyer command returns buyer_session.status=buyer_session_saved, the CLI has stored the buyer account session for this agent device. You may continue with checkout/payment or `buyer vault` commands without asking the human for a token.",
|
|
46
48
|
"Use high-level itp buy when possible; it is designed to show the first-purchase entry, wait/resume, continue to payment, wait for verification, and poll delivery.",
|
|
47
49
|
"Show the returned payment QR exactly as provided.",
|
|
48
50
|
"Payment truth comes only from payment_intent.verified.",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"agent_rules": [
|
|
39
39
|
"Only read through `buyer vault` commands after the human has explicitly approved the agent grant in the ItPay portal.",
|
|
40
40
|
"Prefer `itp buyer vault grants list --checkout <checkout_id> --json`; the CLI can automatically restore the buyer agent session from the checkout auth handoff when possible.",
|
|
41
|
+
"If the response includes buyer_session.status=buyer_session_saved, continue directly to `buyer vault grants read <agent_read_grant_id> --json`; do not ask the human for session tokens, auth IDs, or grant IDs.",
|
|
41
42
|
"Do not ask the human to copy or paste `agent_read_grant_id`; discover it with `buyer vault grants list`.",
|
|
42
43
|
"If no grant is returned, tell the human to open their ItPay account portal, reveal with Passkey, choose fields, and confirm one-key agent authorization.",
|
|
43
44
|
"Use only fields returned in the grant view. Do not infer that unreturned fields are accessible.",
|
package/package.json
CHANGED
|
@@ -67,7 +67,7 @@ itp buyer catalog get --variant <variant_id> --json
|
|
|
67
67
|
itp buyer cart create --variant <variant_id> --json
|
|
68
68
|
itp buyer cart create --variants <variant_id_1>,<variant_id_2> --quantities 1,1 --json
|
|
69
69
|
itp buyer cart show <cart_id> --json
|
|
70
|
-
itp buyer cart add <cart_id> --variant <variant_id> --quantity 1 --json
|
|
70
|
+
itp buyer cart add <cart_id> --variant <variant_id> --input key=value --quantity 1 --json
|
|
71
71
|
itp buyer cart remove <cart_id> --line <cart_line_item_id> --json
|
|
72
72
|
itp buyer checkout create --cart <cart_id> --email <buyer_email> --phone <buyer_phone> --json
|
|
73
73
|
itp buyer checkout resume <checkout_id> --json
|
|
@@ -82,10 +82,18 @@ Enterprise data products require query input at cart time:
|
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
84
|
itp buyer cart create --variant var_itpay_enterprise_fuzzy_search_cny01 --input company_name=京东 --json
|
|
85
|
+
itp buyer cart show <cart_id> --json
|
|
86
|
+
itp buyer cart add <cart_id> --variant var_itpay_enterprise_fuzzy_search_cny01 --input company_name=美团 --json
|
|
85
87
|
itp buyer cart create --variant var_itpay_enterprise_precise_lookup_cny05 --input company_name_or_credit_no=北京京东世纪贸易有限公司 --json
|
|
86
88
|
itp buy var_itpay_enterprise_fuzzy_search_cny01 --sandbox --email <buyer_email> --input company_name=京东 --json
|
|
87
89
|
```
|
|
88
90
|
|
|
91
|
+
For cart edits, always read the server cart first with `buyer cart show`.
|
|
92
|
+
Cart line identity includes the variant, offer, price, provider product, and
|
|
93
|
+
normalized input. A fully identical line increments quantity; a different
|
|
94
|
+
company name, exact name, page number, setting, or other input must stay as a
|
|
95
|
+
separate line.
|
|
96
|
+
|
|
89
97
|
Use fuzzy search when the user gives a short name, brand, keyword, or uncertain
|
|
90
98
|
entity. Use precise lookup only after you have the exact China mainland
|
|
91
99
|
registered company name or unified social credit code. If the user says
|
|
@@ -97,9 +105,11 @@ registered name or run fuzzy search first.
|
|
|
97
105
|
1. Use `--json` for every ItPay command.
|
|
98
106
|
2. Do not invent service IDs, variant IDs, checkout IDs, payment URLs, QR URLs,
|
|
99
107
|
payment intent IDs, delivery IDs, or claim links.
|
|
100
|
-
3. When the user asks for several compatible services,
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
3. When the user asks for several compatible services, use one cart and one
|
|
109
|
+
checkout. Prefer `buyer cart create` for the first line, then `buyer cart
|
|
110
|
+
show` and `buyer cart add` for each additional query line so each service
|
|
111
|
+
input is locked to the correct cart line. Split only when ItPay rejects the
|
|
112
|
+
cart or explicitly says split checkout is required.
|
|
103
113
|
4. Before checkout, make sure a buyer delivery email is available. If the CLI
|
|
104
114
|
has no known buyer email, ask the human for the email; do not invent one,
|
|
105
115
|
do not use placeholders, and do not proceed to checkout without it. The
|
|
@@ -130,7 +140,10 @@ registered name or run fuzzy search first.
|
|
|
130
140
|
session IDs, display tokens, or grant IDs. Run
|
|
131
141
|
`itp buyer vault grants list ...` and then `itp buyer vault read ...`.
|
|
132
142
|
The CLI automatically restores the buyer agent session from the checkout
|
|
133
|
-
auth handoff when possible.
|
|
143
|
+
auth handoff when possible. If the JSON includes
|
|
144
|
+
`buyer_session.status=buyer_session_saved`, continue with the returned
|
|
145
|
+
grants; the session token is intentionally stored locally and not printed.
|
|
146
|
+
Use only the fields returned by that command.
|
|
134
147
|
12. If the user asks you to analyze, compare, summarize, install, or otherwise
|
|
135
148
|
use a delivered result, you may ask them to open the ItPay claim/account
|
|
136
149
|
page, click "Give to Agent / 一键给 Agent", choose fields, and confirm with
|