@vonpay/checkout-cli 0.16.0 → 0.17.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/README.md +1 -1
- package/dist/index.js +110 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ All commands are namespaced under `vonpay checkout`:
|
|
|
53
53
|
| `vonpay checkout refunds list` | List one payment's refunds and its refund totals (`--payment-intent` or `--transaction`) |
|
|
54
54
|
| `vonpay checkout tokens create` | Create a payment-method token for saved-card / MIT flows |
|
|
55
55
|
| `vonpay checkout capabilities` | Show what this merchant's binder supports |
|
|
56
|
-
| `vonpay checkout trigger <event>` | Trigger a synthetic webhook event against your local endpoint (`
|
|
56
|
+
| `vonpay checkout trigger <event>` | Trigger a synthetic webhook event against your local endpoint (`charge.*`, `refund.failed`, `payment_intent.*`, `mirror.order.created`, `subscription.*`, `merchant.card_testing_suspected`, `session.*`; `vonpay checkout trigger --help` lists them all) |
|
|
57
57
|
| `vonpay checkout listen` | Stream live webhook delivery attempts; optionally re-forward each to a local URL with `--forward-to` |
|
|
58
58
|
| `vonpay checkout health` | Check API health and latency |
|
|
59
59
|
| `vonpay checkout doctor` | Diagnose runtime + env + live API probe |
|
package/dist/index.js
CHANGED
|
@@ -474,6 +474,25 @@ var FIELD_PRINTERS = {
|
|
|
474
474
|
orderCurrency: (e) => e.orderCurrency ? `Store order currency: ${safeInline(String(e.orderCurrency))}` : null,
|
|
475
475
|
orderStatus: (e) => e.orderStatus ? `Store order status: ${safeInline(String(e.orderStatus))}` : null,
|
|
476
476
|
orderPaymentStatus: (e) => e.orderPaymentStatus ? `Store order payment status: ${safeInline(String(e.orderPaymentStatus))}` : null,
|
|
477
|
+
// A refused subscription change (built ahead of the API's production release). Validated by
|
|
478
|
+
// the SDK, printed through safeInline all the same.
|
|
479
|
+
subscriptionStatus: (e) => e.subscriptionStatus ? `Subscription status: ${safeInline(String(e.subscriptionStatus))}` : null,
|
|
480
|
+
refusalReason: (e) => e.refusalReason ? `Refused because: ${safeInline(String(e.refusalReason))}` : null,
|
|
481
|
+
minDate: (e) => e.minDate ? `Earliest date allowed: ${safeInline(String(e.minDate))}` : null,
|
|
482
|
+
maxDate: (e) => e.maxDate ? `Latest date allowed: ${safeInline(String(e.maxDate))}` : null,
|
|
483
|
+
currentAmount: (e) => typeof e.currentAmount === "number" ? `Current highest renewal charge: ${safeInline(String(e.currentAmount))} (minor units)` : null,
|
|
484
|
+
maxAmount: (e) => typeof e.maxAmount === "number" ? `Most this key may make a renewal charge: ${safeInline(String(e.maxAmount))} (minor units)` : e.maxAmount === null ? "Most this key may make a renewal charge: none \u2014 this key may only lower the price" : null,
|
|
485
|
+
amountCurrency: (e) => e.amountCurrency ? `Renewal charge currency: ${safeInline(String(e.amountCurrency))}` : null,
|
|
486
|
+
pendingKind: (e) => e.pendingKind ? `Schedule change waiting for its customer notice: ${safeInline(String(e.pendingKind))}` : null,
|
|
487
|
+
// A charge the payment provider refused before any money moved (built ahead
|
|
488
|
+
// of the API's production release): the failed payment intent that records
|
|
489
|
+
// the attempt. The SDK has checked it is a vpi_* id; printed through
|
|
490
|
+
// safeInline all the same. The next step depends on the code: a card the
|
|
491
|
+
// processor is still storing (payment_method_unvaulted) is retried as is
|
|
492
|
+
// after a short wait; every other refusal needs the request or card fixed.
|
|
493
|
+
// Both under a NEW key: the refused record does not hold the key, and the
|
|
494
|
+
// processor may refuse a resend under the same one.
|
|
495
|
+
paymentIntentId: (e) => e.paymentIntentId ? `Refused attempt recorded as: ${safeInline(String(e.paymentIntentId))} (status failed, nothing was charged; ` + (e.code === "payment_method_unvaulted" ? "wait a few seconds, then send the same charge again with a NEW --idempotency-key)" : "fix the request or the card, then charge with a NEW --idempotency-key)") : null,
|
|
477
496
|
// On a withheld retry the SDK sets this to RETRY_WITHHELD_HELP.llmHint — the
|
|
478
497
|
// one wording for every surface — so it is printed as is.
|
|
479
498
|
llmHint: (e) => e.llmHint ? `Hint: ${str(e.llmHint)}` : null,
|
|
@@ -1680,6 +1699,15 @@ var SUPPORTED_EVENTS = [
|
|
|
1680
1699
|
"payment_intent.failed",
|
|
1681
1700
|
"payment_intent.cancelled",
|
|
1682
1701
|
"mirror.order.created",
|
|
1702
|
+
// Opt-in events (an endpoint gets them only when it lists each by name).
|
|
1703
|
+
// Payloads follow checkout's own "Send test event" samples, which are built
|
|
1704
|
+
// by the same code as the real events.
|
|
1705
|
+
"subscription.created",
|
|
1706
|
+
"subscription.renewed",
|
|
1707
|
+
"subscription.payment_failed",
|
|
1708
|
+
"subscription.cancelled",
|
|
1709
|
+
"subscription.updated",
|
|
1710
|
+
"merchant.card_testing_suspected",
|
|
1683
1711
|
"session.succeeded",
|
|
1684
1712
|
"session.failed"
|
|
1685
1713
|
];
|
|
@@ -1701,6 +1729,57 @@ function warnIfUnsubscribable(event, write = (m) => console.warn(m)) {
|
|
|
1701
1729
|
return true;
|
|
1702
1730
|
}
|
|
1703
1731
|
var PROCESSOR_CONNECTION = null;
|
|
1732
|
+
function subscriptionEventData(event, paymentIntentId, amount, currency) {
|
|
1733
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1734
|
+
const inAMonth = now + 30 * 24 * 60 * 60;
|
|
1735
|
+
const base = {
|
|
1736
|
+
subscription_id: `vsub_test_${randomUUID2().replace(/-/g, "").slice(0, 16)}`,
|
|
1737
|
+
status: "active",
|
|
1738
|
+
billing_cycle: null,
|
|
1739
|
+
next_bill_at: inAMonth,
|
|
1740
|
+
amount: null,
|
|
1741
|
+
renewal_amount: amount,
|
|
1742
|
+
currency,
|
|
1743
|
+
payment_intent_id: null,
|
|
1744
|
+
action: null,
|
|
1745
|
+
decline_message: null,
|
|
1746
|
+
decline_code: null,
|
|
1747
|
+
cancel_reason: null,
|
|
1748
|
+
changed_fields: null,
|
|
1749
|
+
// Who made the change (served since checkout's production release of 2026-10-30): an API key
|
|
1750
|
+
// with no id or label on these samples. Set on every event.
|
|
1751
|
+
actor: { type: "api_key", api_key_id: null, label: null },
|
|
1752
|
+
// A cancel scheduled for the end of the paid period, and the discount on future
|
|
1753
|
+
// renewals (served since 2026-10-30): none on these samples.
|
|
1754
|
+
cancel_at_period_end: false,
|
|
1755
|
+
discount: null,
|
|
1756
|
+
// The merchant's own sign-up metadata; `{}` when none was sent.
|
|
1757
|
+
metadata: {}
|
|
1758
|
+
};
|
|
1759
|
+
switch (event) {
|
|
1760
|
+
case "subscription.created":
|
|
1761
|
+
return { ...base, billing_cycle: 1, amount, payment_intent_id: paymentIntentId };
|
|
1762
|
+
case "subscription.renewed":
|
|
1763
|
+
return { ...base, billing_cycle: 2, amount, payment_intent_id: paymentIntentId };
|
|
1764
|
+
case "subscription.payment_failed":
|
|
1765
|
+
return {
|
|
1766
|
+
...base,
|
|
1767
|
+
status: "past_due",
|
|
1768
|
+
billing_cycle: 2,
|
|
1769
|
+
next_bill_at: now + 3 * 24 * 60 * 60,
|
|
1770
|
+
amount,
|
|
1771
|
+
payment_intent_id: paymentIntentId,
|
|
1772
|
+
// The same three values `charge.failed` carries for this code.
|
|
1773
|
+
action: "soft",
|
|
1774
|
+
decline_message: "The card was declined for insufficient funds.",
|
|
1775
|
+
decline_code: "insufficient_funds"
|
|
1776
|
+
};
|
|
1777
|
+
case "subscription.cancelled":
|
|
1778
|
+
return { ...base, status: "cancelled", next_bill_at: null, cancel_reason: "too_expensive" };
|
|
1779
|
+
case "subscription.updated":
|
|
1780
|
+
return { ...base, renewal_amount: Math.max(1, Math.floor(amount * 0.9)), changed_fields: ["renewal_amount"] };
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1704
1783
|
function buildEventData(event, ids, amount, currency) {
|
|
1705
1784
|
const base = {
|
|
1706
1785
|
session_id: ids.sessionId,
|
|
@@ -1709,13 +1788,14 @@ function buildEventData(event, ids, amount, currency) {
|
|
|
1709
1788
|
amount,
|
|
1710
1789
|
currency
|
|
1711
1790
|
};
|
|
1791
|
+
const notARenewal = { subscription_id: null, billing_cycle: null };
|
|
1712
1792
|
switch (event) {
|
|
1713
1793
|
case "session.succeeded":
|
|
1714
1794
|
return base;
|
|
1715
1795
|
case "payment_intent.succeeded":
|
|
1716
|
-
return { ...base, processor_connection: PROCESSOR_CONNECTION };
|
|
1796
|
+
return { ...base, processor_connection: PROCESSOR_CONNECTION, ...notARenewal };
|
|
1717
1797
|
case "charge.succeeded":
|
|
1718
|
-
return { ...base, vp_tx_id: ids.transactionId, card: null, processor_connection: PROCESSOR_CONNECTION };
|
|
1798
|
+
return { ...base, vp_tx_id: ids.transactionId, card: null, processor_connection: PROCESSOR_CONNECTION, ...notARenewal };
|
|
1719
1799
|
case "session.failed":
|
|
1720
1800
|
case "payment_intent.failed":
|
|
1721
1801
|
return {
|
|
@@ -1727,8 +1807,8 @@ function buildEventData(event, ids, amount, currency) {
|
|
|
1727
1807
|
// could be read (as on this ordinary decline) — never permission to retry.
|
|
1728
1808
|
network_advice: null,
|
|
1729
1809
|
network_advice_retry_after_ms: null,
|
|
1730
|
-
// payment_intent.failed only: session.failed
|
|
1731
|
-
...event === "payment_intent.failed" ? { processor_connection: PROCESSOR_CONNECTION } : {}
|
|
1810
|
+
// payment_intent.failed only: session.failed sends neither.
|
|
1811
|
+
...event === "payment_intent.failed" ? { processor_connection: PROCESSOR_CONNECTION, ...notARenewal } : {}
|
|
1732
1812
|
};
|
|
1733
1813
|
case "charge.failed":
|
|
1734
1814
|
return {
|
|
@@ -1744,7 +1824,8 @@ function buildEventData(event, ids, amount, currency) {
|
|
|
1744
1824
|
// Same two fields and values as payment_intent.failed / session.failed.
|
|
1745
1825
|
network_advice: null,
|
|
1746
1826
|
network_advice_retry_after_ms: null,
|
|
1747
|
-
processor_connection: PROCESSOR_CONNECTION
|
|
1827
|
+
processor_connection: PROCESSOR_CONNECTION,
|
|
1828
|
+
...notARenewal
|
|
1748
1829
|
};
|
|
1749
1830
|
case "mirror.order.created":
|
|
1750
1831
|
return {
|
|
@@ -1753,7 +1834,28 @@ function buildEventData(event, ids, amount, currency) {
|
|
|
1753
1834
|
order_status_url: null
|
|
1754
1835
|
};
|
|
1755
1836
|
case "payment_intent.cancelled":
|
|
1756
|
-
return { ...base, cancellation_reason: "buyer_abandoned", processor_connection: PROCESSOR_CONNECTION };
|
|
1837
|
+
return { ...base, cancellation_reason: "buyer_abandoned", processor_connection: PROCESSOR_CONNECTION, ...notARenewal };
|
|
1838
|
+
case "subscription.created":
|
|
1839
|
+
case "subscription.renewed":
|
|
1840
|
+
case "subscription.payment_failed":
|
|
1841
|
+
case "subscription.cancelled":
|
|
1842
|
+
case "subscription.updated":
|
|
1843
|
+
return subscriptionEventData(event, ids.paymentIntentId, amount, currency);
|
|
1844
|
+
case "merchant.card_testing_suspected": {
|
|
1845
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1846
|
+
return {
|
|
1847
|
+
patterns: ["expiry_enumeration", "refusal_burst"],
|
|
1848
|
+
window_start: now - 60 * 60,
|
|
1849
|
+
window_end: now,
|
|
1850
|
+
attempts: 30,
|
|
1851
|
+
refused: 24,
|
|
1852
|
+
accepted: 3,
|
|
1853
|
+
distinct_cards: 12,
|
|
1854
|
+
card: { brand: "visa", last4: "4242" },
|
|
1855
|
+
expiry_variants: 9,
|
|
1856
|
+
blocked: false
|
|
1857
|
+
};
|
|
1858
|
+
}
|
|
1757
1859
|
case "charge.refunded":
|
|
1758
1860
|
return {
|
|
1759
1861
|
...base,
|
|
@@ -1768,7 +1870,8 @@ function buildEventData(event, ids, amount, currency) {
|
|
|
1768
1870
|
is_partial: false,
|
|
1769
1871
|
original_charge_amount: amount,
|
|
1770
1872
|
card: null,
|
|
1771
|
-
processor_connection: PROCESSOR_CONNECTION
|
|
1873
|
+
processor_connection: PROCESSOR_CONNECTION,
|
|
1874
|
+
...notARenewal
|
|
1772
1875
|
};
|
|
1773
1876
|
case "refund.failed":
|
|
1774
1877
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vonpay/checkout-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.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.4.0",
|
|
24
24
|
"commander": "^13.0.0",
|
|
25
25
|
"chalk": "^5.4.0",
|
|
26
26
|
"ora": "^8.2.0"
|