@agenzo/merchant-cli 0.8.16 → 0.9.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.
package/dist/index.js CHANGED
@@ -2162,66 +2162,166 @@ var unifiedOrdersListSchema = {
2162
2162
  cli: CLI_NAME,
2163
2163
  noun: ORDERS_NOUN,
2164
2164
  verb: "list",
2165
- description: 'List orders across ALL providers (ride + hotel) in one call. Use this for generic "my orders" / "order history" requests. Prefer ride-elife/hotel-redaug list-orders when the user names a specific business.',
2165
+ description: "List orders across ALL providers (ride + hotel + flight) with common filters and offset/cursor pagination. Use domain-specific list-orders only for provider-specific fields.",
2166
2166
  flags: {
2167
- "order-type": { type: "string", required: false, description: "Filter by provider: ride | hotel" },
2167
+ "order-type": { type: "string", required: false, description: "Legacy single order type: ride | hotel | flight" },
2168
+ "order-types": { type: "string", required: false, description: "Comma-separated order types: ride,hotel,flight" },
2168
2169
  member: MEMBER_FLAG_SCHEMA,
2169
- status: { type: "string", required: false, description: "Filter by NORMALIZED status (NOT the domain-specific status): PENDING | CONFIRMED | COMPLETED | CANCELLED | FAILED" },
2170
- page: { type: "int", required: false, default: 1, description: "Page number", constraints: ">= 1" },
2171
- "page-size": { type: "int", required: false, default: 20, description: "Items per page", constraints: ">= 1" }
2170
+ status: { type: "string", required: false, description: "Legacy single normalized status: PENDING | CONFIRMED | COMPLETED | CANCELLED | FAILED" },
2171
+ statuses: { type: "string", required: false, description: "Comma-separated normalized statuses" },
2172
+ "created-from": { type: "string", required: false, description: "ISO 8601 created-at lower bound (inclusive)" },
2173
+ "created-to": { type: "string", required: false, description: "ISO 8601 created-at upper bound (exclusive)" },
2174
+ cursor: { type: "string", required: false, description: "Opaque cursor returned by the previous page" },
2175
+ page: { type: "int", required: false, default: 1, description: "Legacy 1-based page number", constraints: ">= 1" },
2176
+ "page-size": { type: "int", required: false, default: 20, description: "Items per page", constraints: "1-100" }
2172
2177
  },
2173
2178
  response: {
2174
2179
  orders: {
2175
2180
  type: "array",
2176
- description: "Slim cross-provider order-index items. For business-specific fields (vehicle_class, hotel_name, etc.), call `orders get --order-id <id>` or the domain-specific `get`.",
2181
+ description: "Slim cross-provider index items. Call `orders get` for business-specific detail.",
2177
2182
  items: {
2178
- order_id: { type: "string", description: "Order id (rio_... for ride, hho_... for hotel). Pass to `orders get`." },
2179
- member_id: { type: "string|null", description: "End-user this order is attributed to; null when unattributed" },
2180
- order_type: { type: "string", description: "'ride' or 'hotel'" },
2181
- status: { type: "string", description: "Normalized status: PENDING | CONFIRMED | COMPLETED | CANCELLED | FAILED" },
2182
- amount: { type: "float|null", description: "Order amount in DECIMAL currency units (NOT cents)" },
2183
+ order_id: { type: "string", description: "Order id (rio_..., hho_..., or ffo_...). Pass to `orders get`." },
2184
+ member_id: { type: "string|null", description: "Attributed end-user id; null when unattributed" },
2185
+ order_type: { type: "string", description: "ride | hotel | flight" },
2186
+ status: { type: "string", description: "Original provider-domain status for display" },
2187
+ unified_status: { type: "string", description: "PENDING | CONFIRMED | COMPLETED | CANCELLED | FAILED" },
2188
+ amount: { type: "float|null", description: "Order amount in decimal currency units" },
2183
2189
  currency: { type: "string|null", description: "ISO 4217 currency code" },
2184
2190
  created_at: { type: "string|null", description: "ISO 8601 datetime" },
2185
2191
  updated_at: { type: "string|null", description: "ISO 8601 datetime" }
2186
2192
  }
2187
2193
  },
2188
2194
  total: { type: "int", description: "Total matching orders across all providers" },
2189
- page: { type: "int", description: "Current page" },
2190
- page_size: { type: "int", description: "Items per page" }
2195
+ page: { type: "int", description: "Legacy current page" },
2196
+ page_size: { type: "int", description: "Items per page" },
2197
+ next_cursor: { type: "string|null", description: "Opaque cursor for the next page; null at the end" },
2198
+ has_more: { type: "bool", description: "Whether another page is available" },
2199
+ applied_filters: { type: "object", description: "Normalized filters applied by the platform" }
2191
2200
  },
2192
2201
  example: {
2193
- command: "agenzo-merchant-cli orders list --page 1 --page-size 10",
2194
- output_summary: "Returns a paginated, cross-provider list of orders (both ride and hotel). If the user then asks about one order, use its order_id with `orders get`."
2202
+ command: "agenzo-merchant-cli orders list --order-types flight,hotel --created-from 2026-07-01T00:00:00Z --page-size 20",
2203
+ output_summary: "Returns ride, hotel, and flight orders with stable pagination metadata."
2195
2204
  },
2196
2205
  error_recovery: {
2197
- INVALID_REQUEST: "The --status value is not one of PENDING/CONFIRMED/COMPLETED/CANCELLED/FAILED. Fix and retry.",
2206
+ INVALID_REQUEST: "Fix invalid type/status/date/cursor filters and retry.",
2198
2207
  INTERNAL_ERROR: "Transient backend error. Retry once after a short delay.",
2199
- PARAM_INVALID: "Ensure --page / --page-size are positive integers, then retry."
2208
+ PARAM_INVALID: "Fix conflicting or invalid CLI options, then retry."
2200
2209
  }
2201
2210
  };
2202
2211
  var unifiedOrdersGetSchema = {
2203
2212
  cli: CLI_NAME,
2204
2213
  noun: ORDERS_NOUN,
2205
2214
  verb: "get",
2206
- description: "Get a single order detail by id, regardless of which provider (ride/hotel) it belongs to. The platform resolves order_id -> provider internally and returns that provider's own detail shape.",
2215
+ description: "Get a ride, hotel, or flight order detail by id. The platform resolves order_id to the owning domain and returns that domain detail shape.",
2207
2216
  flags: {
2208
- "order-id": { type: "string", required: true, description: "Order id from `orders list` (rio_... for ride, hho_... for hotel)" }
2217
+ "order-id": { type: "string", required: true, description: "Order id from `orders list` (rio_..., hho_..., or ffo_...)" }
2209
2218
  },
2210
2219
  response: {
2211
2220
  "(varies by order_type)": {
2212
2221
  type: "object",
2213
- description: "The response shape is delegated to the owning provider and therefore varies: a ride order returns the same shape as `ride-elife get`; a hotel order returns the same shape as `hotel-redaug get`. Treat the result as an opaque object and surface whatever fields it contains \u2014 do NOT assume a fixed schema."
2222
+ description: "Delegated ride, hotel, or flight detail. Treat the result as an opaque domain object and surface the returned fields."
2214
2223
  }
2215
2224
  },
2216
2225
  example: {
2217
- command: "agenzo-merchant-cli orders get --order-id hho_01K...",
2218
- output_summary: "Returns the order's detail, delegated to its owning provider (ride or hotel)."
2226
+ command: "agenzo-merchant-cli orders get --order-id ffo_01K...",
2227
+ output_summary: "Returns the order's provider-domain detail."
2219
2228
  },
2220
2229
  error_recovery: {
2221
- ORDER_NOT_FOUND: "The order_id does not exist or does not belong to this developer/org. Verify the id from `orders list`. Do NOT retry blindly.",
2230
+ ORDER_NOT_FOUND: "The order_id does not exist or does not belong to this developer/org. Verify the id from `orders list`.",
2222
2231
  INTERNAL_ERROR: "The order's provider detail lookup is temporarily unavailable. Retry once after a short delay."
2223
2232
  }
2224
2233
  };
2234
+ var ordersPayBatchSchema = {
2235
+ cli: CLI_NAME,
2236
+ noun: ORDERS_NOUN,
2237
+ verb: "pay-batch",
2238
+ description: "Settle a batch of orders (may mix ride/hotel/flight \u2014 hho_/ffo_/rio_) in ONE aggregate payment via a single payment credential. Physical landing point of the logical write tool orders__aggregate__pay-batch, invoked by the trip-aggregate pay-orders write verb through UniversalGateway (executed only after the single confirmation gate; never exposed to the LLM). Amounts are NOT passed here \u2014 the platform sums each order's locked authoritative price. Provide the aggregate total via one rail: --payment-token-id (\u8F68A: network-token minted for the aggregate total, external_transaction_id bound to this payment_group \u2014 one UnionPay/Visa passkey) OR --payment-method-id (\u8F68B: EVO bound card \u2014 one 3DS challenge); both may be omitted (monthly_settlement / platform default card). On EVO cardholder authentication the response is AUTHENTICATION_REQUIRED with a three_ds_url + merchant_trans_id; finish it out-of-band, then an idempotent replay settles. On success the batch becomes settled / partially_settled (upstream-confirmation-failed orders are refunded). Supports --watch to poll until a terminal batch status.",
2239
+ flags: {
2240
+ "order-ids": {
2241
+ type: "string",
2242
+ required: true,
2243
+ description: `Ordered order ids to settle together \u2014 comma-separated (hho_1,ffo_2,rio_3) or a JSON array (["hho_1","ffo_2"]). May mix hho_/ffo_/rio_ domains. Amounts come from each order's locked authoritative price (NOT passed here).`
2244
+ },
2245
+ "payment-token-id": {
2246
+ type: "string",
2247
+ required: false,
2248
+ description: "[\u8F68A] Network-token id (UnionPay/Visa) minted for the aggregate total with external_transaction_id bound to this payment_group (direct-charge main path). Mutually exclusive with --payment-method-id; both may be omitted for monthly_settlement / platform default."
2249
+ },
2250
+ "payment-method-id": {
2251
+ type: "string",
2252
+ required: false,
2253
+ description: "[\u8F68B] EVO bound-card id to settle the aggregate total via one 3DS challenge (explicit/fallback rail). Mutually exclusive with --payment-token-id."
2254
+ },
2255
+ "evo-explicit": {
2256
+ type: "bool",
2257
+ required: false,
2258
+ default: false,
2259
+ description: "[\u8F68B \u786C\u95E8\u69DB] Explicit opt-in to settle via the EVO bound-card rail. Set true ONLY when the user explicitly chose EVO; forwarded to the body as evo_explicit=true. Omit on the payment-token-id direct-charge path."
2260
+ },
2261
+ "payment-group-id": {
2262
+ type: "string",
2263
+ required: false,
2264
+ description: "Optional caller-pre-generated payment group id; omit to let the platform generate one. The whole batch is associated with this group for cross-provider reconciliation."
2265
+ },
2266
+ member: MEMBER_FLAG_SCHEMA,
2267
+ "idempotency-key": {
2268
+ type: "string",
2269
+ required: true,
2270
+ description: "Unique key forwarded verbatim as the Idempotency-Key header; never auto-generated. The SAME key + the SAME ordered order_ids replays as the same batch (dedup re-check, no double charge); any change to order_ids yields a new batch.",
2271
+ constraints: "1-128 chars [A-Za-z0-9_-]"
2272
+ },
2273
+ watch: {
2274
+ type: "bool",
2275
+ required: false,
2276
+ default: false,
2277
+ description: "Poll until a terminal batch status (settled / partially_settled / failed) or timeout, emitting one NDJSON line per poll. Non-terminal states (authorizing/capturing, AUTHENTICATION_REQUIRED) keep polling \u2014 after the user finishes 3DS out-of-band, the next idempotent replay settles."
2278
+ },
2279
+ // watch 默认值与 pay-batch.ts 的 DEFAULT_PAY_BATCH_WATCH_* 常量一致;此处内联字面量
2280
+ // 以避免 verb-schema.ts ↔ pay-batch.ts 循环依赖(pay-batch.ts 反向依赖本模块的 schema)。
2281
+ "watch-interval": {
2282
+ type: "int",
2283
+ required: false,
2284
+ default: 5,
2285
+ description: "Seconds between polls when --watch is set"
2286
+ },
2287
+ "watch-timeout": {
2288
+ type: "int",
2289
+ required: false,
2290
+ default: 300,
2291
+ description: "Max seconds to poll before giving up"
2292
+ }
2293
+ },
2294
+ response: {
2295
+ payment_group_id: { type: "string", description: "The payment group this batch settled under (echoes --payment-group-id when supplied, else server-generated)." },
2296
+ status: { type: "string", description: "settled | partially_settled | failed | AUTHENTICATION_REQUIRED (3DS challenge body)." },
2297
+ currency: { type: "string", description: "ISO 4217 currency of the aggregate settlement (all orders share one currency)." },
2298
+ total_amount: { type: "float", description: "Aggregate total in DECIMAL units = sum of each order's authoritative price (computed by the platform, NOT sent by the caller)." },
2299
+ orders: {
2300
+ type: "array",
2301
+ description: "Per-order final result after upstream confirmation.",
2302
+ items: {
2303
+ order_id: { type: "string", description: "hho_/ffo_/rio_ order id." },
2304
+ status: { type: "string", description: "confirmed | refunded | failed." },
2305
+ amount: { type: "float", description: "That order's authoritative amount." },
2306
+ refunded_amount: { type: "float", description: "Amount refunded when upstream confirmation failed for this order." }
2307
+ }
2308
+ },
2309
+ three_ds_url: { type: "string", description: "[AUTHENTICATION_REQUIRED only] EVO 3DS challenge URL \u2014 complete out-of-band, then replay to settle." },
2310
+ merchant_trans_id: { type: "string", description: "[AUTHENTICATION_REQUIRED only] merchant trans id of the batch preauth." },
2311
+ amount: { type: "float", description: "[AUTHENTICATION_REQUIRED only] challenge amount = aggregate total." }
2312
+ },
2313
+ example: {
2314
+ command: "agenzo-merchant-cli orders pay-batch --order-ids hho_01K...,ffo_01K...,rio_01K... --payment-token-id ntk_01J2ABC --idempotency-key trip-pay-1",
2315
+ output_summary: "Settles all listed orders in one charge (banks/EVO see one transaction). Returns {payment_group_id, status, total_amount, currency, orders[]}. Use --watch to poll until settled / partially_settled / failed; upstream-confirmation-failed orders are refunded."
2316
+ },
2317
+ error_recovery: {
2318
+ PARAM_INVALID: "Fix --order-ids (a non-empty comma-separated list or JSON array of order ids) and ensure --idempotency-key is present, then retry.",
2319
+ ORDER_NOT_PAYABLE: "One of the order_ids is not in AWAITING_PAYMENT (the error names the specific order_id). Remove/replace it and retry with a NEW idempotency-key.",
2320
+ CURRENCY_MISMATCH: "The batch mixes currencies \u2014 orders in one pay-batch must share a single currency. Split by currency and settle each group separately.",
2321
+ TOKEN_ORDER_MISMATCH: "The token external_transaction_id is not bound to this payment_group. Mint a token for the aggregate total bound to THIS payment_group_id and retry; no funds moved.",
2322
+ AUTHENTICATION_REQUIRED: "EVO requires cardholder 3DS: open three_ds_url, finish authentication, then replay pay-batch with the SAME idempotency-key (or use --watch to poll automatically)."
2323
+ }
2324
+ };
2225
2325
  function flightSchema(verb, description, flags, response, example, extra = {}) {
2226
2326
  return { cli: CLI_NAME, noun: FLIGHT_NOUN, verb, description, flags, response, example, ...extra };
2227
2327
  }
@@ -3883,6 +3983,17 @@ function positiveInt2(value, flag) {
3883
3983
  }
3884
3984
  return String(n);
3885
3985
  }
3986
+ function assertCompatibleOptions(opts) {
3987
+ if (opts.orderType !== void 0 && opts.orderTypes !== void 0) {
3988
+ throw new CliError("PARAM_INVALID", "--order-type and --order-types cannot be used together.");
3989
+ }
3990
+ if (opts.status !== void 0 && opts.statuses !== void 0) {
3991
+ throw new CliError("PARAM_INVALID", "--status and --statuses cannot be used together.");
3992
+ }
3993
+ if (opts.cursor !== void 0 && Number(opts.page ?? DEFAULT_PAGE2) !== 1) {
3994
+ throw new CliError("PARAM_INVALID", "--cursor cannot be combined with --page greater than 1.");
3995
+ }
3996
+ }
3886
3997
  function formatOrders2(data) {
3887
3998
  const orders = data.orders ?? [];
3888
3999
  if (orders.length === 0) {
@@ -3901,14 +4012,17 @@ function formatOrders2(data) {
3901
4012
  ["Page", String(data.page ?? "-")],
3902
4013
  ["Page size", String(data.page_size ?? "-")]
3903
4014
  ];
4015
+ if (data.has_more !== void 0) summary.push(["Has more", String(data.has_more)]);
4016
+ if (data.next_cursor) summary.push(["Next cursor", data.next_cursor]);
3904
4017
  return `${Formatter.table(headers, rows)}
3905
4018
  ${Formatter.keyValue(summary)}`;
3906
4019
  }
3907
4020
  function registerOrdersListCommand(parent, deps) {
3908
- const cmd = parent.command("list").description("List orders across ALL providers (ride + hotel), with optional type/status filters").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-type <type>", "Filter by order type: ride | hotel").option("--status <status>", "Filter by normalized status: PENDING | CONFIRMED | COMPLETED | CANCELLED | FAILED").option("--page <page>", "Page number", DEFAULT_PAGE2).option("--page-size <size>", "Page size", DEFAULT_PAGE_SIZE2).option("--member <id>", MEMBER_OPTION_DESCRIPTION);
4021
+ const cmd = parent.command("list").description("List orders across ALL providers (ride + hotel + flight), with filters and pagination").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-type <type>", "Legacy single order type filter: ride | hotel | flight").option("--order-types <types>", "Comma-separated order types: ride,hotel,flight").option("--status <status>", "Legacy single normalized status filter").option("--statuses <statuses>", "Comma-separated statuses: PENDING,CONFIRMED,COMPLETED,CANCELLED,FAILED").option("--created-from <datetime>", "Created at or after this ISO 8601 datetime (inclusive)").option("--created-to <datetime>", "Created before this ISO 8601 datetime (exclusive)").option("--cursor <cursor>", "Opaque cursor returned by the previous page").option("--page <page>", "Legacy 1-based page number", DEFAULT_PAGE2).option("--page-size <size>", "Page size", DEFAULT_PAGE_SIZE2).option("--member <id>", MEMBER_OPTION_DESCRIPTION);
3909
4022
  attachSchemaHelp(cmd, unifiedOrdersListSchema);
3910
4023
  cmd.action(async () => {
3911
4024
  const opts = cmd.optsWithGlobals();
4025
+ assertCompatibleOptions(opts);
3912
4026
  const format = resolveFormat(opts.format);
3913
4027
  const apiKey = await PromptEngine.resolveInput(opts.apiKey, {
3914
4028
  message: "API Key:",
@@ -3919,7 +4033,12 @@ function registerOrdersListCommand(parent, deps) {
3919
4033
  page_size: positiveInt2(opts.pageSize ?? DEFAULT_PAGE_SIZE2, "page-size")
3920
4034
  };
3921
4035
  if (opts.orderType !== void 0) params.order_type = opts.orderType;
4036
+ if (opts.orderTypes !== void 0) params.order_types = opts.orderTypes;
3922
4037
  if (opts.status !== void 0) params.status = opts.status;
4038
+ if (opts.statuses !== void 0) params.statuses = opts.statuses;
4039
+ if (opts.createdFrom !== void 0) params.created_from = opts.createdFrom;
4040
+ if (opts.createdTo !== void 0) params.created_to = opts.createdTo;
4041
+ if (opts.cursor !== void 0) params.cursor = opts.cursor;
3923
4042
  const member = memberIdOf(opts);
3924
4043
  if (member !== void 0) params.member_id = member;
3925
4044
  const spinner = format === "json" ? null : createSpinner("Fetching orders...");
@@ -3944,7 +4063,7 @@ function registerOrdersListCommand(parent, deps) {
3944
4063
 
3945
4064
  // src/orders/get.ts
3946
4065
  function registerOrdersGetCommand(parent, deps) {
3947
- const cmd = parent.command("get").description("Get a single order detail by id, regardless of provider (ride/hotel)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").requiredOption("--order-id <id>", "Order id (e.g. rio_... or hho_...)");
4066
+ const cmd = parent.command("get").description("Get a single order detail by id, regardless of provider (ride/hotel/flight)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").requiredOption("--order-id <id>", "Order id (e.g. rio_..., hho_..., or ffo_...)");
3948
4067
  attachSchemaHelp(cmd, unifiedOrdersGetSchema);
3949
4068
  cmd.action(async () => {
3950
4069
  const opts = cmd.optsWithGlobals();
@@ -3974,15 +4093,201 @@ function registerOrdersGetCommand(parent, deps) {
3974
4093
  });
3975
4094
  }
3976
4095
 
3977
- // src/hotel-redaug/search.ts
4096
+ // src/orders/pay-batch.ts
4097
+ import { confirm as confirm6 } from "@inquirer/prompts";
4098
+ var DEFAULT_PAY_BATCH_WATCH_INTERVAL_SECONDS = 5;
4099
+ var DEFAULT_PAY_BATCH_WATCH_TIMEOUT_SECONDS = 300;
4100
+ var PAY_BATCH_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
4101
+ "settled",
4102
+ "partially_settled",
4103
+ "failed"
4104
+ ]);
4105
+ function parseOrderIds(raw) {
4106
+ const INVALID = '--order-ids must be a comma-separated list OR a JSON array of order ids (e.g. "hho_1,ffo_2,rio_3" or ["hho_1","ffo_2"]).';
4107
+ const trimmed = raw.trim();
4108
+ let ids;
4109
+ if (trimmed.startsWith("[")) {
4110
+ let parsed;
4111
+ try {
4112
+ parsed = JSON.parse(trimmed);
4113
+ } catch {
4114
+ throw new CliError("PARAM_INVALID", INVALID);
4115
+ }
4116
+ if (!Array.isArray(parsed)) {
4117
+ throw new CliError("PARAM_INVALID", INVALID);
4118
+ }
4119
+ if (!parsed.every((el) => typeof el === "string")) {
4120
+ throw new CliError("PARAM_INVALID", INVALID);
4121
+ }
4122
+ ids = parsed.map((s) => s.trim());
4123
+ } else {
4124
+ ids = trimmed.split(",").map((s) => s.trim());
4125
+ }
4126
+ ids = ids.filter((s) => s.length > 0);
4127
+ if (ids.length === 0) {
4128
+ throw new CliError("PARAM_INVALID", INVALID);
4129
+ }
4130
+ return ids;
4131
+ }
4132
+ function formatPayBatch(data) {
4133
+ const lines = [
4134
+ ["Payment group", String(data.payment_group_id ?? "-")],
4135
+ ["Status", String(data.status ?? "-")]
4136
+ ];
4137
+ if (data.total_amount != null && data.currency) {
4138
+ lines.push(["Total", `${data.total_amount} ${data.currency}`]);
4139
+ }
4140
+ if (data.status === "AUTHENTICATION_REQUIRED") {
4141
+ if (data.three_ds_url) lines.push(["3DS URL", String(data.three_ds_url)]);
4142
+ if (data.merchant_trans_id) lines.push(["Merchant trans ID", String(data.merchant_trans_id)]);
4143
+ if (data.amount != null && data.currency) {
4144
+ lines.push(["Challenge amount", `${data.amount} ${data.currency}`]);
4145
+ }
4146
+ }
4147
+ const out = [Formatter.keyValue(lines)];
4148
+ const perOrder = data.per_order ?? [];
4149
+ if (perOrder.length > 0) {
4150
+ const headers = ["Order ID", "Domain", "Status", "Amount", "Refunded"];
4151
+ const rows = perOrder.map((o) => [
4152
+ String(o.order_id ?? "-"),
4153
+ String(o.domain ?? "-"),
4154
+ String(o.status ?? "-"),
4155
+ String(o.amount ?? "-"),
4156
+ String(o.refunded_amount ?? "-")
4157
+ ]);
4158
+ out.push("", Formatter.table(headers, rows));
4159
+ }
4160
+ return out.join("\n");
4161
+ }
4162
+ function isBatchTerminal(record) {
4163
+ const status = record.status;
4164
+ return typeof status === "string" && PAY_BATCH_TERMINAL_STATUSES.has(status);
4165
+ }
4166
+ function registerOrdersPayBatchCommand(parent, deps) {
4167
+ const cmd = parent.command("pay-batch").description(
4168
+ "Settle a batch of orders (may mix ride/hotel/flight) in one aggregate payment via a single payment credential"
4169
+ ).option("--api-key <key>", "API Key for authentication (X-Api-Key)").option(
4170
+ "--order-ids <ids>",
4171
+ "Ordered order ids to settle together \u2014 comma-separated (hho_1,ffo_2,rio_3) or a JSON array. May mix hho_/ffo_/rio_ domains. Amounts come from each order's locked authoritative price (not passed here)."
4172
+ ).option(
4173
+ "--payment-token-id <id>",
4174
+ "[\u8F68 A] Network-token id minted for the aggregate total and bound to this payment_group (unionpay/visa charge path)"
4175
+ ).option(
4176
+ "--payment-method-id <id>",
4177
+ "[\u8F68 B] EVO bound-card id to settle the aggregate total (one 3DS challenge)"
4178
+ ).option(
4179
+ "--evo-explicit",
4180
+ "[\u8F68 B \u786C\u95E8\u69DB] Explicit opt-in to settle via the EVO bound-card rail. Set ONLY when the user explicitly chose EVO; forwarded to the body as evo_explicit=true."
4181
+ ).option(
4182
+ "--payment-group-id <id>",
4183
+ "Optional caller-pre-generated payment group id; omit to let the platform generate one"
4184
+ ).option("--member <id>", MEMBER_OPTION_DESCRIPTION).option(
4185
+ "--idempotency-key <key>",
4186
+ "Idempotency key forwarded verbatim as the Idempotency-Key header"
4187
+ ).option("--watch", "Poll until a terminal batch status or timeout (NDJSON output)", false).option(
4188
+ "--watch-interval <seconds>",
4189
+ "Seconds between polls when --watch is set",
4190
+ String(DEFAULT_PAY_BATCH_WATCH_INTERVAL_SECONDS)
4191
+ ).option(
4192
+ "--watch-timeout <seconds>",
4193
+ "Max seconds to poll before giving up",
4194
+ String(DEFAULT_PAY_BATCH_WATCH_TIMEOUT_SECONDS)
4195
+ );
4196
+ attachSchemaHelp(cmd, ordersPayBatchSchema);
4197
+ cmd.action(async () => {
4198
+ const opts = cmd.optsWithGlobals();
4199
+ const format = resolveFormat(opts.format);
4200
+ const isYes = Boolean(opts.yes);
4201
+ const apiKey = await PromptEngine.resolveInput(opts.apiKey, {
4202
+ message: "API Key:",
4203
+ type: "password"
4204
+ });
4205
+ const orderIds = parseOrderIds(need9(opts.orderIds, "order-ids"));
4206
+ const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
4207
+ yes: isYes,
4208
+ commandPath: "orders pay-batch"
4209
+ });
4210
+ const watchEnabled = Boolean(opts.watch);
4211
+ const watchInterval = resolveSeconds(opts.watchInterval, DEFAULT_PAY_BATCH_WATCH_INTERVAL_SECONDS);
4212
+ const watchTimeout = resolveSeconds(opts.watchTimeout, DEFAULT_PAY_BATCH_WATCH_TIMEOUT_SECONDS);
4213
+ const body = { order_ids: orderIds };
4214
+ if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
4215
+ if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
4216
+ if (opts.evoExplicit) body.evo_explicit = true;
4217
+ if (opts.paymentGroupId !== void 0) body.payment_group_id = opts.paymentGroupId;
4218
+ const member = memberIdOf(opts);
4219
+ if (member !== void 0) body.member_id = member;
4220
+ if (!isYes) {
4221
+ const confirmed = await confirm6({
4222
+ message: `Settle ${orderIds.length} order(s) in one aggregate payment? This moves money \u2014 a single charge covers the authoritative total of all listed orders (banks/EVO see one transaction).`,
4223
+ default: false
4224
+ });
4225
+ if (!confirmed) {
4226
+ throw new CliError("CLIENT_ABORTED", "Aggregate payment aborted by user.");
4227
+ }
4228
+ }
4229
+ const path = "/orders/pay-batch";
4230
+ const headers = { "Idempotency-Key": idempotencyKey };
4231
+ const auth = { type: "api-key", key: apiKey };
4232
+ if (!watchEnabled) {
4233
+ const spinner = format === "json" ? null : createSpinner("Settling order batch...");
4234
+ const result = await deps.apiClient.post(path, auth, body, headers);
4235
+ spinner?.stop();
4236
+ if (!result.success) {
4237
+ throw CliError.fromApi(result, { auth: "api-key" });
4238
+ }
4239
+ const data = result.data;
4240
+ const configManager = new ConfigManager();
4241
+ const commandResult = {
4242
+ data,
4243
+ text: () => formatPayBatch(data)
4244
+ };
4245
+ await renderWithContext(commandResult, { format }, configManager);
4246
+ } else {
4247
+ const deadline = Date.now() + watchTimeout * 1e3;
4248
+ let lastRecord = null;
4249
+ for (; ; ) {
4250
+ const result = await deps.apiClient.post(path, auth, body, headers);
4251
+ if (result.success) {
4252
+ const data = result.data;
4253
+ lastRecord = data;
4254
+ ndjsonWriteLine(data);
4255
+ if (isBatchTerminal(data)) {
4256
+ return;
4257
+ }
4258
+ } else {
4259
+ throw CliError.fromApi(result, { auth: "api-key" });
4260
+ }
4261
+ if (Date.now() + watchInterval * 1e3 >= deadline) {
4262
+ const timeoutLine = {
4263
+ watch_status: "timeout",
4264
+ message: `Polling stopped after ${watchTimeout}s without reaching a terminal batch status.`,
4265
+ last_status: lastRecord
4266
+ };
4267
+ ndjsonWriteLine(timeoutLine);
4268
+ return;
4269
+ }
4270
+ await realSleep(watchInterval * 1e3);
4271
+ }
4272
+ }
4273
+ });
4274
+ }
3978
4275
  function need9(value, flag) {
3979
4276
  if (value === void 0) {
3980
4277
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
3981
4278
  }
3982
4279
  return value;
3983
4280
  }
4281
+
4282
+ // src/hotel-redaug/search.ts
4283
+ function need10(value, flag) {
4284
+ if (value === void 0) {
4285
+ throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4286
+ }
4287
+ return value;
4288
+ }
3984
4289
  function num5(value, flag) {
3985
- const n = Number(need9(value, flag));
4290
+ const n = Number(need10(value, flag));
3986
4291
  if (!Number.isFinite(n)) {
3987
4292
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
3988
4293
  }
@@ -4004,7 +4309,7 @@ function positiveInt3(value, flag) {
4004
4309
  }
4005
4310
  var YMD_RE = /^\d{4}-\d{2}-\d{2}$/;
4006
4311
  function stayDate(value, flag) {
4007
- const raw = need9(value, flag);
4312
+ const raw = need10(value, flag);
4008
4313
  if (!YMD_RE.test(raw)) {
4009
4314
  throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
4010
4315
  }
@@ -4076,7 +4381,7 @@ function registerHotelSearchCommand(parent, deps) {
4076
4381
  const pageSize = positiveInt3(opts.pageSize, "page-size");
4077
4382
  const body = {};
4078
4383
  if (hasDestination) {
4079
- body.destination_id = need9(opts.destinationId, "destination-id");
4384
+ body.destination_id = need10(opts.destinationId, "destination-id");
4080
4385
  } else {
4081
4386
  body.lat = coord(opts.lat, "lat", -90, 90);
4082
4387
  body.lng = coord(opts.lng, "lng", -180, 180);
@@ -4119,14 +4424,14 @@ function registerHotelSearchCommand(parent, deps) {
4119
4424
  }
4120
4425
 
4121
4426
  // src/hotel-redaug/quote.ts
4122
- function need10(value, flag) {
4427
+ function need11(value, flag) {
4123
4428
  if (value === void 0) {
4124
4429
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4125
4430
  }
4126
4431
  return value;
4127
4432
  }
4128
4433
  function num6(value, flag) {
4129
- const n = Number(need10(value, flag));
4434
+ const n = Number(need11(value, flag));
4130
4435
  if (!Number.isFinite(n)) {
4131
4436
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
4132
4437
  }
@@ -4134,7 +4439,7 @@ function num6(value, flag) {
4134
4439
  }
4135
4440
  var YMD_RE2 = /^\d{4}-\d{2}-\d{2}$/;
4136
4441
  function stayDate2(value, flag) {
4137
- const raw = need10(value, flag);
4442
+ const raw = need11(value, flag);
4138
4443
  if (!YMD_RE2.test(raw)) {
4139
4444
  throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
4140
4445
  }
@@ -4174,7 +4479,7 @@ function registerHotelQuoteCommand(parent, deps) {
4174
4479
  message: "API Key:",
4175
4480
  type: "password"
4176
4481
  });
4177
- const hotelId = need10(opts.hotelId, "hotel-id");
4482
+ const hotelId = need11(opts.hotelId, "hotel-id");
4178
4483
  const checkIn = stayDate2(opts.checkIn, "check-in");
4179
4484
  const checkOut = stayDate2(opts.checkOut, "check-out");
4180
4485
  if (!(checkOut > checkIn)) {
@@ -4208,7 +4513,7 @@ function registerHotelQuoteCommand(parent, deps) {
4208
4513
  }
4209
4514
 
4210
4515
  // src/hotel-redaug/create-order.ts
4211
- import { confirm as confirm6 } from "@inquirer/prompts";
4516
+ import { confirm as confirm7 } from "@inquirer/prompts";
4212
4517
  function parsePriceItems(raw) {
4213
4518
  const INVALID = "--price-items must be a JSON array of {sale_date (string), sale_price (number), breakfast_num (number)}.";
4214
4519
  let parsed;
@@ -4266,14 +4571,14 @@ function parseCancellation(raw) {
4266
4571
  }
4267
4572
  return parsed;
4268
4573
  }
4269
- function need11(value, flag) {
4574
+ function need12(value, flag) {
4270
4575
  if (value === void 0) {
4271
4576
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4272
4577
  }
4273
4578
  return value;
4274
4579
  }
4275
4580
  function num7(value, flag) {
4276
- const n = Number(need11(value, flag));
4581
+ const n = Number(need12(value, flag));
4277
4582
  if (!Number.isFinite(n)) {
4278
4583
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
4279
4584
  }
@@ -4281,7 +4586,7 @@ function num7(value, flag) {
4281
4586
  }
4282
4587
  var YMD_RE3 = /^\d{4}-\d{2}-\d{2}$/;
4283
4588
  function stayDate3(value, flag) {
4284
- const raw = need11(value, flag);
4589
+ const raw = need12(value, flag);
4285
4590
  if (!YMD_RE3.test(raw)) {
4286
4591
  throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
4287
4592
  }
@@ -4350,18 +4655,18 @@ function registerHotelCreateOrderCommand(parent, deps) {
4350
4655
  message: "API Key:",
4351
4656
  type: "password"
4352
4657
  });
4353
- const productToken = need11(opts.productToken, "product-token");
4658
+ const productToken = need12(opts.productToken, "product-token");
4354
4659
  const totalAmount = num7(opts.totalAmount, "total-amount");
4355
- const currency = need11(opts.currency, "currency");
4356
- const priceItems = parsePriceItems(need11(opts.priceItems, "price-items"));
4660
+ const currency = need12(opts.currency, "currency");
4661
+ const priceItems = parsePriceItems(need12(opts.priceItems, "price-items"));
4357
4662
  const checkIn = stayDate3(opts.checkIn, "check-in");
4358
4663
  const checkOut = stayDate3(opts.checkOut, "check-out");
4359
4664
  if (!(checkOut > checkIn)) {
4360
4665
  throw new CliError("PARAM_INVALID", "--check-out must be strictly after --check-in.");
4361
4666
  }
4362
- const guestName = need11(opts.guestName, "guest-name");
4363
- const contactName = need11(opts.contactName, "contact-name");
4364
- const contactPhone = need11(opts.contactPhone, "contact-phone");
4667
+ const guestName = need12(opts.guestName, "guest-name");
4668
+ const contactName = need12(opts.contactName, "contact-name");
4669
+ const contactPhone = need12(opts.contactPhone, "contact-phone");
4365
4670
  const body = {
4366
4671
  product_token: productToken,
4367
4672
  total_amount: totalAmount,
@@ -4395,7 +4700,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
4395
4700
  if (member !== void 0) body.member_id = member;
4396
4701
  if (!isYes) {
4397
4702
  const chargeNote = opts.paymentTokenId !== void 0 ? "Payment has already been captured via UPI Agent Pay; this only locks the room." : "This locks the rate but does NOT charge anything yet.";
4398
- const confirmed = await confirm6({
4703
+ const confirmed = await confirm7({
4399
4704
  message: `Create this hotel order for ${totalAmount} ${currency} (check-in ${checkIn}, check-out ${checkOut})? ${chargeNote}`,
4400
4705
  default: false
4401
4706
  });
@@ -4429,7 +4734,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
4429
4734
  }
4430
4735
 
4431
4736
  // src/hotel-redaug/pay-order.ts
4432
- import { confirm as confirm7 } from "@inquirer/prompts";
4737
+ import { confirm as confirm8 } from "@inquirer/prompts";
4433
4738
 
4434
4739
  // src/hotel-redaug/watch.ts
4435
4740
  var DEFAULT_ORDER_WATCH_INTERVAL_SECONDS = 5;
@@ -4617,7 +4922,7 @@ function registerHotelPayOrderCommand(parent, deps) {
4617
4922
  }
4618
4923
  if (opts.evoExplicit) body.evo_explicit = true;
4619
4924
  if (!isYes) {
4620
- const confirmed = await confirm7({
4925
+ const confirmed = await confirm8({
4621
4926
  message: `Settle hotel order ${orderId}? This moves money via the order's configured billing mode (monthly_settlement or pay_per_call).`,
4622
4927
  default: false
4623
4928
  });
@@ -4695,7 +5000,7 @@ function registerHotelPayOrderCommand(parent, deps) {
4695
5000
  }
4696
5001
 
4697
5002
  // src/hotel-redaug/get.ts
4698
- function need12(value, flag) {
5003
+ function need13(value, flag) {
4699
5004
  if (value === void 0) {
4700
5005
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4701
5006
  }
@@ -4759,7 +5064,7 @@ function registerHotelGetCommand(parent, deps) {
4759
5064
  message: "API Key:",
4760
5065
  type: "password"
4761
5066
  });
4762
- const orderId = need12(opts.orderId, "order-id");
5067
+ const orderId = need13(opts.orderId, "order-id");
4763
5068
  if (opts.watch) {
4764
5069
  await watchOrderStatus(deps.apiClient, apiKey, orderId, {
4765
5070
  intervalSeconds: resolveSeconds(
@@ -4793,7 +5098,7 @@ function registerHotelGetCommand(parent, deps) {
4793
5098
  }
4794
5099
 
4795
5100
  // src/hotel-redaug/cancel.ts
4796
- function need13(value, flag) {
5101
+ function need14(value, flag) {
4797
5102
  if (value === void 0) {
4798
5103
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4799
5104
  }
@@ -4846,8 +5151,8 @@ function registerHotelCancelCommand(parent, deps) {
4846
5151
  message: "API Key:",
4847
5152
  type: "password"
4848
5153
  });
4849
- const orderId = need13(opts.orderId, "order-id");
4850
- const fcOrderCode = need13(opts.fcOrderCode, "fc-order-code");
5154
+ const orderId = need14(opts.orderId, "order-id");
5155
+ const fcOrderCode = need14(opts.fcOrderCode, "fc-order-code");
4851
5156
  const body = { fc_order_code: fcOrderCode };
4852
5157
  if (opts.reason !== void 0) body.reason = opts.reason;
4853
5158
  const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
@@ -4876,15 +5181,15 @@ function registerHotelCancelCommand(parent, deps) {
4876
5181
  }
4877
5182
 
4878
5183
  // src/hotel-redaug/checkout.ts
4879
- import { confirm as confirm8 } from "@inquirer/prompts";
4880
- function need14(value, flag) {
5184
+ import { confirm as confirm9 } from "@inquirer/prompts";
5185
+ function need15(value, flag) {
4881
5186
  if (value === void 0) {
4882
5187
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4883
5188
  }
4884
5189
  return value;
4885
5190
  }
4886
5191
  function num8(value, flag) {
4887
- const n = Number(need14(value, flag));
5192
+ const n = Number(need15(value, flag));
4888
5193
  if (!Number.isFinite(n)) {
4889
5194
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
4890
5195
  }
@@ -4950,10 +5255,10 @@ function registerHotelCheckoutCommand(parent, deps) {
4950
5255
  message: "API Key:",
4951
5256
  type: "password"
4952
5257
  });
4953
- const orderId = need14(opts.orderId, "order-id");
4954
- const fcOrderCode = need14(opts.fcOrderCode, "fc-order-code");
4955
- const reason = need14(opts.reason, "reason");
4956
- const checkoutRooms = parseCheckoutRooms(need14(opts.checkoutRooms, "checkout-rooms"));
5258
+ const orderId = need15(opts.orderId, "order-id");
5259
+ const fcOrderCode = need15(opts.fcOrderCode, "fc-order-code");
5260
+ const reason = need15(opts.reason, "reason");
5261
+ const checkoutRooms = parseCheckoutRooms(need15(opts.checkoutRooms, "checkout-rooms"));
4957
5262
  const refundType = num8(opts.refundType, "refund-type");
4958
5263
  const body = {
4959
5264
  fc_order_code: fcOrderCode,
@@ -4962,7 +5267,7 @@ function registerHotelCheckoutCommand(parent, deps) {
4962
5267
  checkout_rooms: checkoutRooms
4963
5268
  };
4964
5269
  if (!isYes) {
4965
- const confirmed = await confirm8({
5270
+ const confirmed = await confirm9({
4966
5271
  message: `Request check-out / out-of-policy cancellation for order ${orderId} (${checkoutRooms.length} room(s))? The property must approve and charges may apply.`,
4967
5272
  default: false
4968
5273
  });
@@ -4996,7 +5301,7 @@ function registerHotelCheckoutCommand(parent, deps) {
4996
5301
  }
4997
5302
 
4998
5303
  // src/hotel-redaug/get-checkout.ts
4999
- function need15(value, flag) {
5304
+ function need16(value, flag) {
5000
5305
  if (value === void 0) {
5001
5306
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5002
5307
  }
@@ -5032,7 +5337,7 @@ function registerHotelGetCheckoutCommand(parent, deps) {
5032
5337
  message: "API Key:",
5033
5338
  type: "password"
5034
5339
  });
5035
- const taskOrderCode = need15(opts.taskOrderCode, "task-order-code");
5340
+ const taskOrderCode = need16(opts.taskOrderCode, "task-order-code");
5036
5341
  if (opts.watch) {
5037
5342
  await watchCheckoutStatus(deps.apiClient, apiKey, taskOrderCode, {
5038
5343
  intervalSeconds: resolveSeconds(
@@ -5136,7 +5441,7 @@ function registerHotelListOrdersCommand(parent, deps) {
5136
5441
  }
5137
5442
 
5138
5443
  // src/hotel-redaug/find-destination.ts
5139
- function need16(value, flag) {
5444
+ function need17(value, flag) {
5140
5445
  if (value === void 0 || value.trim() === "") {
5141
5446
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5142
5447
  }
@@ -5170,7 +5475,7 @@ function registerHotelFindDestinationCommand(parent, deps) {
5170
5475
  message: "API Key:",
5171
5476
  type: "password"
5172
5477
  });
5173
- const keyword = need16(opts.keyword, "keyword");
5478
+ const keyword = need17(opts.keyword, "keyword");
5174
5479
  const body = { keyword };
5175
5480
  if (opts.dataType !== void 0) {
5176
5481
  body.data_type = opts.dataType;
@@ -5194,14 +5499,14 @@ function registerHotelFindDestinationCommand(parent, deps) {
5194
5499
  }
5195
5500
 
5196
5501
  // src/hotel-redaug/hotel-filters.ts
5197
- function need17(value, flag) {
5502
+ function need18(value, flag) {
5198
5503
  if (value === void 0 || value.trim() === "") {
5199
5504
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5200
5505
  }
5201
5506
  return value;
5202
5507
  }
5203
5508
  function num9(value, flag) {
5204
- const n = Number(need17(value, flag));
5509
+ const n = Number(need18(value, flag));
5205
5510
  if (!Number.isFinite(n)) {
5206
5511
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
5207
5512
  }
@@ -5281,7 +5586,7 @@ function registerHotelFiltersCommand(parent, deps) {
5281
5586
  }
5282
5587
  const body = {};
5283
5588
  if (hasDestination) {
5284
- body.destination_id = need17(opts.destinationId, "destination-id");
5589
+ body.destination_id = need18(opts.destinationId, "destination-id");
5285
5590
  } else {
5286
5591
  body.lat = coord2(opts.lat, "lat", -90, 90);
5287
5592
  body.lng = coord2(opts.lng, "lng", -180, 180);
@@ -5306,7 +5611,7 @@ function registerHotelFiltersCommand(parent, deps) {
5306
5611
  }
5307
5612
 
5308
5613
  // src/hotel-redaug/list-cities.ts
5309
- function need18(value, flag) {
5614
+ function need19(value, flag) {
5310
5615
  if (value === void 0 || value.trim() === "") {
5311
5616
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5312
5617
  }
@@ -5339,7 +5644,7 @@ function registerHotelListCitiesCommand(parent, deps) {
5339
5644
  message: "API Key:",
5340
5645
  type: "password"
5341
5646
  });
5342
- const country = need18(opts.country, "country");
5647
+ const country = need19(opts.country, "country");
5343
5648
  const body = { country_code: country };
5344
5649
  const result = await deps.apiClient.post(
5345
5650
  "/hotel/cities",
@@ -5360,7 +5665,7 @@ function registerHotelListCitiesCommand(parent, deps) {
5360
5665
  }
5361
5666
 
5362
5667
  // src/hotel-redaug/hotel-detail.ts
5363
- function need19(value, flag) {
5668
+ function need20(value, flag) {
5364
5669
  if (value === void 0 || value.trim() === "") {
5365
5670
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5366
5671
  }
@@ -5507,7 +5812,7 @@ function registerHotelDetailCommand(parent, deps) {
5507
5812
  message: "API Key:",
5508
5813
  type: "password"
5509
5814
  });
5510
- const hotelId = need19(opts.hotelId, "hotel-id");
5815
+ const hotelId = need20(opts.hotelId, "hotel-id");
5511
5816
  const rawWithImages = opts.withImages;
5512
5817
  const withImages = rawWithImages !== "false" && rawWithImages !== false;
5513
5818
  const settings = parseSettings(opts.settings);
@@ -5715,14 +6020,14 @@ function registerHotelSkillCommand(parent) {
5715
6020
  }
5716
6021
 
5717
6022
  // src/flight-flink/_helpers.ts
5718
- function need20(value, flag) {
6023
+ function need21(value, flag) {
5719
6024
  if (value === void 0) {
5720
6025
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5721
6026
  }
5722
6027
  return value;
5723
6028
  }
5724
6029
  function num10(value, flag) {
5725
- const n = Number(need20(value, flag));
6030
+ const n = Number(need21(value, flag));
5726
6031
  if (!Number.isFinite(n)) {
5727
6032
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
5728
6033
  }
@@ -5757,7 +6062,7 @@ function registerFindAirportCommand(parent, deps) {
5757
6062
  const opts = cmd.optsWithGlobals();
5758
6063
  const format = resolveFormat(opts.format);
5759
6064
  const apiKey = await resolveApiKey(opts.apiKey);
5760
- const keyword = need20(opts.keyword, "keyword");
6065
+ const keyword = need21(opts.keyword, "keyword");
5761
6066
  const spinner = format === "json" ? null : createSpinner("Resolving airports...");
5762
6067
  const result = await deps.apiClient.post(
5763
6068
  "/flight/find-airport",
@@ -5854,7 +6159,7 @@ function registerSearchCommand(parent, deps) {
5854
6159
  const apiKey = await resolveApiKey(opts.apiKey);
5855
6160
  const body = {
5856
6161
  trip_type: num10(opts.tripType, "trip-type"),
5857
- journeys: jsonArray(need20(opts.journeys, "journeys"), "journeys"),
6162
+ journeys: jsonArray(need21(opts.journeys, "journeys"), "journeys"),
5858
6163
  cabin_class: opts.cabinClass,
5859
6164
  adult_num: num10(opts.adultNum, "adult-num"),
5860
6165
  child_num: num10(opts.childNum, "child-num"),
@@ -5885,7 +6190,7 @@ function registerMoreOffersCommand(parent, deps) {
5885
6190
  const opts = cmd.optsWithGlobals();
5886
6191
  const format = resolveFormat(opts.format);
5887
6192
  const apiKey = await resolveApiKey(opts.apiKey);
5888
- const productToken = need20(opts.productToken, "product-token");
6193
+ const productToken = need21(opts.productToken, "product-token");
5889
6194
  const spinner = format === "json" ? null : createSpinner("Fetching offers...");
5890
6195
  const result = await deps.apiClient.post(
5891
6196
  "/flight/more-offers",
@@ -5906,7 +6211,7 @@ function registerVerifyCommand(parent, deps) {
5906
6211
  const opts = cmd.optsWithGlobals();
5907
6212
  const format = resolveFormat(opts.format);
5908
6213
  const apiKey = await resolveApiKey(opts.apiKey);
5909
- const productToken = need20(opts.productToken, "product-token");
6214
+ const productToken = need21(opts.productToken, "product-token");
5910
6215
  const spinner = format === "json" ? null : createSpinner("Verifying price...");
5911
6216
  const result = await deps.apiClient.post(
5912
6217
  "/flight/verify",
@@ -5928,7 +6233,7 @@ function registerVerifyCommand(parent, deps) {
5928
6233
  }
5929
6234
 
5930
6235
  // src/flight-flink/create-order.ts
5931
- import { confirm as confirm9 } from "@inquirer/prompts";
6236
+ import { confirm as confirm10 } from "@inquirer/prompts";
5932
6237
  function registerCreateOrderCommand(parent, deps) {
5933
6238
  const cmd = parent.command("create-order").description("Create a flight order without charging (locks the fare, await payment)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--product-token <token>", "Authoritative rate token from verify").option("--total-amount <amount>", "Verified total price in decimal units").option("--currency <currency>", "ISO 4217 currency code").option("--trip-type <n>", "1/2/3", "1").option("--contact-name <name>", "Booking contact name").option("--contact-region <code>", "Contact phone country code (no '+')").option("--contact-phone <phone>", "Booking contact phone").option("--contact-email <email>", "Booking contact email").option("--passengers <json>", "JSON array of passengers (gender/id_type are strings)").option("--payment-method-id <id>", "Optional bound-card id (pay_per_call only)").option("--payment-token-id <id>", "Optional UPI network-token id (unionpay charge path)").option(
5934
6239
  "--authorized-merchant-trans-id <id>",
@@ -5940,19 +6245,19 @@ function registerCreateOrderCommand(parent, deps) {
5940
6245
  const format = resolveFormat(opts.format);
5941
6246
  const isYes = Boolean(opts.yes);
5942
6247
  const apiKey = await resolveApiKey(opts.apiKey);
5943
- const productToken = need20(opts.productToken, "product-token");
6248
+ const productToken = need21(opts.productToken, "product-token");
5944
6249
  const totalAmount = num10(opts.totalAmount, "total-amount");
5945
- const currency = need20(opts.currency, "currency");
6250
+ const currency = need21(opts.currency, "currency");
5946
6251
  const body = {
5947
6252
  product_token: productToken,
5948
6253
  total_amount: totalAmount,
5949
6254
  currency,
5950
6255
  trip_type: num10(opts.tripType, "trip-type"),
5951
- contact_name: need20(opts.contactName, "contact-name"),
5952
- contact_region: need20(opts.contactRegion, "contact-region"),
5953
- contact_phone: need20(opts.contactPhone, "contact-phone"),
5954
- contact_email: need20(opts.contactEmail, "contact-email"),
5955
- passengers: jsonArray(need20(opts.passengers, "passengers"), "passengers")
6256
+ contact_name: need21(opts.contactName, "contact-name"),
6257
+ contact_region: need21(opts.contactRegion, "contact-region"),
6258
+ contact_phone: need21(opts.contactPhone, "contact-phone"),
6259
+ contact_email: need21(opts.contactEmail, "contact-email"),
6260
+ passengers: jsonArray(need21(opts.passengers, "passengers"), "passengers")
5956
6261
  };
5957
6262
  if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
5958
6263
  if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
@@ -5962,7 +6267,7 @@ function registerCreateOrderCommand(parent, deps) {
5962
6267
  const member = memberIdOf(opts);
5963
6268
  if (member !== void 0) body.member_id = member;
5964
6269
  if (!isYes) {
5965
- const ok = await confirm9({
6270
+ const ok = await confirm10({
5966
6271
  message: `Create this flight order for ${totalAmount} ${currency}? This locks the fare but does NOT charge yet.`,
5967
6272
  default: false
5968
6273
  });
@@ -6001,7 +6306,7 @@ function registerCreateOrderCommand(parent, deps) {
6001
6306
  }
6002
6307
 
6003
6308
  // src/flight-flink/pay-order.ts
6004
- import { confirm as confirm10 } from "@inquirer/prompts";
6309
+ import { confirm as confirm11 } from "@inquirer/prompts";
6005
6310
  function registerPayOrderCommand(parent, deps) {
6006
6311
  const cmd = parent.command("pay-order").description("Settle a created order by --order-no (triggers ticketing)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-no <id>", "Our order reference from create-order").option("--payment-method-id <id>", "Optional bound-card id to charge (pay_per_call only)").option("--payment-token-id <id>", "Optional network-token id (unionpay/visa charge path)").option(
6007
6312
  "--authorized-merchant-trans-id <id>",
@@ -6016,9 +6321,9 @@ function registerPayOrderCommand(parent, deps) {
6016
6321
  const format = resolveFormat(opts.format);
6017
6322
  const isYes = Boolean(opts.yes);
6018
6323
  const apiKey = await resolveApiKey(opts.apiKey);
6019
- const orderNo = need20(opts.orderNo, "order-no");
6324
+ const orderNo = need21(opts.orderNo, "order-no");
6020
6325
  if (!isYes) {
6021
- const ok = await confirm10({
6326
+ const ok = await confirm11({
6022
6327
  message: `Pay and ticket order ${orderNo}? This settles the order and issues tickets.`,
6023
6328
  default: false
6024
6329
  });
@@ -6068,7 +6373,7 @@ function registerGetOrderCommand(parent, deps) {
6068
6373
  const opts = cmd.optsWithGlobals();
6069
6374
  const format = resolveFormat(opts.format);
6070
6375
  const apiKey = await resolveApiKey(opts.apiKey);
6071
- const orderNo = need20(opts.orderNo, "order-no");
6376
+ const orderNo = need21(opts.orderNo, "order-no");
6072
6377
  const path = `/flight/${encodeURIComponent(orderNo)}/status`;
6073
6378
  const auth = { type: "api-key", key: apiKey };
6074
6379
  if (opts.watch) {
@@ -6108,7 +6413,7 @@ function registerGetOrderCommand(parent, deps) {
6108
6413
  }
6109
6414
 
6110
6415
  // src/flight-flink/cancel-order.ts
6111
- import { confirm as confirm11 } from "@inquirer/prompts";
6416
+ import { confirm as confirm12 } from "@inquirer/prompts";
6112
6417
  function registerCancelOrderCommand(parent, deps) {
6113
6418
  const cmd = parent.command("cancel-order").description("Cancel an un-ticketed flight order (with refund)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-no <id>", "Our order reference").option("--reason <text>", "Optional cancellation reason").option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
6114
6419
  attachSchemaHelp(cmd, flightCancelOrderSchema);
@@ -6117,9 +6422,9 @@ function registerCancelOrderCommand(parent, deps) {
6117
6422
  const format = resolveFormat(opts.format);
6118
6423
  const isYes = Boolean(opts.yes);
6119
6424
  const apiKey = await resolveApiKey(opts.apiKey);
6120
- const orderNo = need20(opts.orderNo, "order-no");
6425
+ const orderNo = need21(opts.orderNo, "order-no");
6121
6426
  if (!isYes) {
6122
- const ok = await confirm11({
6427
+ const ok = await confirm12({
6123
6428
  message: `Cancel order ${orderNo}? This requests cancellation and a refund.`,
6124
6429
  default: false
6125
6430
  });
@@ -6193,10 +6498,10 @@ function registerChangeSearchCommand(parent, deps) {
6193
6498
  const format = resolveFormat(opts.format);
6194
6499
  const apiKey = await resolveApiKey(opts.apiKey);
6195
6500
  const body = {
6196
- order_no: need20(opts.orderNo, "order-no"),
6197
- date: need20(opts.date, "date"),
6198
- passenger: need20(opts.passenger, "passenger"),
6199
- segment_id: need20(opts.segmentId, "segment-id"),
6501
+ order_no: need21(opts.orderNo, "order-no"),
6502
+ date: need21(opts.date, "date"),
6503
+ passenger: need21(opts.passenger, "passenger"),
6504
+ segment_id: need21(opts.segmentId, "segment-id"),
6200
6505
  cabin_class: opts.cabinClass
6201
6506
  };
6202
6507
  const spinner = format === "json" ? null : createSpinner("Searching change options...");
@@ -6212,7 +6517,7 @@ function registerChangeSearchCommand(parent, deps) {
6212
6517
  }
6213
6518
 
6214
6519
  // src/flight-flink/change-apply.ts
6215
- import { confirm as confirm12 } from "@inquirer/prompts";
6520
+ import { confirm as confirm13 } from "@inquirer/prompts";
6216
6521
  function registerChangeApplyCommand(parent, deps) {
6217
6522
  const cmd = parent.command("change-apply").description("Submit a change request (returns change_order_no, pending review)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-no <id>", "Our order reference").option("--passenger <code>", "passengerCode").option("--segment-id <ids>", "Comma-separated segment ids").option("--product-token <token>", "Change priceKey token").option("--contact-name <name>", "Contact name").option("--contact-region <code>", "Contact region").option("--contact-phone <phone>", "Contact phone").option("--contact-email <email>", "Contact email").option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
6218
6523
  attachSchemaHelp(cmd, flightChangeApplySchema);
@@ -6222,17 +6527,17 @@ function registerChangeApplyCommand(parent, deps) {
6222
6527
  const isYes = Boolean(opts.yes);
6223
6528
  const apiKey = await resolveApiKey(opts.apiKey);
6224
6529
  const body = {
6225
- order_no: need20(opts.orderNo, "order-no"),
6226
- passenger: need20(opts.passenger, "passenger"),
6227
- segment_id: need20(opts.segmentId, "segment-id"),
6228
- product_token: need20(opts.productToken, "product-token"),
6229
- contact_name: need20(opts.contactName, "contact-name"),
6230
- contact_region: need20(opts.contactRegion, "contact-region"),
6231
- contact_phone: need20(opts.contactPhone, "contact-phone"),
6232
- contact_email: need20(opts.contactEmail, "contact-email")
6530
+ order_no: need21(opts.orderNo, "order-no"),
6531
+ passenger: need21(opts.passenger, "passenger"),
6532
+ segment_id: need21(opts.segmentId, "segment-id"),
6533
+ product_token: need21(opts.productToken, "product-token"),
6534
+ contact_name: need21(opts.contactName, "contact-name"),
6535
+ contact_region: need21(opts.contactRegion, "contact-region"),
6536
+ contact_phone: need21(opts.contactPhone, "contact-phone"),
6537
+ contact_email: need21(opts.contactEmail, "contact-email")
6233
6538
  };
6234
6539
  if (!isYes) {
6235
- const ok = await confirm12({
6540
+ const ok = await confirm13({
6236
6541
  message: `Submit a change request for order ${body.order_no}?`,
6237
6542
  default: false
6238
6543
  });
@@ -6263,7 +6568,7 @@ function registerChangeDetailCommand(parent, deps) {
6263
6568
  const opts = cmd.optsWithGlobals();
6264
6569
  const format = resolveFormat(opts.format);
6265
6570
  const apiKey = await resolveApiKey(opts.apiKey);
6266
- const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
6571
+ const changeOrderNo = need21(opts.changeOrderNo, "change-order-no");
6267
6572
  const spinner = format === "json" ? null : createSpinner("Fetching change detail...");
6268
6573
  const result = await deps.apiClient.get(
6269
6574
  `/flight/change/${encodeURIComponent(changeOrderNo)}`,
@@ -6276,7 +6581,7 @@ function registerChangeDetailCommand(parent, deps) {
6276
6581
  }
6277
6582
 
6278
6583
  // src/flight-flink/change-cancel.ts
6279
- import { confirm as confirm13 } from "@inquirer/prompts";
6584
+ import { confirm as confirm14 } from "@inquirer/prompts";
6280
6585
  function registerChangeCancelCommand(parent, deps) {
6281
6586
  const cmd = parent.command("change-cancel").description("Cancel a change request (immediate terminal)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--change-order-no <id>", "Change order number").option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
6282
6587
  attachSchemaHelp(cmd, flightChangeCancelSchema);
@@ -6285,9 +6590,9 @@ function registerChangeCancelCommand(parent, deps) {
6285
6590
  const format = resolveFormat(opts.format);
6286
6591
  const isYes = Boolean(opts.yes);
6287
6592
  const apiKey = await resolveApiKey(opts.apiKey);
6288
- const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
6593
+ const changeOrderNo = need21(opts.changeOrderNo, "change-order-no");
6289
6594
  if (!isYes) {
6290
- const ok = await confirm13({ message: `Cancel change request ${changeOrderNo}?`, default: false });
6595
+ const ok = await confirm14({ message: `Cancel change request ${changeOrderNo}?`, default: false });
6291
6596
  if (!ok) throw new CliError("CLIENT_ABORTED", "Change cancellation aborted by user.");
6292
6597
  }
6293
6598
  const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
@@ -6308,7 +6613,7 @@ function registerChangeCancelCommand(parent, deps) {
6308
6613
  }
6309
6614
 
6310
6615
  // src/flight-flink/change-pay.ts
6311
- import { confirm as confirm14 } from "@inquirer/prompts";
6616
+ import { confirm as confirm15 } from "@inquirer/prompts";
6312
6617
  function registerChangePayCommand(parent, deps) {
6313
6618
  const cmd = parent.command("change-pay").description("Pay a change request fee (like a normal order) and trigger change ticketing").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--change-order-no <id>", "Change order number").option("--order-no <id>", "Original order reference (ownership check)").option("--amount <amount>", "Change fee total in decimal units (change-detail price_total)").option("--currency <currency>", "ISO 4217 currency code", "USD").option("--payment-method-id <id>", "Optional bound-card id (EVO path)").option("--payment-token-id <id>", "Optional UPI network-token id (unionpay charge path)").option(
6314
6619
  "--authorized-merchant-trans-id <id>",
@@ -6320,10 +6625,10 @@ function registerChangePayCommand(parent, deps) {
6320
6625
  const format = resolveFormat(opts.format);
6321
6626
  const isYes = Boolean(opts.yes);
6322
6627
  const apiKey = await resolveApiKey(opts.apiKey);
6323
- const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
6324
- const orderNo = need20(opts.orderNo, "order-no");
6628
+ const changeOrderNo = need21(opts.changeOrderNo, "change-order-no");
6629
+ const orderNo = need21(opts.orderNo, "order-no");
6325
6630
  const amount = num10(opts.amount, "amount");
6326
- const currency = need20(opts.currency, "currency");
6631
+ const currency = need21(opts.currency, "currency");
6327
6632
  const body = {
6328
6633
  order_no: orderNo,
6329
6634
  amount,
@@ -6337,7 +6642,7 @@ function registerChangePayCommand(parent, deps) {
6337
6642
  if (!isYes) {
6338
6643
  const isResume = opts.authorizedMerchantTransId !== void 0;
6339
6644
  const message = isResume ? `Resume change fee ${amount} ${currency} for change order ${changeOrderNo}? The card is already authorised; this captures it and triggers change ticketing.` : `Pay change fee ${amount} ${currency} for change order ${changeOrderNo}? This charges the customer and triggers change ticketing.`;
6340
- const ok = await confirm14({ message, default: false });
6645
+ const ok = await confirm15({ message, default: false });
6341
6646
  if (!ok) throw new CliError("CLIENT_ABORTED", "Change payment aborted by user.");
6342
6647
  }
6343
6648
  const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
@@ -6384,7 +6689,7 @@ function registerChangePayCommand(parent, deps) {
6384
6689
  }
6385
6690
 
6386
6691
  // src/flight-flink/refund-apply.ts
6387
- import { confirm as confirm15 } from "@inquirer/prompts";
6692
+ import { confirm as confirm16 } from "@inquirer/prompts";
6388
6693
  function registerRefundApplyCommand(parent, deps) {
6389
6694
  const cmd = parent.command("refund-apply").description("Submit a refund request (returns refund_order_no, pending review)").option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--order-no <id>", "Our order reference").option("--passenger <code>", "passengerCode").option("--segment-id <ids>", "Comma-separated segment ids").option("--reason-type <n>", "Refund reason type code").option("--reason <text>", "Free-text reason").option("--contact-name <name>", "Contact name").option("--contact-region <code>", "Contact region").option("--contact-phone <phone>", "Contact phone").option("--contact-email <email>", "Contact email").option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
6390
6695
  attachSchemaHelp(cmd, flightRefundApplySchema);
@@ -6394,18 +6699,18 @@ function registerRefundApplyCommand(parent, deps) {
6394
6699
  const isYes = Boolean(opts.yes);
6395
6700
  const apiKey = await resolveApiKey(opts.apiKey);
6396
6701
  const body = {
6397
- order_no: need20(opts.orderNo, "order-no"),
6398
- passenger: need20(opts.passenger, "passenger"),
6399
- segment_id: need20(opts.segmentId, "segment-id"),
6702
+ order_no: need21(opts.orderNo, "order-no"),
6703
+ passenger: need21(opts.passenger, "passenger"),
6704
+ segment_id: need21(opts.segmentId, "segment-id"),
6400
6705
  reason_type: num10(opts.reasonType, "reason-type"),
6401
- contact_name: need20(opts.contactName, "contact-name"),
6402
- contact_region: need20(opts.contactRegion, "contact-region"),
6403
- contact_phone: need20(opts.contactPhone, "contact-phone"),
6404
- contact_email: need20(opts.contactEmail, "contact-email")
6706
+ contact_name: need21(opts.contactName, "contact-name"),
6707
+ contact_region: need21(opts.contactRegion, "contact-region"),
6708
+ contact_phone: need21(opts.contactPhone, "contact-phone"),
6709
+ contact_email: need21(opts.contactEmail, "contact-email")
6405
6710
  };
6406
6711
  if (opts.reason !== void 0) body.reason = opts.reason;
6407
6712
  if (!isYes) {
6408
- const ok = await confirm15({
6713
+ const ok = await confirm16({
6409
6714
  message: `Submit a refund request for order ${body.order_no}?`,
6410
6715
  default: false
6411
6716
  });
@@ -6436,7 +6741,7 @@ function registerRefundDetailCommand(parent, deps) {
6436
6741
  const opts = cmd.optsWithGlobals();
6437
6742
  const format = resolveFormat(opts.format);
6438
6743
  const apiKey = await resolveApiKey(opts.apiKey);
6439
- const refundOrderNo = need20(opts.refundOrderNo, "refund-order-no");
6744
+ const refundOrderNo = need21(opts.refundOrderNo, "refund-order-no");
6440
6745
  const spinner = format === "json" ? null : createSpinner("Fetching refund detail...");
6441
6746
  const result = await deps.apiClient.get(
6442
6747
  `/flight/refund/${encodeURIComponent(refundOrderNo)}`,
@@ -6449,7 +6754,7 @@ function registerRefundDetailCommand(parent, deps) {
6449
6754
  }
6450
6755
 
6451
6756
  // src/flight-flink/refund-confirm.ts
6452
- import { confirm as confirm16 } from "@inquirer/prompts";
6757
+ import { confirm as confirm17 } from "@inquirer/prompts";
6453
6758
  function registerRefundConfirmCommand(parent, deps) {
6454
6759
  const cmd = parent.command("refund-confirm").description('Confirm ("1") or cancel ("2") a refund').option("--api-key <key>", "API Key for authentication (X-Api-Key)").option("--refund-order-no <id>", "Refund order number").option("--confirm <flag>", '"1" confirm / "2" cancel').option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
6455
6760
  attachSchemaHelp(cmd, flightRefundConfirmSchema);
@@ -6458,14 +6763,14 @@ function registerRefundConfirmCommand(parent, deps) {
6458
6763
  const format = resolveFormat(opts.format);
6459
6764
  const isYes = Boolean(opts.yes);
6460
6765
  const apiKey = await resolveApiKey(opts.apiKey);
6461
- const refundOrderNo = need20(opts.refundOrderNo, "refund-order-no");
6462
- const confirmFlag = need20(opts.confirm, "confirm");
6766
+ const refundOrderNo = need21(opts.refundOrderNo, "refund-order-no");
6767
+ const confirmFlag = need21(opts.confirm, "confirm");
6463
6768
  if (confirmFlag !== "1" && confirmFlag !== "2") {
6464
6769
  throw new CliError("PARAM_INVALID", '--confirm must be "1" (confirm) or "2" (cancel).');
6465
6770
  }
6466
6771
  if (!isYes) {
6467
6772
  const action = confirmFlag === "1" ? "confirm" : "cancel";
6468
- const ok = await confirm16({ message: `${action} refund ${refundOrderNo}?`, default: false });
6773
+ const ok = await confirm17({ message: `${action} refund ${refundOrderNo}?`, default: false });
6469
6774
  if (!ok) throw new CliError("CLIENT_ABORTED", "Refund confirmation aborted by user.");
6470
6775
  }
6471
6776
  const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
@@ -6639,10 +6944,11 @@ Key notes:
6639
6944
  registerServicesListCommand(servicesCmd, { discoveryClient, program });
6640
6945
  registerServiceGetCommand(servicesCmd, { discoveryClient, program });
6641
6946
  const ordersCmd = program.command("orders").description(
6642
- 'Unified cross-provider order index (spans ride + hotel). Use for generic "my orders" requests; use ride-elife/hotel-redaug commands once the business is known.'
6947
+ 'Unified cross-provider order index (spans ride + hotel + flight). Use list/get for generic "my orders" requests (use ride-elife/hotel-redaug/flight-flink commands once the business is known); pay-batch settles a batch of AWAITING_PAYMENT orders in one aggregate payment (trip checkout).'
6643
6948
  );
6644
6949
  registerOrdersListCommand(ordersCmd, deps);
6645
6950
  registerOrdersGetCommand(ordersCmd, deps);
6951
+ registerOrdersPayBatchCommand(ordersCmd, deps);
6646
6952
  const hotelCmd = program.command("hotel-redaug").description(
6647
6953
  `Hotel booking (Redaug) \u2014 international hotel search, quote, create-order, pay-order, cancel, and check-out.
6648
6954