@curless/sinocare-demo 0.64.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 +19 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -777,7 +777,7 @@ var RAIL_TOOLS = [
|
|
|
777
777
|
},
|
|
778
778
|
{
|
|
779
779
|
name: "start_sinocare_uaag_handoff",
|
|
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 purchase
|
|
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.",
|
|
781
781
|
inputSchema: {
|
|
782
782
|
type: "object",
|
|
783
783
|
required: ["sku"],
|
|
@@ -1341,7 +1341,10 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
1341
1341
|
// charges it, and Sinocare cannot.
|
|
1342
1342
|
ordered: false,
|
|
1343
1343
|
awaitingPayment: true,
|
|
1344
|
-
|
|
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",
|
|
1345
1348
|
checkoutUrl: checkout.upi.checkoutUrl ?? null,
|
|
1346
1349
|
srcCorrelationId: checkout.srcCorrelationId,
|
|
1347
1350
|
paymentIntentId: session.sessionId,
|
|
@@ -1379,8 +1382,20 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
1379
1382
|
credential: state.credential ?? null,
|
|
1380
1383
|
issuedAt: state.issuedAt ?? null,
|
|
1381
1384
|
paymentIntentStatus: state.paymentIntentStatus,
|
|
1382
|
-
|
|
1383
|
-
|
|
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."
|
|
1384
1399
|
});
|
|
1385
1400
|
}
|
|
1386
1401
|
if (req.params.name === "start_sinocare_wallet_handoff") {
|