tixbit 0.2.1 → 0.2.2
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/cli.js +28 -6
- package/dist/index.js +14 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -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`, do not start another checkout. Contact TixBit support with the order reference so the charge and ticket can be reconciled. 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.
|
|
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,
|
|
@@ -1049,7 +1063,15 @@ 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) return state.result;
|
|
1067
|
+
if (state.paymentAttempted) return {
|
|
1068
|
+
success: false,
|
|
1069
|
+
status: "pending",
|
|
1070
|
+
orderReference,
|
|
1071
|
+
amountCents: state.amountCents,
|
|
1072
|
+
error: { code: "PURCHASE_OUTCOME_AMBIGUOUS", message: "Payment may have been submitted, but the result is unknown." },
|
|
1073
|
+
action: "Do not retry payment or start another checkout. Contact TixBit support with this order reference."
|
|
1074
|
+
};
|
|
1053
1075
|
const approval = await linkCli(["spend-request", "retrieve", state.spendRequestId, "--include", "shared_payment_token"]);
|
|
1054
1076
|
if (["denied", "declined", "expired", "canceled", "cancelled"].includes(String(approval.status))) {
|
|
1055
1077
|
return {
|
|
@@ -1097,6 +1119,8 @@ async function completeLinkPurchase(orderReference) {
|
|
|
1097
1119
|
}
|
|
1098
1120
|
});
|
|
1099
1121
|
let decline = false;
|
|
1122
|
+
state.paymentAttempted = true;
|
|
1123
|
+
await saveState(state);
|
|
1100
1124
|
const client2 = new TixBitClient({
|
|
1101
1125
|
paymentEndpoint: paymentEndpoint(),
|
|
1102
1126
|
timeoutMs: 9e4,
|
|
@@ -1123,13 +1147,11 @@ async function completeLinkPurchase(orderReference) {
|
|
|
1123
1147
|
...result.order && !decline ? { order: result.order } : {},
|
|
1124
1148
|
...!result.success ? {
|
|
1125
1149
|
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
|
|
1150
|
+
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
1151
|
} : {}
|
|
1128
1152
|
};
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
await saveState(state);
|
|
1132
|
-
}
|
|
1153
|
+
state.result = output2;
|
|
1154
|
+
await saveState(state);
|
|
1133
1155
|
return output2;
|
|
1134
1156
|
}
|
|
1135
1157
|
|
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,
|