@agenzo/merchant-cli 0.8.17 → 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
@@ -2231,6 +2231,97 @@ var unifiedOrdersGetSchema = {
2231
2231
  INTERNAL_ERROR: "The order's provider detail lookup is temporarily unavailable. Retry once after a short delay."
2232
2232
  }
2233
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
+ };
2234
2325
  function flightSchema(verb, description, flags, response, example, extra = {}) {
2235
2326
  return { cli: CLI_NAME, noun: FLIGHT_NOUN, verb, description, flags, response, example, ...extra };
2236
2327
  }
@@ -4002,15 +4093,201 @@ function registerOrdersGetCommand(parent, deps) {
4002
4093
  });
4003
4094
  }
4004
4095
 
4005
- // 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
+ }
4006
4275
  function need9(value, flag) {
4007
4276
  if (value === void 0) {
4008
4277
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4009
4278
  }
4010
4279
  return value;
4011
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
+ }
4012
4289
  function num5(value, flag) {
4013
- const n = Number(need9(value, flag));
4290
+ const n = Number(need10(value, flag));
4014
4291
  if (!Number.isFinite(n)) {
4015
4292
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
4016
4293
  }
@@ -4032,7 +4309,7 @@ function positiveInt3(value, flag) {
4032
4309
  }
4033
4310
  var YMD_RE = /^\d{4}-\d{2}-\d{2}$/;
4034
4311
  function stayDate(value, flag) {
4035
- const raw = need9(value, flag);
4312
+ const raw = need10(value, flag);
4036
4313
  if (!YMD_RE.test(raw)) {
4037
4314
  throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
4038
4315
  }
@@ -4104,7 +4381,7 @@ function registerHotelSearchCommand(parent, deps) {
4104
4381
  const pageSize = positiveInt3(opts.pageSize, "page-size");
4105
4382
  const body = {};
4106
4383
  if (hasDestination) {
4107
- body.destination_id = need9(opts.destinationId, "destination-id");
4384
+ body.destination_id = need10(opts.destinationId, "destination-id");
4108
4385
  } else {
4109
4386
  body.lat = coord(opts.lat, "lat", -90, 90);
4110
4387
  body.lng = coord(opts.lng, "lng", -180, 180);
@@ -4147,14 +4424,14 @@ function registerHotelSearchCommand(parent, deps) {
4147
4424
  }
4148
4425
 
4149
4426
  // src/hotel-redaug/quote.ts
4150
- function need10(value, flag) {
4427
+ function need11(value, flag) {
4151
4428
  if (value === void 0) {
4152
4429
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4153
4430
  }
4154
4431
  return value;
4155
4432
  }
4156
4433
  function num6(value, flag) {
4157
- const n = Number(need10(value, flag));
4434
+ const n = Number(need11(value, flag));
4158
4435
  if (!Number.isFinite(n)) {
4159
4436
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
4160
4437
  }
@@ -4162,7 +4439,7 @@ function num6(value, flag) {
4162
4439
  }
4163
4440
  var YMD_RE2 = /^\d{4}-\d{2}-\d{2}$/;
4164
4441
  function stayDate2(value, flag) {
4165
- const raw = need10(value, flag);
4442
+ const raw = need11(value, flag);
4166
4443
  if (!YMD_RE2.test(raw)) {
4167
4444
  throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
4168
4445
  }
@@ -4202,7 +4479,7 @@ function registerHotelQuoteCommand(parent, deps) {
4202
4479
  message: "API Key:",
4203
4480
  type: "password"
4204
4481
  });
4205
- const hotelId = need10(opts.hotelId, "hotel-id");
4482
+ const hotelId = need11(opts.hotelId, "hotel-id");
4206
4483
  const checkIn = stayDate2(opts.checkIn, "check-in");
4207
4484
  const checkOut = stayDate2(opts.checkOut, "check-out");
4208
4485
  if (!(checkOut > checkIn)) {
@@ -4236,7 +4513,7 @@ function registerHotelQuoteCommand(parent, deps) {
4236
4513
  }
4237
4514
 
4238
4515
  // src/hotel-redaug/create-order.ts
4239
- import { confirm as confirm6 } from "@inquirer/prompts";
4516
+ import { confirm as confirm7 } from "@inquirer/prompts";
4240
4517
  function parsePriceItems(raw) {
4241
4518
  const INVALID = "--price-items must be a JSON array of {sale_date (string), sale_price (number), breakfast_num (number)}.";
4242
4519
  let parsed;
@@ -4294,14 +4571,14 @@ function parseCancellation(raw) {
4294
4571
  }
4295
4572
  return parsed;
4296
4573
  }
4297
- function need11(value, flag) {
4574
+ function need12(value, flag) {
4298
4575
  if (value === void 0) {
4299
4576
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4300
4577
  }
4301
4578
  return value;
4302
4579
  }
4303
4580
  function num7(value, flag) {
4304
- const n = Number(need11(value, flag));
4581
+ const n = Number(need12(value, flag));
4305
4582
  if (!Number.isFinite(n)) {
4306
4583
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
4307
4584
  }
@@ -4309,7 +4586,7 @@ function num7(value, flag) {
4309
4586
  }
4310
4587
  var YMD_RE3 = /^\d{4}-\d{2}-\d{2}$/;
4311
4588
  function stayDate3(value, flag) {
4312
- const raw = need11(value, flag);
4589
+ const raw = need12(value, flag);
4313
4590
  if (!YMD_RE3.test(raw)) {
4314
4591
  throw new CliError("PARAM_INVALID", `--${flag} must be a YYYY-MM-DD date.`);
4315
4592
  }
@@ -4378,18 +4655,18 @@ function registerHotelCreateOrderCommand(parent, deps) {
4378
4655
  message: "API Key:",
4379
4656
  type: "password"
4380
4657
  });
4381
- const productToken = need11(opts.productToken, "product-token");
4658
+ const productToken = need12(opts.productToken, "product-token");
4382
4659
  const totalAmount = num7(opts.totalAmount, "total-amount");
4383
- const currency = need11(opts.currency, "currency");
4384
- const priceItems = parsePriceItems(need11(opts.priceItems, "price-items"));
4660
+ const currency = need12(opts.currency, "currency");
4661
+ const priceItems = parsePriceItems(need12(opts.priceItems, "price-items"));
4385
4662
  const checkIn = stayDate3(opts.checkIn, "check-in");
4386
4663
  const checkOut = stayDate3(opts.checkOut, "check-out");
4387
4664
  if (!(checkOut > checkIn)) {
4388
4665
  throw new CliError("PARAM_INVALID", "--check-out must be strictly after --check-in.");
4389
4666
  }
4390
- const guestName = need11(opts.guestName, "guest-name");
4391
- const contactName = need11(opts.contactName, "contact-name");
4392
- 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");
4393
4670
  const body = {
4394
4671
  product_token: productToken,
4395
4672
  total_amount: totalAmount,
@@ -4423,7 +4700,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
4423
4700
  if (member !== void 0) body.member_id = member;
4424
4701
  if (!isYes) {
4425
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.";
4426
- const confirmed = await confirm6({
4703
+ const confirmed = await confirm7({
4427
4704
  message: `Create this hotel order for ${totalAmount} ${currency} (check-in ${checkIn}, check-out ${checkOut})? ${chargeNote}`,
4428
4705
  default: false
4429
4706
  });
@@ -4457,7 +4734,7 @@ function registerHotelCreateOrderCommand(parent, deps) {
4457
4734
  }
4458
4735
 
4459
4736
  // src/hotel-redaug/pay-order.ts
4460
- import { confirm as confirm7 } from "@inquirer/prompts";
4737
+ import { confirm as confirm8 } from "@inquirer/prompts";
4461
4738
 
4462
4739
  // src/hotel-redaug/watch.ts
4463
4740
  var DEFAULT_ORDER_WATCH_INTERVAL_SECONDS = 5;
@@ -4645,7 +4922,7 @@ function registerHotelPayOrderCommand(parent, deps) {
4645
4922
  }
4646
4923
  if (opts.evoExplicit) body.evo_explicit = true;
4647
4924
  if (!isYes) {
4648
- const confirmed = await confirm7({
4925
+ const confirmed = await confirm8({
4649
4926
  message: `Settle hotel order ${orderId}? This moves money via the order's configured billing mode (monthly_settlement or pay_per_call).`,
4650
4927
  default: false
4651
4928
  });
@@ -4723,7 +5000,7 @@ function registerHotelPayOrderCommand(parent, deps) {
4723
5000
  }
4724
5001
 
4725
5002
  // src/hotel-redaug/get.ts
4726
- function need12(value, flag) {
5003
+ function need13(value, flag) {
4727
5004
  if (value === void 0) {
4728
5005
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4729
5006
  }
@@ -4787,7 +5064,7 @@ function registerHotelGetCommand(parent, deps) {
4787
5064
  message: "API Key:",
4788
5065
  type: "password"
4789
5066
  });
4790
- const orderId = need12(opts.orderId, "order-id");
5067
+ const orderId = need13(opts.orderId, "order-id");
4791
5068
  if (opts.watch) {
4792
5069
  await watchOrderStatus(deps.apiClient, apiKey, orderId, {
4793
5070
  intervalSeconds: resolveSeconds(
@@ -4821,7 +5098,7 @@ function registerHotelGetCommand(parent, deps) {
4821
5098
  }
4822
5099
 
4823
5100
  // src/hotel-redaug/cancel.ts
4824
- function need13(value, flag) {
5101
+ function need14(value, flag) {
4825
5102
  if (value === void 0) {
4826
5103
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4827
5104
  }
@@ -4874,8 +5151,8 @@ function registerHotelCancelCommand(parent, deps) {
4874
5151
  message: "API Key:",
4875
5152
  type: "password"
4876
5153
  });
4877
- const orderId = need13(opts.orderId, "order-id");
4878
- 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");
4879
5156
  const body = { fc_order_code: fcOrderCode };
4880
5157
  if (opts.reason !== void 0) body.reason = opts.reason;
4881
5158
  const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
@@ -4904,15 +5181,15 @@ function registerHotelCancelCommand(parent, deps) {
4904
5181
  }
4905
5182
 
4906
5183
  // src/hotel-redaug/checkout.ts
4907
- import { confirm as confirm8 } from "@inquirer/prompts";
4908
- function need14(value, flag) {
5184
+ import { confirm as confirm9 } from "@inquirer/prompts";
5185
+ function need15(value, flag) {
4909
5186
  if (value === void 0) {
4910
5187
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
4911
5188
  }
4912
5189
  return value;
4913
5190
  }
4914
5191
  function num8(value, flag) {
4915
- const n = Number(need14(value, flag));
5192
+ const n = Number(need15(value, flag));
4916
5193
  if (!Number.isFinite(n)) {
4917
5194
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
4918
5195
  }
@@ -4978,10 +5255,10 @@ function registerHotelCheckoutCommand(parent, deps) {
4978
5255
  message: "API Key:",
4979
5256
  type: "password"
4980
5257
  });
4981
- const orderId = need14(opts.orderId, "order-id");
4982
- const fcOrderCode = need14(opts.fcOrderCode, "fc-order-code");
4983
- const reason = need14(opts.reason, "reason");
4984
- 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"));
4985
5262
  const refundType = num8(opts.refundType, "refund-type");
4986
5263
  const body = {
4987
5264
  fc_order_code: fcOrderCode,
@@ -4990,7 +5267,7 @@ function registerHotelCheckoutCommand(parent, deps) {
4990
5267
  checkout_rooms: checkoutRooms
4991
5268
  };
4992
5269
  if (!isYes) {
4993
- const confirmed = await confirm8({
5270
+ const confirmed = await confirm9({
4994
5271
  message: `Request check-out / out-of-policy cancellation for order ${orderId} (${checkoutRooms.length} room(s))? The property must approve and charges may apply.`,
4995
5272
  default: false
4996
5273
  });
@@ -5024,7 +5301,7 @@ function registerHotelCheckoutCommand(parent, deps) {
5024
5301
  }
5025
5302
 
5026
5303
  // src/hotel-redaug/get-checkout.ts
5027
- function need15(value, flag) {
5304
+ function need16(value, flag) {
5028
5305
  if (value === void 0) {
5029
5306
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5030
5307
  }
@@ -5060,7 +5337,7 @@ function registerHotelGetCheckoutCommand(parent, deps) {
5060
5337
  message: "API Key:",
5061
5338
  type: "password"
5062
5339
  });
5063
- const taskOrderCode = need15(opts.taskOrderCode, "task-order-code");
5340
+ const taskOrderCode = need16(opts.taskOrderCode, "task-order-code");
5064
5341
  if (opts.watch) {
5065
5342
  await watchCheckoutStatus(deps.apiClient, apiKey, taskOrderCode, {
5066
5343
  intervalSeconds: resolveSeconds(
@@ -5164,7 +5441,7 @@ function registerHotelListOrdersCommand(parent, deps) {
5164
5441
  }
5165
5442
 
5166
5443
  // src/hotel-redaug/find-destination.ts
5167
- function need16(value, flag) {
5444
+ function need17(value, flag) {
5168
5445
  if (value === void 0 || value.trim() === "") {
5169
5446
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5170
5447
  }
@@ -5198,7 +5475,7 @@ function registerHotelFindDestinationCommand(parent, deps) {
5198
5475
  message: "API Key:",
5199
5476
  type: "password"
5200
5477
  });
5201
- const keyword = need16(opts.keyword, "keyword");
5478
+ const keyword = need17(opts.keyword, "keyword");
5202
5479
  const body = { keyword };
5203
5480
  if (opts.dataType !== void 0) {
5204
5481
  body.data_type = opts.dataType;
@@ -5222,14 +5499,14 @@ function registerHotelFindDestinationCommand(parent, deps) {
5222
5499
  }
5223
5500
 
5224
5501
  // src/hotel-redaug/hotel-filters.ts
5225
- function need17(value, flag) {
5502
+ function need18(value, flag) {
5226
5503
  if (value === void 0 || value.trim() === "") {
5227
5504
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5228
5505
  }
5229
5506
  return value;
5230
5507
  }
5231
5508
  function num9(value, flag) {
5232
- const n = Number(need17(value, flag));
5509
+ const n = Number(need18(value, flag));
5233
5510
  if (!Number.isFinite(n)) {
5234
5511
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
5235
5512
  }
@@ -5309,7 +5586,7 @@ function registerHotelFiltersCommand(parent, deps) {
5309
5586
  }
5310
5587
  const body = {};
5311
5588
  if (hasDestination) {
5312
- body.destination_id = need17(opts.destinationId, "destination-id");
5589
+ body.destination_id = need18(opts.destinationId, "destination-id");
5313
5590
  } else {
5314
5591
  body.lat = coord2(opts.lat, "lat", -90, 90);
5315
5592
  body.lng = coord2(opts.lng, "lng", -180, 180);
@@ -5334,7 +5611,7 @@ function registerHotelFiltersCommand(parent, deps) {
5334
5611
  }
5335
5612
 
5336
5613
  // src/hotel-redaug/list-cities.ts
5337
- function need18(value, flag) {
5614
+ function need19(value, flag) {
5338
5615
  if (value === void 0 || value.trim() === "") {
5339
5616
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5340
5617
  }
@@ -5367,7 +5644,7 @@ function registerHotelListCitiesCommand(parent, deps) {
5367
5644
  message: "API Key:",
5368
5645
  type: "password"
5369
5646
  });
5370
- const country = need18(opts.country, "country");
5647
+ const country = need19(opts.country, "country");
5371
5648
  const body = { country_code: country };
5372
5649
  const result = await deps.apiClient.post(
5373
5650
  "/hotel/cities",
@@ -5388,7 +5665,7 @@ function registerHotelListCitiesCommand(parent, deps) {
5388
5665
  }
5389
5666
 
5390
5667
  // src/hotel-redaug/hotel-detail.ts
5391
- function need19(value, flag) {
5668
+ function need20(value, flag) {
5392
5669
  if (value === void 0 || value.trim() === "") {
5393
5670
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5394
5671
  }
@@ -5535,7 +5812,7 @@ function registerHotelDetailCommand(parent, deps) {
5535
5812
  message: "API Key:",
5536
5813
  type: "password"
5537
5814
  });
5538
- const hotelId = need19(opts.hotelId, "hotel-id");
5815
+ const hotelId = need20(opts.hotelId, "hotel-id");
5539
5816
  const rawWithImages = opts.withImages;
5540
5817
  const withImages = rawWithImages !== "false" && rawWithImages !== false;
5541
5818
  const settings = parseSettings(opts.settings);
@@ -5743,14 +6020,14 @@ function registerHotelSkillCommand(parent) {
5743
6020
  }
5744
6021
 
5745
6022
  // src/flight-flink/_helpers.ts
5746
- function need20(value, flag) {
6023
+ function need21(value, flag) {
5747
6024
  if (value === void 0) {
5748
6025
  throw new CliError("PARAM_INVALID", `Missing required --${flag}.`);
5749
6026
  }
5750
6027
  return value;
5751
6028
  }
5752
6029
  function num10(value, flag) {
5753
- const n = Number(need20(value, flag));
6030
+ const n = Number(need21(value, flag));
5754
6031
  if (!Number.isFinite(n)) {
5755
6032
  throw new CliError("PARAM_INVALID", `--${flag} must be a number.`);
5756
6033
  }
@@ -5785,7 +6062,7 @@ function registerFindAirportCommand(parent, deps) {
5785
6062
  const opts = cmd.optsWithGlobals();
5786
6063
  const format = resolveFormat(opts.format);
5787
6064
  const apiKey = await resolveApiKey(opts.apiKey);
5788
- const keyword = need20(opts.keyword, "keyword");
6065
+ const keyword = need21(opts.keyword, "keyword");
5789
6066
  const spinner = format === "json" ? null : createSpinner("Resolving airports...");
5790
6067
  const result = await deps.apiClient.post(
5791
6068
  "/flight/find-airport",
@@ -5882,7 +6159,7 @@ function registerSearchCommand(parent, deps) {
5882
6159
  const apiKey = await resolveApiKey(opts.apiKey);
5883
6160
  const body = {
5884
6161
  trip_type: num10(opts.tripType, "trip-type"),
5885
- journeys: jsonArray(need20(opts.journeys, "journeys"), "journeys"),
6162
+ journeys: jsonArray(need21(opts.journeys, "journeys"), "journeys"),
5886
6163
  cabin_class: opts.cabinClass,
5887
6164
  adult_num: num10(opts.adultNum, "adult-num"),
5888
6165
  child_num: num10(opts.childNum, "child-num"),
@@ -5913,7 +6190,7 @@ function registerMoreOffersCommand(parent, deps) {
5913
6190
  const opts = cmd.optsWithGlobals();
5914
6191
  const format = resolveFormat(opts.format);
5915
6192
  const apiKey = await resolveApiKey(opts.apiKey);
5916
- const productToken = need20(opts.productToken, "product-token");
6193
+ const productToken = need21(opts.productToken, "product-token");
5917
6194
  const spinner = format === "json" ? null : createSpinner("Fetching offers...");
5918
6195
  const result = await deps.apiClient.post(
5919
6196
  "/flight/more-offers",
@@ -5934,7 +6211,7 @@ function registerVerifyCommand(parent, deps) {
5934
6211
  const opts = cmd.optsWithGlobals();
5935
6212
  const format = resolveFormat(opts.format);
5936
6213
  const apiKey = await resolveApiKey(opts.apiKey);
5937
- const productToken = need20(opts.productToken, "product-token");
6214
+ const productToken = need21(opts.productToken, "product-token");
5938
6215
  const spinner = format === "json" ? null : createSpinner("Verifying price...");
5939
6216
  const result = await deps.apiClient.post(
5940
6217
  "/flight/verify",
@@ -5956,7 +6233,7 @@ function registerVerifyCommand(parent, deps) {
5956
6233
  }
5957
6234
 
5958
6235
  // src/flight-flink/create-order.ts
5959
- import { confirm as confirm9 } from "@inquirer/prompts";
6236
+ import { confirm as confirm10 } from "@inquirer/prompts";
5960
6237
  function registerCreateOrderCommand(parent, deps) {
5961
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(
5962
6239
  "--authorized-merchant-trans-id <id>",
@@ -5968,19 +6245,19 @@ function registerCreateOrderCommand(parent, deps) {
5968
6245
  const format = resolveFormat(opts.format);
5969
6246
  const isYes = Boolean(opts.yes);
5970
6247
  const apiKey = await resolveApiKey(opts.apiKey);
5971
- const productToken = need20(opts.productToken, "product-token");
6248
+ const productToken = need21(opts.productToken, "product-token");
5972
6249
  const totalAmount = num10(opts.totalAmount, "total-amount");
5973
- const currency = need20(opts.currency, "currency");
6250
+ const currency = need21(opts.currency, "currency");
5974
6251
  const body = {
5975
6252
  product_token: productToken,
5976
6253
  total_amount: totalAmount,
5977
6254
  currency,
5978
6255
  trip_type: num10(opts.tripType, "trip-type"),
5979
- contact_name: need20(opts.contactName, "contact-name"),
5980
- contact_region: need20(opts.contactRegion, "contact-region"),
5981
- contact_phone: need20(opts.contactPhone, "contact-phone"),
5982
- contact_email: need20(opts.contactEmail, "contact-email"),
5983
- 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")
5984
6261
  };
5985
6262
  if (opts.paymentMethodId !== void 0) body.payment_method_id = opts.paymentMethodId;
5986
6263
  if (opts.paymentTokenId !== void 0) body.payment_token_id = opts.paymentTokenId;
@@ -5990,7 +6267,7 @@ function registerCreateOrderCommand(parent, deps) {
5990
6267
  const member = memberIdOf(opts);
5991
6268
  if (member !== void 0) body.member_id = member;
5992
6269
  if (!isYes) {
5993
- const ok = await confirm9({
6270
+ const ok = await confirm10({
5994
6271
  message: `Create this flight order for ${totalAmount} ${currency}? This locks the fare but does NOT charge yet.`,
5995
6272
  default: false
5996
6273
  });
@@ -6029,7 +6306,7 @@ function registerCreateOrderCommand(parent, deps) {
6029
6306
  }
6030
6307
 
6031
6308
  // src/flight-flink/pay-order.ts
6032
- import { confirm as confirm10 } from "@inquirer/prompts";
6309
+ import { confirm as confirm11 } from "@inquirer/prompts";
6033
6310
  function registerPayOrderCommand(parent, deps) {
6034
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(
6035
6312
  "--authorized-merchant-trans-id <id>",
@@ -6044,9 +6321,9 @@ function registerPayOrderCommand(parent, deps) {
6044
6321
  const format = resolveFormat(opts.format);
6045
6322
  const isYes = Boolean(opts.yes);
6046
6323
  const apiKey = await resolveApiKey(opts.apiKey);
6047
- const orderNo = need20(opts.orderNo, "order-no");
6324
+ const orderNo = need21(opts.orderNo, "order-no");
6048
6325
  if (!isYes) {
6049
- const ok = await confirm10({
6326
+ const ok = await confirm11({
6050
6327
  message: `Pay and ticket order ${orderNo}? This settles the order and issues tickets.`,
6051
6328
  default: false
6052
6329
  });
@@ -6096,7 +6373,7 @@ function registerGetOrderCommand(parent, deps) {
6096
6373
  const opts = cmd.optsWithGlobals();
6097
6374
  const format = resolveFormat(opts.format);
6098
6375
  const apiKey = await resolveApiKey(opts.apiKey);
6099
- const orderNo = need20(opts.orderNo, "order-no");
6376
+ const orderNo = need21(opts.orderNo, "order-no");
6100
6377
  const path = `/flight/${encodeURIComponent(orderNo)}/status`;
6101
6378
  const auth = { type: "api-key", key: apiKey };
6102
6379
  if (opts.watch) {
@@ -6136,7 +6413,7 @@ function registerGetOrderCommand(parent, deps) {
6136
6413
  }
6137
6414
 
6138
6415
  // src/flight-flink/cancel-order.ts
6139
- import { confirm as confirm11 } from "@inquirer/prompts";
6416
+ import { confirm as confirm12 } from "@inquirer/prompts";
6140
6417
  function registerCancelOrderCommand(parent, deps) {
6141
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");
6142
6419
  attachSchemaHelp(cmd, flightCancelOrderSchema);
@@ -6145,9 +6422,9 @@ function registerCancelOrderCommand(parent, deps) {
6145
6422
  const format = resolveFormat(opts.format);
6146
6423
  const isYes = Boolean(opts.yes);
6147
6424
  const apiKey = await resolveApiKey(opts.apiKey);
6148
- const orderNo = need20(opts.orderNo, "order-no");
6425
+ const orderNo = need21(opts.orderNo, "order-no");
6149
6426
  if (!isYes) {
6150
- const ok = await confirm11({
6427
+ const ok = await confirm12({
6151
6428
  message: `Cancel order ${orderNo}? This requests cancellation and a refund.`,
6152
6429
  default: false
6153
6430
  });
@@ -6221,10 +6498,10 @@ function registerChangeSearchCommand(parent, deps) {
6221
6498
  const format = resolveFormat(opts.format);
6222
6499
  const apiKey = await resolveApiKey(opts.apiKey);
6223
6500
  const body = {
6224
- order_no: need20(opts.orderNo, "order-no"),
6225
- date: need20(opts.date, "date"),
6226
- passenger: need20(opts.passenger, "passenger"),
6227
- 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"),
6228
6505
  cabin_class: opts.cabinClass
6229
6506
  };
6230
6507
  const spinner = format === "json" ? null : createSpinner("Searching change options...");
@@ -6240,7 +6517,7 @@ function registerChangeSearchCommand(parent, deps) {
6240
6517
  }
6241
6518
 
6242
6519
  // src/flight-flink/change-apply.ts
6243
- import { confirm as confirm12 } from "@inquirer/prompts";
6520
+ import { confirm as confirm13 } from "@inquirer/prompts";
6244
6521
  function registerChangeApplyCommand(parent, deps) {
6245
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");
6246
6523
  attachSchemaHelp(cmd, flightChangeApplySchema);
@@ -6250,17 +6527,17 @@ function registerChangeApplyCommand(parent, deps) {
6250
6527
  const isYes = Boolean(opts.yes);
6251
6528
  const apiKey = await resolveApiKey(opts.apiKey);
6252
6529
  const body = {
6253
- order_no: need20(opts.orderNo, "order-no"),
6254
- passenger: need20(opts.passenger, "passenger"),
6255
- segment_id: need20(opts.segmentId, "segment-id"),
6256
- product_token: need20(opts.productToken, "product-token"),
6257
- contact_name: need20(opts.contactName, "contact-name"),
6258
- contact_region: need20(opts.contactRegion, "contact-region"),
6259
- contact_phone: need20(opts.contactPhone, "contact-phone"),
6260
- 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")
6261
6538
  };
6262
6539
  if (!isYes) {
6263
- const ok = await confirm12({
6540
+ const ok = await confirm13({
6264
6541
  message: `Submit a change request for order ${body.order_no}?`,
6265
6542
  default: false
6266
6543
  });
@@ -6291,7 +6568,7 @@ function registerChangeDetailCommand(parent, deps) {
6291
6568
  const opts = cmd.optsWithGlobals();
6292
6569
  const format = resolveFormat(opts.format);
6293
6570
  const apiKey = await resolveApiKey(opts.apiKey);
6294
- const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
6571
+ const changeOrderNo = need21(opts.changeOrderNo, "change-order-no");
6295
6572
  const spinner = format === "json" ? null : createSpinner("Fetching change detail...");
6296
6573
  const result = await deps.apiClient.get(
6297
6574
  `/flight/change/${encodeURIComponent(changeOrderNo)}`,
@@ -6304,7 +6581,7 @@ function registerChangeDetailCommand(parent, deps) {
6304
6581
  }
6305
6582
 
6306
6583
  // src/flight-flink/change-cancel.ts
6307
- import { confirm as confirm13 } from "@inquirer/prompts";
6584
+ import { confirm as confirm14 } from "@inquirer/prompts";
6308
6585
  function registerChangeCancelCommand(parent, deps) {
6309
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");
6310
6587
  attachSchemaHelp(cmd, flightChangeCancelSchema);
@@ -6313,9 +6590,9 @@ function registerChangeCancelCommand(parent, deps) {
6313
6590
  const format = resolveFormat(opts.format);
6314
6591
  const isYes = Boolean(opts.yes);
6315
6592
  const apiKey = await resolveApiKey(opts.apiKey);
6316
- const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
6593
+ const changeOrderNo = need21(opts.changeOrderNo, "change-order-no");
6317
6594
  if (!isYes) {
6318
- const ok = await confirm13({ message: `Cancel change request ${changeOrderNo}?`, default: false });
6595
+ const ok = await confirm14({ message: `Cancel change request ${changeOrderNo}?`, default: false });
6319
6596
  if (!ok) throw new CliError("CLIENT_ABORTED", "Change cancellation aborted by user.");
6320
6597
  }
6321
6598
  const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
@@ -6336,7 +6613,7 @@ function registerChangeCancelCommand(parent, deps) {
6336
6613
  }
6337
6614
 
6338
6615
  // src/flight-flink/change-pay.ts
6339
- import { confirm as confirm14 } from "@inquirer/prompts";
6616
+ import { confirm as confirm15 } from "@inquirer/prompts";
6340
6617
  function registerChangePayCommand(parent, deps) {
6341
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(
6342
6619
  "--authorized-merchant-trans-id <id>",
@@ -6348,10 +6625,10 @@ function registerChangePayCommand(parent, deps) {
6348
6625
  const format = resolveFormat(opts.format);
6349
6626
  const isYes = Boolean(opts.yes);
6350
6627
  const apiKey = await resolveApiKey(opts.apiKey);
6351
- const changeOrderNo = need20(opts.changeOrderNo, "change-order-no");
6352
- const orderNo = need20(opts.orderNo, "order-no");
6628
+ const changeOrderNo = need21(opts.changeOrderNo, "change-order-no");
6629
+ const orderNo = need21(opts.orderNo, "order-no");
6353
6630
  const amount = num10(opts.amount, "amount");
6354
- const currency = need20(opts.currency, "currency");
6631
+ const currency = need21(opts.currency, "currency");
6355
6632
  const body = {
6356
6633
  order_no: orderNo,
6357
6634
  amount,
@@ -6365,7 +6642,7 @@ function registerChangePayCommand(parent, deps) {
6365
6642
  if (!isYes) {
6366
6643
  const isResume = opts.authorizedMerchantTransId !== void 0;
6367
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.`;
6368
- const ok = await confirm14({ message, default: false });
6645
+ const ok = await confirm15({ message, default: false });
6369
6646
  if (!ok) throw new CliError("CLIENT_ABORTED", "Change payment aborted by user.");
6370
6647
  }
6371
6648
  const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
@@ -6412,7 +6689,7 @@ function registerChangePayCommand(parent, deps) {
6412
6689
  }
6413
6690
 
6414
6691
  // src/flight-flink/refund-apply.ts
6415
- import { confirm as confirm15 } from "@inquirer/prompts";
6692
+ import { confirm as confirm16 } from "@inquirer/prompts";
6416
6693
  function registerRefundApplyCommand(parent, deps) {
6417
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");
6418
6695
  attachSchemaHelp(cmd, flightRefundApplySchema);
@@ -6422,18 +6699,18 @@ function registerRefundApplyCommand(parent, deps) {
6422
6699
  const isYes = Boolean(opts.yes);
6423
6700
  const apiKey = await resolveApiKey(opts.apiKey);
6424
6701
  const body = {
6425
- order_no: need20(opts.orderNo, "order-no"),
6426
- passenger: need20(opts.passenger, "passenger"),
6427
- 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"),
6428
6705
  reason_type: num10(opts.reasonType, "reason-type"),
6429
- contact_name: need20(opts.contactName, "contact-name"),
6430
- contact_region: need20(opts.contactRegion, "contact-region"),
6431
- contact_phone: need20(opts.contactPhone, "contact-phone"),
6432
- 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")
6433
6710
  };
6434
6711
  if (opts.reason !== void 0) body.reason = opts.reason;
6435
6712
  if (!isYes) {
6436
- const ok = await confirm15({
6713
+ const ok = await confirm16({
6437
6714
  message: `Submit a refund request for order ${body.order_no}?`,
6438
6715
  default: false
6439
6716
  });
@@ -6464,7 +6741,7 @@ function registerRefundDetailCommand(parent, deps) {
6464
6741
  const opts = cmd.optsWithGlobals();
6465
6742
  const format = resolveFormat(opts.format);
6466
6743
  const apiKey = await resolveApiKey(opts.apiKey);
6467
- const refundOrderNo = need20(opts.refundOrderNo, "refund-order-no");
6744
+ const refundOrderNo = need21(opts.refundOrderNo, "refund-order-no");
6468
6745
  const spinner = format === "json" ? null : createSpinner("Fetching refund detail...");
6469
6746
  const result = await deps.apiClient.get(
6470
6747
  `/flight/refund/${encodeURIComponent(refundOrderNo)}`,
@@ -6477,7 +6754,7 @@ function registerRefundDetailCommand(parent, deps) {
6477
6754
  }
6478
6755
 
6479
6756
  // src/flight-flink/refund-confirm.ts
6480
- import { confirm as confirm16 } from "@inquirer/prompts";
6757
+ import { confirm as confirm17 } from "@inquirer/prompts";
6481
6758
  function registerRefundConfirmCommand(parent, deps) {
6482
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");
6483
6760
  attachSchemaHelp(cmd, flightRefundConfirmSchema);
@@ -6486,14 +6763,14 @@ function registerRefundConfirmCommand(parent, deps) {
6486
6763
  const format = resolveFormat(opts.format);
6487
6764
  const isYes = Boolean(opts.yes);
6488
6765
  const apiKey = await resolveApiKey(opts.apiKey);
6489
- const refundOrderNo = need20(opts.refundOrderNo, "refund-order-no");
6490
- const confirmFlag = need20(opts.confirm, "confirm");
6766
+ const refundOrderNo = need21(opts.refundOrderNo, "refund-order-no");
6767
+ const confirmFlag = need21(opts.confirm, "confirm");
6491
6768
  if (confirmFlag !== "1" && confirmFlag !== "2") {
6492
6769
  throw new CliError("PARAM_INVALID", '--confirm must be "1" (confirm) or "2" (cancel).');
6493
6770
  }
6494
6771
  if (!isYes) {
6495
6772
  const action = confirmFlag === "1" ? "confirm" : "cancel";
6496
- const ok = await confirm16({ message: `${action} refund ${refundOrderNo}?`, default: false });
6773
+ const ok = await confirm17({ message: `${action} refund ${refundOrderNo}?`, default: false });
6497
6774
  if (!ok) throw new CliError("CLIENT_ABORTED", "Refund confirmation aborted by user.");
6498
6775
  }
6499
6776
  const idempotencyKey = await resolveIdempotencyKey(opts.idempotencyKey, {
@@ -6667,10 +6944,11 @@ Key notes:
6667
6944
  registerServicesListCommand(servicesCmd, { discoveryClient, program });
6668
6945
  registerServiceGetCommand(servicesCmd, { discoveryClient, program });
6669
6946
  const ordersCmd = program.command("orders").description(
6670
- "Unified cross-provider order index (ride + hotel + flight). Use for order history, common filters, and stable pagination."
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).'
6671
6948
  );
6672
6949
  registerOrdersListCommand(ordersCmd, deps);
6673
6950
  registerOrdersGetCommand(ordersCmd, deps);
6951
+ registerOrdersPayBatchCommand(ordersCmd, deps);
6674
6952
  const hotelCmd = program.command("hotel-redaug").description(
6675
6953
  `Hotel booking (Redaug) \u2014 international hotel search, quote, create-order, pay-order, cancel, and check-out.
6676
6954