@agenzo/merchant-cli 0.9.5 → 0.9.6

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
@@ -910,6 +910,42 @@ function memberIdOf(opts) {
910
910
  return trimmed.length > 0 ? trimmed : void 0;
911
911
  }
912
912
 
913
+ // src/price-annotation.ts
914
+ var ORIGINAL_DESCRIPTION = "Original (pre-discount) price in integer cents. Optional, RECORD-ONLY: stored on our own order / charge record and echoed back in the order detail, never sent to the acquiring gateway and never used to derive or validate the amount charged (that always comes from the order's locked authoritative price).";
915
+ var DISCOUNT_DESCRIPTION = "Discount amount in integer cents. Optional, RECORD-ONLY: same semantics as --original-amount-cents.";
916
+ var PRICE_ANNOTATION_FLAGS = {
917
+ "original-amount-cents": {
918
+ type: "int",
919
+ required: false,
920
+ description: ORIGINAL_DESCRIPTION,
921
+ constraints: "non-negative integer cents"
922
+ },
923
+ "discount-amount-cents": {
924
+ type: "int",
925
+ required: false,
926
+ description: DISCOUNT_DESCRIPTION,
927
+ constraints: "non-negative integer cents"
928
+ }
929
+ };
930
+ function applyPriceAnnotation(body, opts) {
931
+ const mappings = [
932
+ ["--original-amount-cents", "originalAmountCents", "original_amount_cents"],
933
+ ["--discount-amount-cents", "discountAmountCents", "discount_amount_cents"]
934
+ ];
935
+ for (const [flag, optKey, bodyKey] of mappings) {
936
+ const raw = opts[optKey];
937
+ if (raw === void 0) continue;
938
+ const cents = Number(raw);
939
+ if (!Number.isInteger(cents) || cents < 0) {
940
+ throw new CliError(
941
+ "PARAM_INVALID",
942
+ `Invalid ${flag} "${raw}". Expected a non-negative integer number of cents (e.g. 10000 for 100.00).`
943
+ );
944
+ }
945
+ body[bodyKey] = cents;
946
+ }
947
+ }
948
+
913
949
  // src/ride-elife/watch.ts
914
950
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
915
951
  "At destination",
@@ -1250,7 +1286,8 @@ var ridePayOrderSchema = {
1250
1286
  type: "string",
1251
1287
  required: true,
1252
1288
  description: "Unique key (1-128 chars [A-Za-z0-9_-]) forwarded verbatim as the Idempotency-Key header; never auto-generated"
1253
- }
1289
+ },
1290
+ ...PRICE_ANNOTATION_FLAGS
1254
1291
  },
1255
1292
  response: {
1256
1293
  order_id: { type: "string", description: "Authoritative order_ref (rio_\u2026, = order document _id) that was settled" },
@@ -1851,6 +1888,7 @@ var hotelPayOrderSchema = {
1851
1888
  description: "Unique key forwarded verbatim as the Idempotency-Key header; never auto-generated. Derive from business intent (e.g. hash(order_id + attempt)) and reuse the SAME key when retrying the same payment",
1852
1889
  constraints: "1-128 chars [A-Za-z0-9_-]"
1853
1890
  },
1891
+ ...PRICE_ANNOTATION_FLAGS,
1854
1892
  watch: { type: "bool", required: false, default: false, description: "Poll automatically on PAYMENT_NOT_COMPLETED until PAID or timeout. Each iteration emits one NDJSON line" },
1855
1893
  "watch-interval": { type: "int", required: false, default: 5, description: "Seconds between poll attempts in --watch mode" },
1856
1894
  "watch-timeout": { type: "int", required: false, default: 300, description: "Total seconds before giving up in --watch mode" }
@@ -2679,7 +2717,8 @@ var flightPayOrderSchema = flightSchema(
2679
2717
  "return-url": { type: "string", required: false, description: "Optional 3DS/passkey return URL for the network-token authenticate path; falls back to the platform EVO_3DS_RETURN_URL." },
2680
2718
  "authorized-charge-no": { type: "string", required: false, description: "Resume a network-token 3DS challenge: charge_no from a prior AUTHENTICATION_REQUIRED response (settled via resume_token), then triggers ticketing on success." },
2681
2719
  "evo-explicit": { type: "bool", required: false, default: false, description: "[\u65B9\u6848 B/R16] Explicit opt-in to settle this pay_per_call order via the EVO bound-card fallback rail. Set true ONLY when the user explicitly chose EVO; forwarded to the pay body as evo_explicit=true. Without it, a pay_per_call settlement lacking --payment-token-id is hard-gated server-side." },
2682
- "idempotency-key": { type: "string", required: true, description: "Forwarded verbatim as the Idempotency-Key header." }
2720
+ "idempotency-key": { type: "string", required: true, description: "Forwarded verbatim as the Idempotency-Key header." },
2721
+ ...PRICE_ANNOTATION_FLAGS
2683
2722
  },
2684
2723
  { order_no: { type: "string", description: "Our order reference." }, status: { type: "string", description: "PAID on success; AUTHENTICATION_REQUIRED when the card needs 3DS." } },
2685
2724
  { command: "agenzo-merchant-cli flight-flink pay-order --order-no ffo_... --idempotency-key k2", output_summary: "Order becomes PAID; poll get-order until TICKETED." }
@@ -2788,7 +2827,8 @@ var flightChangePaySchema = flightSchema(
2788
2827
  "payment-method-id": { type: "string", required: false, description: "Optional bound-card id (EVO path)." },
2789
2828
  "payment-token-id": { type: "string", required: false, description: "Optional UPI network-token id (unionpay charge path)." },
2790
2829
  "authorized-merchant-trans-id": { type: "string", required: false, description: "Resume a 3DS challenge with the merchant trans id of the already-authorised preauth; the platform reuses and captures it instead of authorizing again." },
2791
- "idempotency-key": { type: "string", required: true, description: "Idempotency-Key header." }
2830
+ "idempotency-key": { type: "string", required: true, description: "Idempotency-Key header." },
2831
+ ...PRICE_ANNOTATION_FLAGS
2792
2832
  },
2793
2833
  {
2794
2834
  change_order_no: { type: "string", description: "Change order number." },
@@ -3384,6 +3424,12 @@ function registerRidePayOrderCommand(parent, deps) {
3384
3424
  ).option(
3385
3425
  "--idempotency-key <key>",
3386
3426
  "Idempotency key forwarded verbatim as the Idempotency-Key header"
3427
+ ).option(
3428
+ "--original-amount-cents <cents>",
3429
+ PRICE_ANNOTATION_FLAGS["original-amount-cents"].description
3430
+ ).option(
3431
+ "--discount-amount-cents <cents>",
3432
+ PRICE_ANNOTATION_FLAGS["discount-amount-cents"].description
3387
3433
  );
3388
3434
  attachSchemaHelp(cmd, ridePayOrderSchema);
3389
3435
  cmd.action(async () => {
@@ -3411,6 +3457,7 @@ function registerRidePayOrderCommand(parent, deps) {
3411
3457
  if (opts.returnUrl !== void 0) body.return_url = opts.returnUrl;
3412
3458
  if (authorizedChargeNo !== void 0) body.authorized_charge_no = authorizedChargeNo;
3413
3459
  if (opts.evoExplicit) body.evo_explicit = true;
3460
+ applyPriceAnnotation(body, opts);
3414
3461
  if (!isYes) {
3415
3462
  const confirmed = await confirm3({
3416
3463
  message: `Settle ride order ${orderId}? This charges the card and creates the ride (AWAITING_PAYMENT \u2192 PAID).`,
@@ -5408,7 +5455,7 @@ function registerHotelPayOrderCommand(parent, deps) {
5408
5455
  ).option(
5409
5456
  "--idempotency-key <key>",
5410
5457
  "Idempotency key forwarded verbatim as the Idempotency-Key header"
5411
- ).option("--watch", "Poll until PAID or timeout (NDJSON output)", false).option(
5458
+ ).option("--original-amount-cents <cents>", PRICE_ANNOTATION_FLAGS["original-amount-cents"].description).option("--discount-amount-cents <cents>", PRICE_ANNOTATION_FLAGS["discount-amount-cents"].description).option("--watch", "Poll until PAID or timeout (NDJSON output)", false).option(
5412
5459
  "--watch-interval <seconds>",
5413
5460
  "Seconds between polls when --watch is set",
5414
5461
  String(DEFAULT_PAY_WATCH_INTERVAL_SECONDS)
@@ -5449,6 +5496,7 @@ function registerHotelPayOrderCommand(parent, deps) {
5449
5496
  body.authorized_charge_no = opts.authorizedChargeNo;
5450
5497
  }
5451
5498
  if (opts.evoExplicit) body.evo_explicit = true;
5499
+ applyPriceAnnotation(body, opts);
5452
5500
  if (!isYes) {
5453
5501
  const confirmed = await confirm8({
5454
5502
  message: `Settle hotel order ${orderId}? This moves money via the order's configured billing mode (monthly_settlement or pay_per_call).`,
@@ -6865,7 +6913,13 @@ function registerPayOrderCommand(parent, deps) {
6865
6913
  ).option(
6866
6914
  "--evo-explicit",
6867
6915
  "[\u65B9\u6848 B/R16] Explicit opt-in to settle this pay_per_call order via the EVO bound-card fallback rail. Set ONLY when the user explicitly chose EVO; forwarded to the pay body as evo_explicit=true. Without it, a pay_per_call settlement lacking --payment-token-id is hard-gated server-side."
6868
- ).option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
6916
+ ).option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header").option(
6917
+ "--original-amount-cents <cents>",
6918
+ PRICE_ANNOTATION_FLAGS["original-amount-cents"].description
6919
+ ).option(
6920
+ "--discount-amount-cents <cents>",
6921
+ PRICE_ANNOTATION_FLAGS["discount-amount-cents"].description
6922
+ );
6869
6923
  attachSchemaHelp(cmd, flightPayOrderSchema);
6870
6924
  cmd.action(async () => {
6871
6925
  const opts = cmd.optsWithGlobals();
@@ -6897,6 +6951,7 @@ function registerPayOrderCommand(parent, deps) {
6897
6951
  body.authorized_charge_no = opts.authorizedChargeNo;
6898
6952
  }
6899
6953
  if (opts.evoExplicit) body.evo_explicit = true;
6954
+ applyPriceAnnotation(body, opts);
6900
6955
  const result = await deps.apiClient.post(
6901
6956
  `/flight/${encodeURIComponent(orderNo)}/pay`,
6902
6957
  { type: "api-key", key: apiKey },
@@ -7175,7 +7230,13 @@ function registerChangePayCommand(parent, deps) {
7175
7230
  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(
7176
7231
  "--authorized-merchant-trans-id <id>",
7177
7232
  "Resume a 3DS challenge: merchant trans id of the already-authorised preauth"
7178
- ).option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header");
7233
+ ).option("--idempotency-key <key>", "Forwarded verbatim as the Idempotency-Key header").option(
7234
+ "--original-amount-cents <cents>",
7235
+ PRICE_ANNOTATION_FLAGS["original-amount-cents"].description
7236
+ ).option(
7237
+ "--discount-amount-cents <cents>",
7238
+ PRICE_ANNOTATION_FLAGS["discount-amount-cents"].description
7239
+ );
7179
7240
  attachSchemaHelp(cmd, flightChangePaySchema);
7180
7241
  cmd.action(async () => {
7181
7242
  const opts = cmd.optsWithGlobals();
@@ -7196,6 +7257,7 @@ function registerChangePayCommand(parent, deps) {
7196
7257
  if (opts.authorizedMerchantTransId !== void 0) {
7197
7258
  body.authorized_merchant_trans_id = opts.authorizedMerchantTransId;
7198
7259
  }
7260
+ applyPriceAnnotation(body, opts);
7199
7261
  if (!isYes) {
7200
7262
  const isResume = opts.authorizedMerchantTransId !== void 0;
7201
7263
  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.`;