@curless/sinocare-demo 0.67.0 → 0.69.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
@@ -171,33 +171,6 @@ var storefrontTools = (opts) => [
171
171
  required: ["sku"]
172
172
  }
173
173
  },
174
- {
175
- name: "start_sinocare_uaag_handoff",
176
- description: "PAY WITH A UNIONPAY CARD the person bound to their Curless wallet. Sinocare prices the order; the card comes from their wallet, not from you. Returns a URL THEY open \u2014 UnionPay authenticates the cardholder on their own page, with 3DS and a passkey, so no card number ever reaches this server. \u26A0\uFE0F This is a HANDOFF, not a completed purchase, 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 calls the INPUT to an authorization \u2014 a message nobody has sent yet, and the MERCHANT\u2019s acquirer is who sends it. Sinocare has no UnionPay acceptance, so nothing is charged. Returns ordered:false and paid:false always. Then call get_sinocare_uaag_status.",
177
- inputSchema: {
178
- type: "object",
179
- properties: {
180
- sku,
181
- query,
182
- quantity,
183
- cardId: {
184
- type: "string",
185
- description: "OPTIONAL, and normally omit it. The storefront reads the bound UnionPay cards from the person\u2019s own wallet and uses the one they have; pass this only to pick between several. A uaagcard_\u2026 you did not get from that list is a guess, and UnionPay answers a wrong one with a 404 that does not say what was wrong."
186
- }
187
- }
188
- }
189
- },
190
- {
191
- name: "get_sinocare_uaag_status",
192
- description: "Has UnionPay issued the payment credential yet? Pass the paymentIntentId from start_sinocare_uaag_handoff. The cardholder authenticates in their own browser and this server is never told when they finish, so this is the only way to know. \u26A0\uFE0F `issued: true` means the cardholder confirmed and a one-time token now exists \u2014 it does NOT mean the order is paid. The MERCHANT charges that credential through their own UnionPay acceptance, which Sinocare does not have, so this demo stops there on purpose. Say both halves; never report it as paid.",
193
- inputSchema: {
194
- type: "object",
195
- required: ["paymentIntentId"],
196
- properties: {
197
- paymentIntentId: { type: "string", description: "from start_sinocare_uaag_handoff" }
198
- }
199
- }
200
- },
201
174
  {
202
175
  name: "get_sinocare_order_status",
203
176
  description: "Has this checkout been paid? Use after pay_sinocare_hosted \u2014 the approval happens in a browser and this server is never told when it does. `completed` means the money moved.",
@@ -245,12 +218,24 @@ var productsView = (products) => ({
245
218
  count: products.length,
246
219
  products: [...products]
247
220
  });
221
+ var TERMINAL = /* @__PURE__ */ new Set(["captured", "settled", "reconciled", "refunded", "failed", "canceled"]);
248
222
  var ordersView = (orders) => ({
249
223
  view: "orders",
250
224
  orders: orders.map(
251
225
  (o) => ({
252
226
  orderId: o.id,
253
- status: o.refundRequest ? o.refundRequest.status === "approved" ? "refund approved" : "refund requested" : o.status,
227
+ status: o.refundRequest ? o.refundRequest.status === "approved" ? "refund approved" : "refund requested" : (
228
+ // ⚠️ A UnionPay order is the one case where a still-uncaptured order
229
+ // is not "nothing happened yet". The cardholder confirmed and a
230
+ // one-time credential exists; the charge belongs to the merchant's
231
+ // own acquirer, which is why the PI — and so `o.status` — never
232
+ // moves. Left as the bare pending status, the person sees an unpaid
233
+ // order and no reason, having just confirmed a payment.
234
+ //
235
+ // ⚠️ Not "paid", and never will be from here. The wording carries
236
+ // both halves, which is the same rule the tool descriptions follow.
237
+ o.metadata?.uaag?.credentialAt && !TERMINAL.has(o.status) ? "credential issued \xB7 merchant to charge" : o.status
238
+ ),
254
239
  refundPending: Boolean(o.refundRequest),
255
240
  product: o.lineItems?.map((li) => `${li.name} \xD7${li.quantity}`).join(", ") ?? "",
256
241
  total: formatMinor(Number(o.amount ?? 0), String(o.currency ?? "EUR")),
@@ -414,6 +399,9 @@ var uaagCheckoutStatus = async (deps, paymentIntentId) => {
414
399
  const issued = uaag?.credential !== void 0;
415
400
  return {
416
401
  issued,
402
+ // Present on any order this rail ever touched, credential or not — it is
403
+ // what tells a shared status tool which question it is answering.
404
+ startedAt: uaag?.startedAt ?? null,
417
405
  // ⚠️ `issued` is not `paid`, and the two are one word apart in every
418
406
  // language this will be read in.
419
407
  ordered: false,
@@ -965,6 +953,33 @@ var RAIL_TOOLS = [
965
953
  }
966
954
  }
967
955
  },
956
+ {
957
+ name: "start_sinocare_uaag_handoff",
958
+ description: "PAY WITH A UNIONPAY CARD the person bound to their Curless wallet. Sinocare prices the order; the card comes from their wallet, not from you. Returns a URL THEY open \u2014 UnionPay authenticates the cardholder on their own page, with 3DS and a passkey, so no card number ever reaches this server. \u26A0\uFE0F This is a HANDOFF, not a completed purchase, 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 calls the INPUT to an authorization \u2014 a message nobody has sent yet, and the MERCHANT\u2019s acquirer is who sends it. Sinocare has no UnionPay acceptance, so nothing is charged. Returns ordered:false and paid:false always. Then call get_sinocare_uaag_status.",
959
+ inputSchema: {
960
+ type: "object",
961
+ properties: {
962
+ sku: { type: "string", description: "the product's exact sku" },
963
+ query: { type: "string", description: "the product NAME, resolved against the catalog" },
964
+ quantity: { type: "integer", description: "how many, default 1" },
965
+ cardId: {
966
+ type: "string",
967
+ description: "OPTIONAL, and normally omit it. The storefront reads the bound UnionPay cards from the person\u2019s own wallet and uses the one they have; pass this only to pick between several. A uaagcard_\u2026 you did not get from that list is a guess, and UnionPay answers a wrong one with a 404 that does not say what was wrong."
968
+ }
969
+ }
970
+ }
971
+ },
972
+ {
973
+ name: "get_sinocare_uaag_status",
974
+ description: "Has UnionPay issued the payment credential yet? Pass the paymentIntentId from start_sinocare_uaag_handoff. The cardholder authenticates in their own browser and this server is never told when they finish, so this is the only way to know. \u26A0\uFE0F `issued: true` means the cardholder confirmed and a one-time token now exists \u2014 it does NOT mean the order is paid. The MERCHANT charges that credential through their own UnionPay acceptance, which Sinocare does not have, so this demo stops there on purpose. Say both halves; never report it as paid.",
975
+ inputSchema: {
976
+ type: "object",
977
+ required: ["paymentIntentId"],
978
+ properties: {
979
+ paymentIntentId: { type: "string", description: "from start_sinocare_uaag_handoff" }
980
+ }
981
+ }
982
+ },
968
983
  {
969
984
  name: "buy_sinocare_product_acp",
970
985
  description: "Buy a Sinocare product over ACP (Agentic Commerce Protocol) \u2014 Sinocare prices the product and opens a merchant-quoted checkout session; this agent completes it with a delegated card credential, settling on the card rail (test mode). One of THREE ways to pay: ACP (card) / UCP (card) / x402 (USDC). The card rail is an implementation detail, not a separate payment choice. Returns the ordered order.",