tixbit 0.2.1 → 0.2.3
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 +2 -2
- package/dist/cli.js +54 -7
- package/dist/index.js +14 -0
- package/package.json +1 -1
- package/skills/tixbit/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -82,7 +82,7 @@ tixbit purchase <listing-id> \
|
|
|
82
82
|
|
|
83
83
|
Sign in to Link once, then start a purchase with a total price limit:
|
|
84
84
|
|
|
85
|
-
TixBit
|
|
85
|
+
TixBit needs Node.js 22 or later. The included Link CLI uses your local Link sign-in; TixBit does not ask for a developer API key.
|
|
86
86
|
|
|
87
87
|
```sh
|
|
88
88
|
npx @stripe/link-cli auth login
|
|
@@ -95,7 +95,7 @@ tixbit link start <listing-id> --quantity 1 --email buyer@example.com --max-pric
|
|
|
95
95
|
tixbit link complete <order-reference>
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
The second command checks approval, sends one Stripe MPP credential, and reports whether the ticket was issued. If approval is still pending, it returns the same URL without sending payment.
|
|
98
|
+
The second command checks approval, sends one Stripe MPP credential, and reports whether the ticket was issued. If approval is still pending, it returns the same URL without sending payment. After payment submission, the CLI will not send that payment again. If the result is `pending`, run `tixbit link complete <order-reference>` again later. This checks the same order without resending the payment credential. Do not start another checkout. The CLI stores the purchase key in a private file under `~/.local/state/tixbit/link` (or `XDG_STATE_HOME`) and never prints or saves the Link payment token. Keep that file until the order is settled. Each command returns JSON; `approval_required` and payment failures use exit code 2. A completed purchase returns an order receipt URL, and TixBit sends the order confirmation and ticket delivery emails to the buyer address.
|
|
99
99
|
|
|
100
100
|
Each spend request includes its TixBit order reference in the approval details. Link can still rate limit a matching amount and merchant for a short time, even after a request is canceled. If Link rejects a request, the CLI reports a safe error code such as `LINK_DUPLICATE_REQUEST` or `LINK_NETWORK_UNAVAILABLE` without printing Link credentials.
|
|
101
101
|
|
package/dist/cli.js
CHANGED
|
@@ -428,6 +428,20 @@ var TixBitClient = class {
|
|
|
428
428
|
const body = await response.json().catch(() => ({}));
|
|
429
429
|
const orderReference = normalizeOrderReference(body.orderReference);
|
|
430
430
|
const receiptUrl = normalizeReceiptUrl(body.receiptUrl);
|
|
431
|
+
if (response.status >= 500 && body.status !== "manual_review_required") {
|
|
432
|
+
return {
|
|
433
|
+
success: false,
|
|
434
|
+
status: "pending",
|
|
435
|
+
idempotencyKey,
|
|
436
|
+
orderReference,
|
|
437
|
+
receiptUrl,
|
|
438
|
+
error: {
|
|
439
|
+
code: "PURCHASE_OUTCOME_AMBIGUOUS",
|
|
440
|
+
message: "The server failed to confirm the purchase outcome."
|
|
441
|
+
},
|
|
442
|
+
action: "Check the order with the same idempotency key. Do not create a new payment or purchase attempt."
|
|
443
|
+
};
|
|
444
|
+
}
|
|
431
445
|
if (response.status === 402) {
|
|
432
446
|
const order = normalizePurchaseOrder(
|
|
433
447
|
body.order,
|
|
@@ -870,7 +884,7 @@ var SPEND_REQUEST_ID = /^lsrq_[A-Za-z0-9]+$/;
|
|
|
870
884
|
var require2 = createRequire(import.meta.url);
|
|
871
885
|
function linkCliEntry() {
|
|
872
886
|
if (Number(process.versions.node.split(".")[0]) < 22) {
|
|
873
|
-
throw new LinkCheckoutError("LINK_NODE_UNSUPPORTED", "TixBit
|
|
887
|
+
throw new LinkCheckoutError("LINK_NODE_UNSUPPORTED", "TixBit needs Node.js 22 or later.");
|
|
874
888
|
}
|
|
875
889
|
try {
|
|
876
890
|
return join(dirname(require2.resolve("@stripe/link-cli/package.json")), "dist", "cli.js");
|
|
@@ -1049,7 +1063,39 @@ async function startLinkPurchase(input) {
|
|
|
1049
1063
|
}
|
|
1050
1064
|
async function completeLinkPurchase(orderReference) {
|
|
1051
1065
|
const state = await loadState(orderReference);
|
|
1052
|
-
if (state.result
|
|
1066
|
+
if (state.result && ["fulfilled", "payment_failed", "rejected"].includes(state.result.status)) return state.result;
|
|
1067
|
+
if (state.paymentAttempted) {
|
|
1068
|
+
const request2 = JSON.parse(state.requestBody);
|
|
1069
|
+
const result2 = await new TixBitClient({ paymentEndpoint: paymentEndpoint(), timeoutMs: 3e4 }).purchaseTickets(request2);
|
|
1070
|
+
if (result2.orderReference && result2.orderReference !== orderReference) {
|
|
1071
|
+
throw new LinkCheckoutError("ORDER_REFERENCE_CHANGED", "TixBit returned a different order reference. Check the order before another payment.");
|
|
1072
|
+
}
|
|
1073
|
+
if (state.result?.status === "manual_review_required" && result2.status !== "fulfilled") {
|
|
1074
|
+
return state.result;
|
|
1075
|
+
}
|
|
1076
|
+
const sameOrder = result2.orderReference === orderReference;
|
|
1077
|
+
const terminalFailure = sameOrder && (result2.status === "payment_failed" || result2.status === "rejected");
|
|
1078
|
+
const manualReview = sameOrder && result2.status === "manual_review_required";
|
|
1079
|
+
const fulfilled = sameOrder && result2.success && result2.status === "fulfilled";
|
|
1080
|
+
const output3 = {
|
|
1081
|
+
success: fulfilled,
|
|
1082
|
+
status: fulfilled || manualReview || terminalFailure ? result2.status : "pending",
|
|
1083
|
+
orderReference,
|
|
1084
|
+
amountCents: state.amountCents,
|
|
1085
|
+
...sameOrder && result2.order ? { order: result2.order } : {},
|
|
1086
|
+
...sameOrder && result2.receiptUrl ? { receiptUrl: result2.receiptUrl } : {},
|
|
1087
|
+
...!fulfilled ? {
|
|
1088
|
+
error: sameOrder && (manualReview || terminalFailure) && result2.error ? result2.error : { code: "PURCHASE_OUTCOME_AMBIGUOUS", message: "The order is still being checked." },
|
|
1089
|
+
action: terminalFailure || manualReview ? result2.action ?? "Contact TixBit support with this order reference. Do not submit another payment." : "Run the same complete command again later. Do not start another payment or purchase."
|
|
1090
|
+
} : {}
|
|
1091
|
+
};
|
|
1092
|
+
if (output3.success || terminalFailure || output3.status === "manual_review_required") {
|
|
1093
|
+
state.result = output3;
|
|
1094
|
+
await saveState(state);
|
|
1095
|
+
}
|
|
1096
|
+
return output3;
|
|
1097
|
+
}
|
|
1098
|
+
if (state.result) return state.result;
|
|
1053
1099
|
const approval = await linkCli(["spend-request", "retrieve", state.spendRequestId, "--include", "shared_payment_token"]);
|
|
1054
1100
|
if (["denied", "declined", "expired", "canceled", "cancelled"].includes(String(approval.status))) {
|
|
1055
1101
|
return {
|
|
@@ -1097,6 +1143,8 @@ async function completeLinkPurchase(orderReference) {
|
|
|
1097
1143
|
}
|
|
1098
1144
|
});
|
|
1099
1145
|
let decline = false;
|
|
1146
|
+
state.paymentAttempted = true;
|
|
1147
|
+
await saveState(state);
|
|
1100
1148
|
const client2 = new TixBitClient({
|
|
1101
1149
|
paymentEndpoint: paymentEndpoint(),
|
|
1102
1150
|
timeoutMs: 9e4,
|
|
@@ -1121,15 +1169,14 @@ async function completeLinkPurchase(orderReference) {
|
|
|
1121
1169
|
orderReference,
|
|
1122
1170
|
amountCents: state.amountCents,
|
|
1123
1171
|
...result.order && !decline ? { order: result.order } : {},
|
|
1172
|
+
...result.receiptUrl && !decline ? { receiptUrl: result.receiptUrl } : {},
|
|
1124
1173
|
...!result.success ? {
|
|
1125
1174
|
error: decline ? { code: "CARD_DECLINED", message: "Stripe declined the card selected in Link." } : result.error,
|
|
1126
|
-
action: decline ? "Select another card in Link and start a new spend approval. No ticket was issued." : result.action
|
|
1175
|
+
action: decline ? "Select another card in Link and start a new spend approval. No ticket was issued." : result.status === "pending" ? "Payment may have succeeded. Do not retry or start another checkout. Contact TixBit support with this order reference." : result.action
|
|
1127
1176
|
} : {}
|
|
1128
1177
|
};
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
await saveState(state);
|
|
1132
|
-
}
|
|
1178
|
+
state.result = output2;
|
|
1179
|
+
await saveState(state);
|
|
1133
1180
|
return output2;
|
|
1134
1181
|
}
|
|
1135
1182
|
|
package/dist/index.js
CHANGED
|
@@ -408,6 +408,20 @@ var TixBitClient = class {
|
|
|
408
408
|
const body = await response.json().catch(() => ({}));
|
|
409
409
|
const orderReference = normalizeOrderReference(body.orderReference);
|
|
410
410
|
const receiptUrl = normalizeReceiptUrl(body.receiptUrl);
|
|
411
|
+
if (response.status >= 500 && body.status !== "manual_review_required") {
|
|
412
|
+
return {
|
|
413
|
+
success: false,
|
|
414
|
+
status: "pending",
|
|
415
|
+
idempotencyKey,
|
|
416
|
+
orderReference,
|
|
417
|
+
receiptUrl,
|
|
418
|
+
error: {
|
|
419
|
+
code: "PURCHASE_OUTCOME_AMBIGUOUS",
|
|
420
|
+
message: "The server failed to confirm the purchase outcome."
|
|
421
|
+
},
|
|
422
|
+
action: "Check the order with the same idempotency key. Do not create a new payment or purchase attempt."
|
|
423
|
+
};
|
|
424
|
+
}
|
|
411
425
|
if (response.status === 402) {
|
|
412
426
|
const order = normalizePurchaseOrder(
|
|
413
427
|
body.order,
|
package/package.json
CHANGED
package/skills/tixbit/SKILL.md
CHANGED
|
@@ -64,7 +64,7 @@ npx tixbit purchase <listingId> \
|
|
|
64
64
|
- The older `buy` web route supports 4-12 alphanumeric IDs only. The new Link MPP command accepts the listing IDs supported by the MPP server.
|
|
65
65
|
- Without a signed-in user integration, seller commands return browser sign-in guidance and do not read or submit listings. Browser-to-CLI seller sessions are not supported. Do not extract browser tokens. Optional authorized integrations may supply `TIXBIT_ACCESS_TOKEN`; seller creation still requires `--confirm`, `termsAccepted: true`, and server ownership/access checks.
|
|
66
66
|
- All commands emit JSON, including errors. Preserve full case-sensitive IDs.
|
|
67
|
-
- Never
|
|
67
|
+
- Never resend an uncertain Link payment. Repeat `link complete` with the same order reference to check server recovery without sending a second credential. Read seller listings after uncertain creation.
|
|
68
68
|
- No bids or negotiation are available. Do not claim a price reduction.
|
|
69
69
|
|
|
70
70
|
## Required workflow
|