@curless/sinocare-demo 0.63.0 → 0.65.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 CHANGED
@@ -636,6 +636,24 @@ var SINOCARE_GROUPS = [
636
636
  }
637
637
  ]
638
638
  },
639
+ {
640
+ // ⚠️ ITS OWN GROUP, AND THE SUBTITLE SAYS WHY.
641
+ //
642
+ // Every other row on this card ends in money moving. This one does not:
643
+ // UnionPay authenticates the cardholder and hands back a one-time token for
644
+ // the MERCHANT to charge through their own UnionPay acceptance, which
645
+ // Sinocare does not have. Filing it under 卡 next to ACP/UCP would put a
646
+ // button that cannot pay beside two that can, and the difference would be
647
+ // invisible until someone read the result.
648
+ label: "\u94F6\u8054 \xB7 UnionPay Agent Pay",
649
+ rows: [
650
+ {
651
+ title: "\u94F6\u8054\u5361(UAAG)",
652
+ sub: "\u7528\u4F60\u94B1\u5305\u91CC\u7ED1\u7684\u94F6\u8054\u5361 \xB7 \u94F6\u8054\u9875\u9762\u8BA4\u8BC1 \xB7 \u6F14\u793A\u6B62\u4E8E\u51ED\u8BC1\u7B7E\u53D1,\u4E0D\u6263\u6B3E",
653
+ actions: [{ label: "\u5728\u804A\u5929\u91CC\u4ED8\u6B3E", tool: "start_sinocare_uaag_handoff", chat: true }]
654
+ }
655
+ ]
656
+ },
639
657
  {
640
658
  label: "\u5916\u94FE \xB7 \u5546\u5BB6\u6536\u94F6\u53F0",
641
659
  rows: [
@@ -742,7 +760,7 @@ var CHECKOUT_URI = `${CHECKOUT_URI_PREFIX}card-v33.html`;
742
760
  var CHECKOUT_UI_META = uiMeta(CHECKOUT_URI);
743
761
  var WIDGET_META = widgetMeta();
744
762
  var SHARED_TOOLS = storefrontTools({
745
- checkoutOffers: "It offers Card (ACP) / UCP / USDC (x402) / RLUSD (XRP Ledger) in the conversation, the buyer\u2019s own Curless wallet, and an external hosted Payment Link page."
763
+ checkoutOffers: "It offers Card (ACP) / UCP / USDC (x402) / RLUSD (XRP Ledger) in the conversation, the buyer\u2019s own Curless wallet, a UnionPay card the buyer bound to that wallet (UAAG \u2014 which ends at a credential, not a payment), and an external hosted Payment Link page."
746
764
  });
747
765
  var RAIL_TOOLS = [
748
766
  {
@@ -759,7 +777,7 @@ var RAIL_TOOLS = [
759
777
  },
760
778
  {
761
779
  name: "start_sinocare_uaag_handoff",
762
- description: "Buy a Sinocare product over UnionPay Agent Pay (UAAG). Sinocare prices it and opens a checkout session; UnionPay then authenticates the CARDHOLDER on its own page (3DS / Passkey) and issues a one-time payment token. \u26A0\uFE0F This is a HANDOFF, not a purchase: it returns UnionPay\u2019s checkout URL for the person to open, and the flow ends when UnionPay issues the credential. UnionPay\u2019s model has the MERCHANT charge that credential \u2014 it is shaped like an ordinary UnionPay card (token as the card number, DTVC as the CVV2), so the merchant needs UnionPay acceptance. Sinocare\u2019s demo checkout has none, so nothing is charged and no order is placed. Returns ordered:false always.",
780
+ description: "Buy a Sinocare product over UnionPay Agent Pay (UAAG). Sinocare prices it and opens a checkout session; UnionPay then authenticates the CARDHOLDER on its own page (3DS / Passkey) and issues a one-time payment token. \u26A0\uFE0F This is a HANDOFF, not a completed purchase \u2014 and the distinction is subtle enough that the first person through it got it wrong. UnionPay\u2019s page is titled \u300C\u786E\u8BA4\u652F\u4ED8\u300D and shows the amount, merchant and items, so the cardholder really is approving THIS purchase. What their approval produces is a one-time token + DTVC, which the spec describes as the INPUT to an authorization (\u201Cused in authorization\u201D, \u201Csubmitted \u2026 for payment authorization\u201D, \u201CF23 of authorization\u201D) \u2014 a message nobody has sent yet. So after they confirm: they authorised it, AND no money moved. Saying only one of those is wrong either way. UnionPay\u2019s model has the MERCHANT charge that credential \u2014 it is shaped like an ordinary UnionPay card (token as the card number, DTVC as the CVV2), so the merchant needs UnionPay acceptance. Sinocare\u2019s demo checkout has none, so nothing is charged and no order is placed. Returns ordered:false always.",
763
781
  inputSchema: {
764
782
  type: "object",
765
783
  required: ["sku"],
@@ -1323,7 +1341,10 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
1323
1341
  // charges it, and Sinocare cannot.
1324
1342
  ordered: false,
1325
1343
  awaitingPayment: true,
1326
- message: "\u94F6\u8054\u6536\u94F6\u53F0\u5DF2\u5F00\u597D\u3002\u5728\u6D4F\u89C8\u5668\u91CC\u5B8C\u6210 3DS / Passkey \u8BA4\u8BC1\u540E,\u94F6\u8054\u4F1A\u5411\u6211\u4EEC\u56DE\u8C03\u4E00\u6B21\u6027\u652F\u4ED8\u51ED\u8BC1\u3002",
1344
+ // ⚠️ Tell them what the page says BEFORE they see it. It is titled
1345
+ // 确认支付 and shows the amount — so "authenticate" undersells it and
1346
+ // the person is left thinking they paid. They authorise; nobody charges.
1347
+ message: "\u94F6\u8054\u6536\u94F6\u53F0\u5DF2\u5F00\u597D\u3002\u9875\u9762\u4E0A\u5199\u7684\u662F\u300C\u786E\u8BA4\u652F\u4ED8\u300D\u5E76\u663E\u793A\u91D1\u989D \u2014\u2014 \u4F60\u786E\u8BA4\u7684\u662F\u8FD9\u7B14\u8D2D\u4E70\u672C\u8EAB\uFF0C\u786E\u8BA4\u540E\u94F6\u8054\u628A\u4E00\u6B21\u6027\u652F\u4ED8\u51ED\u8BC1\u56DE\u8C03\u7ED9\u6211\u4EEC\u3002\u26A0\uFE0F \u5361\u4E0D\u4F1A\u5728\u90A3\u4E00\u523B\u88AB\u6263\u6B3E\uFF1A\u6263\u6B3E\u8981\u5546\u6237\u62FF\u8FD9\u5F20\u51ED\u8BC1\u8D70\u81EA\u5DF1\u7684\u94F6\u8054\u6536\u5355\uFF0C\u4E09\u8BFA\u6CA1\u6709\uFF0C\u6240\u4EE5\u6F14\u793A\u5230\u51ED\u8BC1\u4E3A\u6B62\u3002",
1327
1348
  checkoutUrl: checkout.upi.checkoutUrl ?? null,
1328
1349
  srcCorrelationId: checkout.srcCorrelationId,
1329
1350
  paymentIntentId: session.sessionId,
@@ -1361,8 +1382,20 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
1361
1382
  credential: state.credential ?? null,
1362
1383
  issuedAt: state.issuedAt ?? null,
1363
1384
  paymentIntentStatus: state.paymentIntentStatus,
1364
- message: state.issued ? "\u94F6\u8054\u5DF2\u7ECF\u7B7E\u53D1\u4E86\u4E00\u6B21\u6027\u652F\u4ED8\u51ED\u8BC1(\u4EE4\u724C + DTVC)\u3002\u5230\u6B64\u4E3A\u6B62 \u2014\u2014 \u4E09\u8BFA\u6CA1\u6709\u94F6\u8054\u6536\u5355,\u8FD9\u7B14\u4E0D\u4F1A\u88AB\u6263\u6B3E\u3002" : "\u8FD8\u6CA1\u6709\u3002\u6301\u5361\u4EBA\u8FD8\u6CA1\u5728\u94F6\u8054\u9875\u9762\u4E0A\u5B8C\u6210\u8BA4\u8BC1,\u6216\u8005\u521A\u5B8C\u6210\u3001\u56DE\u8C03\u8FD8\u6CA1\u5230\u3002",
1365
- next: state.issued ? "say plainly that UnionPay issued the credential and the demo stops there \u2014 nothing was charged and no order exists. Do NOT call it paid." : "tell them it is not done yet and let them finish on UnionPay\u2019s page. Do not retry in a tight loop."
1385
+ // ⚠️ THE WORDING MATTERS, AND THE FIRST PERSON THROUGH THIS GOT IT
1386
+ // WRONG reasonably. UnionPay's page says 确认支付 and shows the amount,
1387
+ // the merchant and the items, so the cardholder DID confirm a payment.
1388
+ // Answering that with a bare `paid: false` reads as "it failed".
1389
+ //
1390
+ // What is true is narrower and stranger: they authorised it, and the
1391
+ // ISO 8583 authorization that would actually move money has not been
1392
+ // sent. The spec says so in the fields themselves — paymentToken "can
1393
+ // be used in authorization", the cryptogram is "submitted along with
1394
+ // the payment token for payment authorization", panSequenceNumber goes
1395
+ // "in F23 of authorization". Those are inputs to a message nobody has
1396
+ // sent yet, and the party who sends it is the merchant's acquirer.
1397
+ message: state.issued ? "\u6301\u5361\u4EBA\u5DF2\u5728\u94F6\u8054\u9875\u9762\u786E\u8BA4\u652F\u4ED8\uFF0C\u94F6\u8054\u5DF2\u7B7E\u53D1\u4E00\u6B21\u6027\u652F\u4ED8\u51ED\u8BC1\uFF08\u4EE4\u724C + DTVC\uFF09\u3002\u26A0\uFE0F \u4F46\u94B1\u8FD8\u6CA1\u52A8\uFF1A\u51ED\u8BC1\u662F\u4E00\u6761\u5C1A\u672A\u53D1\u51FA\u7684\u6388\u6743\u62A5\u6587\u7684\u5165\u53C2\uFF0C\u8981\u7531\u5546\u6237\u7684\u94F6\u8054\u6536\u5355\u673A\u6784\u53BB\u53D1\u3002\u4E09\u8BFA\u6CA1\u6709\u94F6\u8054\u6536\u5355\uFF0C\u6240\u4EE5\u6F14\u793A\u5230\u6B64\u4E3A\u6B62\u3002" : "\u8FD8\u6CA1\u6709\u3002\u6301\u5361\u4EBA\u8FD8\u6CA1\u5728\u94F6\u8054\u9875\u9762\u4E0A\u70B9\u300C\u786E\u8BA4\u652F\u4ED8\u300D\uFF0C\u6216\u8005\u521A\u70B9\u5B8C\u3001\u56DE\u8C03\u8FD8\u6CA1\u5230\u3002",
1398
+ next: state.issued ? "Say BOTH halves, in this order: the cardholder confirmed the payment and UnionPay issued the credential \u2014 AND nothing has been charged yet, because the credential is the input to an authorization the MERCHANT\u2019s acquirer still has to send, and Sinocare has no UnionPay acceptance. Do not say it failed, and do not say it is paid. Both are wrong." : "tell them it is not done yet and let them finish on UnionPay\u2019s page. Do not retry in a tight loop."
1366
1399
  });
1367
1400
  }
1368
1401
  if (req.params.name === "start_sinocare_wallet_handoff") {