@vonpay/checkout-cli 0.20.0 → 0.21.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 +77 -17
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1358,7 +1358,7 @@ function parseMetadata(pairs) {
|
|
|
1358
1358
|
return out;
|
|
1359
1359
|
}
|
|
1360
1360
|
var METADATA_FILTER_KEY = /^[A-Za-z0-9_.:-]{1,64}$/;
|
|
1361
|
-
var METADATA_FILTER_VALUE_MAX =
|
|
1361
|
+
var METADATA_FILTER_VALUE_MAX = 128;
|
|
1362
1362
|
function assertMetadataFilterKey(key, flag) {
|
|
1363
1363
|
if (!METADATA_FILTER_KEY.test(key)) {
|
|
1364
1364
|
throw new Error(
|
|
@@ -1378,6 +1378,41 @@ function parseMetadataFilter(raw, flag) {
|
|
|
1378
1378
|
return { [key]: value };
|
|
1379
1379
|
}
|
|
1380
1380
|
|
|
1381
|
+
// src/utils/processor-detail.ts
|
|
1382
|
+
import { SAFE_CODE_PATTERN, SAFE_CONNECTION_ID_PATTERN, safeValueOrWithheld } from "@vonpay/checkout-node";
|
|
1383
|
+
var INCLUDE_PROCESSOR_DETAIL_HELP = "With --json: also print the card processor's own answer (untrusted text), every try with its connection name, the connection's name, and the card's first six digits";
|
|
1384
|
+
var PROCESSOR_DETAIL_KEYS = ["processorResponse", "attempts", "attemptsStatus"];
|
|
1385
|
+
function cardForDisplay(card) {
|
|
1386
|
+
if (card === null || typeof card !== "object" || Array.isArray(card)) return card;
|
|
1387
|
+
const c = card;
|
|
1388
|
+
return { brand: c.brand ?? null, last4: c.last4 ?? null };
|
|
1389
|
+
}
|
|
1390
|
+
function attemptSummary(a) {
|
|
1391
|
+
return {
|
|
1392
|
+
connectionId: safeValueOrWithheld(a.processorConnection?.id, SAFE_CONNECTION_ID_PATTERN),
|
|
1393
|
+
result: safeValueOrWithheld(a.result, SAFE_CODE_PATTERN),
|
|
1394
|
+
declineCode: safeValueOrWithheld(a.declineCode, SAFE_CODE_PATTERN),
|
|
1395
|
+
outcome: safeValueOrWithheld(a.outcome, SAFE_CODE_PATTERN)
|
|
1396
|
+
};
|
|
1397
|
+
}
|
|
1398
|
+
function attemptsStatusForDisplay(value) {
|
|
1399
|
+
return safeValueOrWithheld(value, SAFE_CODE_PATTERN);
|
|
1400
|
+
}
|
|
1401
|
+
function connectionForDisplay(connection) {
|
|
1402
|
+
if (connection === null || typeof connection !== "object" || Array.isArray(connection)) return connection;
|
|
1403
|
+
return { id: connection.id ?? null };
|
|
1404
|
+
}
|
|
1405
|
+
function withoutProcessorDetail(obj, includeProcessorDetail) {
|
|
1406
|
+
const src = obj;
|
|
1407
|
+
if (includeProcessorDetail) return src;
|
|
1408
|
+
const out = { ...src };
|
|
1409
|
+
for (const k of PROCESSOR_DETAIL_KEYS) delete out[k];
|
|
1410
|
+
if ("card" in out) out.card = cardForDisplay(out.card);
|
|
1411
|
+
if ("processorConnection" in out) out.processorConnection = connectionForDisplay(out.processorConnection);
|
|
1412
|
+
return out;
|
|
1413
|
+
}
|
|
1414
|
+
var PROCESSOR_DETAIL_NEEDS_JSON = "--include-processor-detail is used with --json.";
|
|
1415
|
+
|
|
1381
1416
|
// src/commands/payment-reports.ts
|
|
1382
1417
|
import chalk8 from "chalk";
|
|
1383
1418
|
import { formatMinorUnits as formatMinorUnits2 } from "@vonpay/checkout-node";
|
|
@@ -1430,12 +1465,24 @@ var PAYMENT_LIST_JSON_FIELDS = [
|
|
|
1430
1465
|
"declineCode",
|
|
1431
1466
|
"action",
|
|
1432
1467
|
"ruleCode",
|
|
1433
|
-
"networkAdvice"
|
|
1468
|
+
"networkAdvice",
|
|
1469
|
+
// Each try as the safe summary only (connection id, result, decline code, outcome), and
|
|
1470
|
+
// whether that list is the full record. --include-processor-detail prints the whole tries.
|
|
1471
|
+
"attempts",
|
|
1472
|
+
"attemptsStatus"
|
|
1434
1473
|
];
|
|
1435
|
-
function listItemJson(pi, includeMetadata) {
|
|
1436
|
-
if (includeMetadata) return pi;
|
|
1474
|
+
function listItemJson(pi, includeMetadata, includeProcessorDetail) {
|
|
1437
1475
|
const src = pi;
|
|
1438
|
-
|
|
1476
|
+
const out = includeMetadata ? { ...src } : Object.fromEntries(PAYMENT_LIST_JSON_FIELDS.filter((k) => src[k] !== void 0).map((k) => [k, src[k]]));
|
|
1477
|
+
if (includeProcessorDetail) {
|
|
1478
|
+
if (src.processorResponse !== void 0) out.processorResponse = src.processorResponse;
|
|
1479
|
+
return out;
|
|
1480
|
+
}
|
|
1481
|
+
const safe = withoutProcessorDetail(out, false);
|
|
1482
|
+
if (src.attemptsStatus !== void 0) safe.attemptsStatus = attemptsStatusForDisplay(src.attemptsStatus);
|
|
1483
|
+
if (pi.attempts === null) safe.attempts = null;
|
|
1484
|
+
else if (Array.isArray(pi.attempts)) safe.attempts = pi.attempts.map(attemptSummary);
|
|
1485
|
+
return safe;
|
|
1439
1486
|
}
|
|
1440
1487
|
var ALL_DEFAULT_MAX_ITEMS = 1e4;
|
|
1441
1488
|
function stoppedAtDefaultCap() {
|
|
@@ -1450,6 +1497,7 @@ function buildListParams(opts) {
|
|
|
1450
1497
|
if (opts.startingAfter !== void 0) params.startingAfter = opts.startingAfter;
|
|
1451
1498
|
if (opts.maxItems !== void 0 && !opts.all) throw new Error("--max-items is used with --all.");
|
|
1452
1499
|
if (opts.includeMetadata && !opts.json) throw new Error("--include-metadata is used with --json.");
|
|
1500
|
+
if (opts.includeProcessorDetail && !opts.json) throw new Error(PROCESSOR_DETAIL_NEEDS_JSON);
|
|
1453
1501
|
const maxItems = opts.maxItems !== void 0 ? positiveWholeNumber(opts.maxItems, "--max-items") : opts.all ? ALL_DEFAULT_MAX_ITEMS : void 0;
|
|
1454
1502
|
return { params, ...maxItems !== void 0 ? { maxItems } : {} };
|
|
1455
1503
|
}
|
|
@@ -1514,7 +1562,7 @@ var FILTER_HELP = {
|
|
|
1514
1562
|
createdLt: "End of the window, exclusive (default: now). At most 31 days after the start (7 with summary --group-by hour)",
|
|
1515
1563
|
outcome: "Only these outcomes, comma-separated (e.g. bank_declined,refused_before_bank)",
|
|
1516
1564
|
store: "Only payments for this connected store hostname (e.g. shop.example.com)",
|
|
1517
|
-
metadata: "Only payments with this metadata tag, key=value (ONE tag; key 1-64 of letters, digits, _ . : -; value 1-
|
|
1565
|
+
metadata: "Only payments with this metadata tag, key=value (ONE tag; key 1-64 of letters, digits, _ . : -; value 1-128 characters)",
|
|
1518
1566
|
cardBrand: "Only these card brands, comma-separated (visa, mastercard, amex, discover, unionpay, jcb, diners, unknown)",
|
|
1519
1567
|
currency: "Only payments in this currency (e.g. USD)",
|
|
1520
1568
|
initiator: "merchant (merchant-initiated charges on a saved card) or customer",
|
|
@@ -1541,7 +1589,7 @@ function addPaymentReportCommands(intents) {
|
|
|
1541
1589
|
).option("--max-items <n>", `With --all: stop after this many payments (default ${ALL_DEFAULT_MAX_ITEMS})`).option(
|
|
1542
1590
|
"--json",
|
|
1543
1591
|
"Output JSON: each payment's status, outcome, amount, card, store and decline fields \u2014 not your metadata (with --all: one JSON array)"
|
|
1544
|
-
).option("--include-metadata", "With --json: print every field of each payment, your metadata included").action(async (opts) => {
|
|
1592
|
+
).option("--include-metadata", "With --json: print every field of each payment, your metadata included (not the processor detail: see --include-processor-detail)").option("--include-processor-detail", INCLUDE_PROCESSOR_DETAIL_HELP).action(async (opts) => {
|
|
1545
1593
|
let built;
|
|
1546
1594
|
try {
|
|
1547
1595
|
built = buildListParams(opts);
|
|
@@ -1558,7 +1606,7 @@ function addPaymentReportCommands(intents) {
|
|
|
1558
1606
|
});
|
|
1559
1607
|
if (opts.json) {
|
|
1560
1608
|
const items = [];
|
|
1561
|
-
for await (const pi of pager) items.push(listItemJson(pi, opts.includeMetadata));
|
|
1609
|
+
for await (const pi of pager) items.push(listItemJson(pi, opts.includeMetadata, opts.includeProcessorDetail));
|
|
1562
1610
|
spinner.stop();
|
|
1563
1611
|
console.log(jsonOutput(items));
|
|
1564
1612
|
if (opts.maxItems === void 0 && items.length >= ALL_DEFAULT_MAX_ITEMS) console.error(stoppedAtDefaultCap());
|
|
@@ -1579,7 +1627,12 @@ function addPaymentReportCommands(intents) {
|
|
|
1579
1627
|
const page = await client.paymentIntents.list(built.params);
|
|
1580
1628
|
spinner.stop();
|
|
1581
1629
|
if (opts.json) {
|
|
1582
|
-
console.log(
|
|
1630
|
+
console.log(
|
|
1631
|
+
jsonOutput({
|
|
1632
|
+
...page,
|
|
1633
|
+
data: page.data.map((pi) => listItemJson(pi, opts.includeMetadata, opts.includeProcessorDetail))
|
|
1634
|
+
})
|
|
1635
|
+
);
|
|
1583
1636
|
return;
|
|
1584
1637
|
}
|
|
1585
1638
|
for (const line of paymentListLines(page)) console.log(line);
|
|
@@ -1620,6 +1673,9 @@ function addPaymentReportCommands(intents) {
|
|
|
1620
1673
|
}
|
|
1621
1674
|
|
|
1622
1675
|
// src/commands/payment-intents.ts
|
|
1676
|
+
function refuseProcessorDetailWithoutJson(opts) {
|
|
1677
|
+
if (opts.includeProcessorDetail && !opts.json) exitWithCliError(PROCESSOR_DETAIL_NEEDS_JSON, chalk9.red(PROCESSOR_DETAIL_NEEDS_JSON));
|
|
1678
|
+
}
|
|
1623
1679
|
var MIT_INITIATORS = ["merchant", "customer"];
|
|
1624
1680
|
var MIT_REASONS = [
|
|
1625
1681
|
"recurring",
|
|
@@ -1755,7 +1811,8 @@ function paymentIntentsCommand() {
|
|
|
1755
1811
|
).option("--buyer-email <email>", "Buyer email for this charge").option(
|
|
1756
1812
|
"--idempotency-key <key>",
|
|
1757
1813
|
"Idempotency key for this charge. Reuse the SAME key to retry the same charge safely. REQUIRED on a live key; on a sandbox key generated (and printed) when omitted"
|
|
1758
|
-
).addOption(retiredConfirmLiveOption()).option("--json", "Output raw JSON").action(async (raw) => {
|
|
1814
|
+
).addOption(retiredConfirmLiveOption()).option("--json", "Output raw JSON").option("--include-processor-detail", INCLUDE_PROCESSOR_DETAIL_HELP).action(async (raw) => {
|
|
1815
|
+
refuseProcessorDetailWithoutJson(raw);
|
|
1759
1816
|
const apiKey = requireApiKey();
|
|
1760
1817
|
const opts = { ...raw, amount: minorUnitsOrExit(raw.amount, "--amount") };
|
|
1761
1818
|
const captureMethod = opts.captureMethod?.toLowerCase();
|
|
@@ -1797,7 +1854,7 @@ function paymentIntentsCommand() {
|
|
|
1797
1854
|
});
|
|
1798
1855
|
spinner.stop();
|
|
1799
1856
|
if (opts.json) {
|
|
1800
|
-
console.log(jsonOutput(intent));
|
|
1857
|
+
console.log(jsonOutput(withoutProcessorDetail(intent, opts.includeProcessorDetail)));
|
|
1801
1858
|
} else {
|
|
1802
1859
|
console.log(chalk9.green("\u2713 Payment intent created"));
|
|
1803
1860
|
printPaymentIntent(intent);
|
|
@@ -1809,14 +1866,15 @@ function paymentIntentsCommand() {
|
|
|
1809
1866
|
});
|
|
1810
1867
|
intents.command("get").description(
|
|
1811
1868
|
"Read a payment intent back \u2014 the way to check a payment whose outcome was unclear before doing anything else"
|
|
1812
|
-
).argument("<id>", "Payment intent ID (vpi_*)").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
1869
|
+
).argument("<id>", "Payment intent ID (vpi_*)").option("--json", "Output raw JSON").option("--include-processor-detail", INCLUDE_PROCESSOR_DETAIL_HELP).action(async (id, opts) => {
|
|
1870
|
+
refuseProcessorDetailWithoutJson(opts);
|
|
1813
1871
|
const client = makeCheckoutClient();
|
|
1814
1872
|
const spinner = startSpinner("Fetching payment intent...");
|
|
1815
1873
|
try {
|
|
1816
1874
|
const intent = await client.paymentIntents.retrieve(id);
|
|
1817
1875
|
spinner.stop();
|
|
1818
1876
|
if (opts.json) {
|
|
1819
|
-
console.log(jsonOutput(intent));
|
|
1877
|
+
console.log(jsonOutput(withoutProcessorDetail(intent, opts.includeProcessorDetail)));
|
|
1820
1878
|
} else {
|
|
1821
1879
|
printPaymentIntent(intent);
|
|
1822
1880
|
}
|
|
@@ -1831,8 +1889,9 @@ function paymentIntentsCommand() {
|
|
|
1831
1889
|
).option(
|
|
1832
1890
|
"--idempotency-key <key>",
|
|
1833
1891
|
"Idempotency key. Reuse the SAME key to retry safely. REQUIRED on a live key; on a sandbox key generated (and printed) when omitted"
|
|
1834
|
-
).addOption(retiredConfirmLiveOption()).option("--json", "Output raw JSON").action(
|
|
1892
|
+
).addOption(retiredConfirmLiveOption()).option("--json", "Output raw JSON").option("--include-processor-detail", INCLUDE_PROCESSOR_DETAIL_HELP).action(
|
|
1835
1893
|
async (id, opts) => {
|
|
1894
|
+
refuseProcessorDetailWithoutJson(opts);
|
|
1836
1895
|
const apiKey = requireApiKey();
|
|
1837
1896
|
const amountToCapture = optionalMinorUnitsOrExit(
|
|
1838
1897
|
opts.amountToCapture,
|
|
@@ -1866,7 +1925,7 @@ function paymentIntentsCommand() {
|
|
|
1866
1925
|
);
|
|
1867
1926
|
spinner.stop();
|
|
1868
1927
|
if (opts.json) {
|
|
1869
|
-
console.log(jsonOutput(intent));
|
|
1928
|
+
console.log(jsonOutput(withoutProcessorDetail(intent, opts.includeProcessorDetail)));
|
|
1870
1929
|
} else {
|
|
1871
1930
|
const captureLabel = amountToCapture !== void 0 ? ` (partial: ${formatMinorUnits3(amountToCapture, intent.currency)})` : "";
|
|
1872
1931
|
console.log(chalk9.green(`\u2713 Payment intent captured${captureLabel}`));
|
|
@@ -1881,8 +1940,9 @@ function paymentIntentsCommand() {
|
|
|
1881
1940
|
intents.command("void").description("Void an authorized (uncaptured) payment intent").argument("<id>", "Payment intent ID (vpi_*)").option(
|
|
1882
1941
|
"--idempotency-key <key>",
|
|
1883
1942
|
"Idempotency key. Reuse the SAME key to retry safely. REQUIRED on a live key; on a sandbox key generated (and printed) when omitted"
|
|
1884
|
-
).addOption(retiredConfirmLiveOption()).option("--json", "Output raw JSON").action(
|
|
1943
|
+
).addOption(retiredConfirmLiveOption()).option("--json", "Output raw JSON").option("--include-processor-detail", INCLUDE_PROCESSOR_DETAIL_HELP).action(
|
|
1885
1944
|
async (id, opts) => {
|
|
1945
|
+
refuseProcessorDetailWithoutJson(opts);
|
|
1886
1946
|
const apiKey = requireApiKey();
|
|
1887
1947
|
refuseUnsafeLiveDestination(apiKey);
|
|
1888
1948
|
const idempotencyKey = idempotencyKeyFor(opts.idempotencyKey, "void", apiKey);
|
|
@@ -1905,7 +1965,7 @@ function paymentIntentsCommand() {
|
|
|
1905
1965
|
const intent = await client.paymentIntents.void(id, { idempotencyKey });
|
|
1906
1966
|
spinner.stop();
|
|
1907
1967
|
if (opts.json) {
|
|
1908
|
-
console.log(jsonOutput(intent));
|
|
1968
|
+
console.log(jsonOutput(withoutProcessorDetail(intent, opts.includeProcessorDetail)));
|
|
1909
1969
|
} else {
|
|
1910
1970
|
console.log(chalk9.green("\u2713 Payment intent voided"));
|
|
1911
1971
|
printPaymentIntent(intent);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vonpay/checkout-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Von Payments CLI — developer tools for checkout integration",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"node": ">=20"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@vonpay/checkout-node": "^4.
|
|
23
|
+
"@vonpay/checkout-node": "^4.9.0",
|
|
24
24
|
"commander": "^13.0.0",
|
|
25
25
|
"chalk": "^5.4.0",
|
|
26
26
|
"ora": "^8.2.0"
|