@curless/hotel-storefront 0.37.2 → 0.38.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.
Files changed (45) hide show
  1. package/dist/card.generated.d.ts +1 -1
  2. package/dist/card.generated.js +2 -2
  3. package/dist/card.generated.js.map +1 -1
  4. package/dist/config.d.ts +15 -0
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js.map +1 -1
  7. package/dist/huazhu/backend.d.ts +7 -0
  8. package/dist/huazhu/backend.d.ts.map +1 -1
  9. package/dist/huazhu/backend.js +306 -7
  10. package/dist/huazhu/backend.js.map +1 -1
  11. package/dist/huazhu/bookings.d.ts +9 -0
  12. package/dist/huazhu/bookings.d.ts.map +1 -1
  13. package/dist/huazhu/bookings.js.map +1 -1
  14. package/dist/huazhu/fake.d.ts.map +1 -1
  15. package/dist/huazhu/fake.js +5 -0
  16. package/dist/huazhu/fake.js.map +1 -1
  17. package/dist/huazhu/make.d.ts.map +1 -1
  18. package/dist/huazhu/make.js +28 -1
  19. package/dist/huazhu/make.js.map +1 -1
  20. package/dist/huazhu/wire.d.ts +17 -0
  21. package/dist/huazhu/wire.d.ts.map +1 -1
  22. package/dist/huazhu/wire.js.map +1 -1
  23. package/dist/legal.d.ts.map +1 -1
  24. package/dist/legal.js +23 -4
  25. package/dist/legal.js.map +1 -1
  26. package/dist/lib.d.ts +1 -1
  27. package/dist/lib.d.ts.map +1 -1
  28. package/dist/lib.js.map +1 -1
  29. package/dist/payments/fake-unionpay.d.ts +22 -0
  30. package/dist/payments/fake-unionpay.d.ts.map +1 -0
  31. package/dist/payments/fake-unionpay.js +89 -0
  32. package/dist/payments/fake-unionpay.js.map +1 -0
  33. package/dist/payments/unionpay.d.ts +66 -0
  34. package/dist/payments/unionpay.d.ts.map +1 -1
  35. package/dist/payments/unionpay.js +163 -0
  36. package/dist/payments/unionpay.js.map +1 -1
  37. package/dist/server.d.ts +2 -2
  38. package/dist/server.d.ts.map +1 -1
  39. package/dist/server.js +12 -3
  40. package/dist/server.js.map +1 -1
  41. package/dist/tools.d.ts +24 -0
  42. package/dist/tools.d.ts.map +1 -1
  43. package/dist/tools.js +107 -0
  44. package/dist/tools.js.map +1 -1
  45. package/package.json +2 -1
package/dist/lib.d.ts CHANGED
@@ -20,7 +20,7 @@ export { buildTools, withheldTools } from './tools.js';
20
20
  export { INSTRUCTS, listingProblems } from './listing.js';
21
21
  export { resolveBrand, DEMO_NOTE } from './vocab.js';
22
22
  export { FULL_CAPABILITIES, MAX_PAGE } from './backend.js';
23
- export type { BackendCapabilities, HotelBackend, PaymentReturn, SupplierInfo } from './backend.js';
23
+ export type { BackendCapabilities, HotelBackend, PaymentReturn, SupplierInfo, UnionPayStep, } from './backend.js';
24
24
  export type { ApiSource, HotelConfig, ToolNames } from './config.js';
25
25
  export { HUAZHU_CAPABILITIES, createHuazhuHotels } from './huazhu/backend.js';
26
26
  export { checkHuazhu } from './huazhu/check.js';
package/dist/lib.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,QAAQ,EACR,UAAU,EACV,SAAS,EACT,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACnG,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAErE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC5D,YAAY,EACV,OAAO,EACP,aAAa,EACb,UAAU,EACV,KAAK,EACL,KAAK,EACL,WAAW,EACX,WAAW,EACX,QAAQ,EACR,MAAM,EACN,KAAK,EACL,WAAW,EACX,WAAW,EACX,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,QAAQ,GACT,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,QAAQ,EACR,UAAU,EACV,SAAS,EACT,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC3D,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,YAAY,GACb,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAErE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC5D,YAAY,EACV,OAAO,EACP,aAAa,EACb,UAAU,EACV,KAAK,EACL,KAAK,EACL,WAAW,EACX,WAAW,EACX,QAAQ,EACR,MAAM,EACN,KAAK,EACL,WAAW,EACX,WAAW,EACX,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,QAAQ,GACT,MAAM,YAAY,CAAC"}
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,QAAQ,EACR,UAAU,EACV,SAAS,EACT,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,4EAA4E;AAC5E,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACvD,8EAA8E;AAC9E,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG3D,qEAAqE;AACrE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,QAAQ,EACR,UAAU,EACV,SAAS,EACT,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,4EAA4E;AAC5E,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACvD,8EAA8E;AAC9E,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAS3D,qEAAqE;AACrE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { OneTimeCard, UnionPayHandoff, UnionPayState } from './unionpay.js';
2
+ type Session = {
3
+ state: UnionPayState;
4
+ card?: OneTimeCard;
5
+ taken: number;
6
+ input: Parameters<UnionPayHandoff['open']>[0];
7
+ };
8
+ /** Stripe's published UnionPay test card number - a test value, never a real card. */
9
+ export declare const TEST_ONE_TIME_CARD: OneTimeCard;
10
+ export declare const createFakeUnionPay: () => {
11
+ handoff: UnionPayHandoff;
12
+ calls: string[];
13
+ sessions: Map<string, Session>;
14
+ /** The gateway or UnionPay not answering. */
15
+ down: boolean;
16
+ /** The guest finished UnionPay's page for binding a card. */
17
+ bind(email: string, lastFour?: string): void;
18
+ /** The guest confirmed on UnionPay's page, and UnionPay issued the one-time card. */
19
+ confirm(id: string, card?: OneTimeCard): void;
20
+ };
21
+ export {};
22
+ //# sourceMappingURL=fake-unionpay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-unionpay.d.ts","sourceRoot":"","sources":["../../src/payments/fake-unionpay.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGjF,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/C,CAAC;AAEF,sFAAsF;AACtF,eAAO,MAAM,kBAAkB,EAAE,WAKhC,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;IAuD3B,6CAA6C;UACjC,OAAO;IAGnB,6DAA6D;gBACjD,MAAM;IAKlB,qFAAqF;gBACzE,MAAM,SAAQ,WAAW;CAOxC,CAAC"}
@@ -0,0 +1,89 @@
1
+ // UnionPay's APOP, in memory - what `UnionPayHandoff` stands for - so paying a
2
+ // stay with a UnionPay one-time card can be run through in a test with no
3
+ // gateway, no UnionPay and no card. It keeps the rules that matter: a card is
4
+ // bound only when the guest finishes UnionPay's page, a confirmation is the
5
+ // guest's to make, and the one-time card is handed over once.
6
+ import { UnionPayError } from './unionpay.js';
7
+ /** Stripe's published UnionPay test card number - a test value, never a real card. */
8
+ export const TEST_ONE_TIME_CARD = {
9
+ number: '6200000000000005',
10
+ expMonth: '12',
11
+ expYear: '2030',
12
+ securityCode: '123',
13
+ };
14
+ export const createFakeUnionPay = () => {
15
+ const cards = new Map();
16
+ const sessions = new Map();
17
+ const calls = [];
18
+ const state = { down: false };
19
+ let seq = 0;
20
+ const k = (email) => email.trim().toLowerCase();
21
+ const reachable = () => {
22
+ if (state.down)
23
+ throw new UnionPayError('the gateway did not answer (fake: down)');
24
+ };
25
+ const handoff = {
26
+ async cardsOf(email) {
27
+ calls.push('cards');
28
+ reachable();
29
+ return [...(cards.get(k(email)) ?? [])];
30
+ },
31
+ async enroll(email) {
32
+ calls.push('enroll');
33
+ reachable();
34
+ return { url: `https://unionpay.test/enroll/${encodeURIComponent(k(email))}/${++seq}` };
35
+ },
36
+ async open(o) {
37
+ calls.push('open');
38
+ reachable();
39
+ if (!(cards.get(k(o.email)) ?? []).some((c) => c.id === o.cardId))
40
+ throw new UnionPayError('Card not found or does not belong to agent', 404);
41
+ const id = `pi_up_${++seq}`;
42
+ sessions.set(id, { state: 'open', taken: 0, input: o });
43
+ return { sessionId: id, url: `https://unionpay.test/confirm/${id}` };
44
+ },
45
+ async state(id) {
46
+ calls.push('state');
47
+ reachable();
48
+ return sessions.get(id)?.state ?? 'closed';
49
+ },
50
+ async card(id) {
51
+ calls.push('card');
52
+ reachable();
53
+ const s = sessions.get(id);
54
+ if (!s || s.state !== 'issued')
55
+ return undefined;
56
+ s.taken += 1;
57
+ // Once: the gateway forgets it after handing it over.
58
+ return s.taken === 1 ? s.card : undefined;
59
+ },
60
+ async close(id) {
61
+ calls.push('close');
62
+ return sessions.get(id)?.state ?? 'closed';
63
+ },
64
+ };
65
+ return {
66
+ handoff,
67
+ calls,
68
+ sessions,
69
+ /** The gateway or UnionPay not answering. */
70
+ set down(v) {
71
+ state.down = v;
72
+ },
73
+ /** The guest finished UnionPay's page for binding a card. */
74
+ bind(email, lastFour = '0005') {
75
+ const list = cards.get(k(email)) ?? [];
76
+ list.push({ id: `uaagcard_${++seq}`, lastFour });
77
+ cards.set(k(email), list);
78
+ },
79
+ /** The guest confirmed on UnionPay's page, and UnionPay issued the one-time card. */
80
+ confirm(id, card = TEST_ONE_TIME_CARD) {
81
+ const s = sessions.get(id);
82
+ if (!s)
83
+ throw new Error(`no UnionPay page ${id}`);
84
+ s.state = 'issued';
85
+ s.card = card;
86
+ },
87
+ };
88
+ };
89
+ //# sourceMappingURL=fake-unionpay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-unionpay.js","sourceRoot":"","sources":["../../src/payments/fake-unionpay.ts"],"names":[],"mappings":"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"}
@@ -32,16 +32,30 @@ export declare class UnionPayError extends Error {
32
32
  constructor(message: string, status?: number | undefined);
33
33
  }
34
34
  export interface UnionPayHandoff {
35
+ /** The guest's cards UnionPay has bound for them - active ones only. */
36
+ cardsOf(email: string): Promise<{
37
+ id: string;
38
+ lastFour: string;
39
+ }[]>;
40
+ /** UnionPay's page for binding a card. The card exists once UnionPay says so, not when this answers. */
41
+ enroll(email: string): Promise<{
42
+ url: string;
43
+ }>;
35
44
  /** For one stay: UnionPay's page, for the total the guest was shown. */
36
45
  open(o: {
37
46
  /** The booking's own key with the hotel - Huazhu's `distributorResId`. */
38
47
  ref: string;
39
48
  code?: string;
40
49
  title: string;
50
+ /** What UnionPay's page calls the stay - ASCII only, UnionPay's rule. */
51
+ label?: string;
41
52
  amountMinor: number;
42
53
  currency: string;
43
54
  /** The guest's, who UnionPay files their cards under. */
44
55
  email: string;
56
+ name?: string;
57
+ /** One of `cardsOf`'s. */
58
+ cardId: string;
45
59
  }): Promise<OpenedUnionPay>;
46
60
  state(sessionId: string): Promise<UnionPayState>;
47
61
  /**
@@ -56,4 +70,56 @@ export interface UnionPayHandoff {
56
70
  export declare const lastFour: (c: OneTimeCard) => string;
57
71
  /** `MMyy`, as Huazhu's `paymentCard.expireDate` takes it. */
58
72
  export declare const expiryMMyy: (c: OneTimeCard) => string;
73
+ export type GatewayUnionPayOptions = {
74
+ /** The agentbank gateway, e.g. https://mcp.curless.ai. */
75
+ baseUrl: string;
76
+ /** The Curless merchant the stays are sold as - a test-mode one. */
77
+ merchantId: string;
78
+ /** Its key (`merchant:write`): opens the payment, binds and lists members' cards, takes the one-time card. */
79
+ merchantKey: string;
80
+ /** An agent key (`agent:execute`) in the same organisation: registers the order with UnionPay. */
81
+ agentKey: string;
82
+ /** On UnionPay's page as whose order it is - ASCII only, UnionPay's rule. */
83
+ merchantName: string;
84
+ merchantUrl: string;
85
+ fetch?: typeof fetch;
86
+ timeoutMs?: number;
87
+ };
88
+ /**
89
+ * The guest, as UnionPay files their cards: a merchant member keyed by their
90
+ * email (robin, 2026-10-15: no Huazhu member sign-in yet - the email until
91
+ * there is one). Hashed, so the gateway holds no address it does not need.
92
+ */
93
+ export declare const memberRefOf: (email: string) => string;
94
+ export declare class GatewayUnionPay implements UnionPayHandoff {
95
+ private readonly opts;
96
+ private readonly fetch;
97
+ private readonly base;
98
+ constructor(opts: GatewayUnionPayOptions);
99
+ private call;
100
+ /** The guest's cards UnionPay has bound - active ones only. */
101
+ cardsOf(email: string): Promise<{
102
+ id: string;
103
+ lastFour: string;
104
+ }[]>;
105
+ /** UnionPay's page for binding a card. Bound only once UnionPay says so - never by this answer. */
106
+ enroll(email: string): Promise<{
107
+ url: string;
108
+ }>;
109
+ open(o: Parameters<UnionPayHandoff['open']>[0]): Promise<OpenedUnionPay>;
110
+ state(sessionId: string): Promise<UnionPayState>;
111
+ /**
112
+ * The one-time card, from the gateway - which gives it once and then forgets
113
+ * it. ⚠️ THE GATEWAY'S SIDE IS NOT BUILT YET (总线程 asked to route it to the
114
+ * gateway, 2026-10-15): the path is the one proposed in
115
+ * docs/huazhu-unionpay-apop.md.
116
+ */
117
+ card(sessionId: string): Promise<OneTimeCard | undefined>;
118
+ /**
119
+ * A payment handed to UnionPay cannot be cancelled at the gateway - and need
120
+ * not be: nothing is charged unless its card is handed on, which a lapsed
121
+ * booking never does. Says where it stands.
122
+ */
123
+ close(sessionId: string): Promise<UnionPayState>;
124
+ }
59
125
  //# sourceMappingURL=unionpay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"unionpay.d.ts","sourceRoot":"","sources":["../../src/payments/unionpay.ts"],"names":[],"mappings":"AAiBA,qEAAqE;AACrE,MAAM,MAAM,WAAW,GAAG;IACxB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,4CAA4C;AAC5C,MAAM,MAAM,aAAa;AACvB,qDAAqD;AACnD,MAAM;AACR,sEAAsE;GACpE,QAAQ;AACV,4EAA4E;GAC1E,QAAQ,CAAC;AAEb,MAAM,MAAM,cAAc,GAAG;IAC3B,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,gGAAgG;IAChG,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IAGpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;gBADxB,OAAO,EAAE,MAAM,EACN,MAAM,CAAC,EAAE,MAAM,YAAA;CAK3B;AAED,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,IAAI,CAAC,CAAC,EAAE;QACN,0EAA0E;QAC1E,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,yDAAyD;QACzD,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5B,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACjD;;;OAGG;IACH,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAC1D,iFAAiF;IACjF,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAClD;AAED,qFAAqF;AACrF,eAAO,MAAM,QAAQ,GAAI,GAAG,WAAW,KAAG,MAA4B,CAAC;AAEvE,6DAA6D;AAC7D,eAAO,MAAM,UAAU,GAAI,GAAG,WAAW,KAAG,MACsB,CAAC"}
1
+ {"version":3,"file":"unionpay.d.ts","sourceRoot":"","sources":["../../src/payments/unionpay.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,8 @@
14
14
  //
15
15
  // The gateway (UnionPay's UAAG behind it) is one implementation; a test's
16
16
  // fake is the other.
17
+ import { createHash } from 'node:crypto';
18
+ import { checkoutState, startUaagCheckoutForLines } from '@curless/agentbank-protocols/uaag';
17
19
  export class UnionPayError extends Error {
18
20
  status;
19
21
  constructor(message, status) {
@@ -26,4 +28,165 @@ export class UnionPayError extends Error {
26
28
  export const lastFour = (c) => c.number.slice(-4);
27
29
  /** `MMyy`, as Huazhu's `paymentCard.expireDate` takes it. */
28
30
  export const expiryMMyy = (c) => `${c.expMonth.padStart(2, '0').slice(-2)}${c.expYear.slice(-2)}`;
31
+ /**
32
+ * The guest, as UnionPay files their cards: a merchant member keyed by their
33
+ * email (robin, 2026-10-15: no Huazhu member sign-in yet - the email until
34
+ * there is one). Hashed, so the gateway holds no address it does not need.
35
+ */
36
+ export const memberRefOf = (email) => `hz-${createHash('sha256').update(email.trim().toLowerCase()).digest('hex').slice(0, 40)}`;
37
+ /** UnionPay shows ASCII only - anything else is dropped by the gateway anyway. */
38
+ const ascii = (s, fallback) => {
39
+ const t = s
40
+ .normalize('NFKD')
41
+ .replace(/[^\x20-\x7E]/g, '')
42
+ .replace(/\s+/g, ' ')
43
+ .trim();
44
+ return (t || fallback).slice(0, 120);
45
+ };
46
+ export class GatewayUnionPay {
47
+ opts;
48
+ fetch;
49
+ base;
50
+ constructor(opts) {
51
+ this.opts = opts;
52
+ this.fetch = opts.fetch ?? globalThis.fetch;
53
+ this.base = opts.baseUrl.replace(/\/$/, '');
54
+ }
55
+ async call(method, path, body) {
56
+ let res;
57
+ try {
58
+ res = await this.fetch(`${this.base}${path}`, {
59
+ method,
60
+ headers: {
61
+ authorization: `Bearer ${this.opts.merchantKey}`,
62
+ ...(body !== undefined ? { 'content-type': 'application/json' } : {}),
63
+ },
64
+ ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
65
+ signal: AbortSignal.timeout(this.opts.timeoutMs ?? 15_000),
66
+ });
67
+ }
68
+ catch (err) {
69
+ throw new UnionPayError(`the gateway did not answer (${err.message})`);
70
+ }
71
+ const text = await res.text();
72
+ if (!res.ok) {
73
+ // Its own message, never the request - and never a card: a key rides in
74
+ // a header, and a one-time card only ever in an answer we read once.
75
+ let said = text.slice(0, 300).replace(/\d{12,19}/g, '****');
76
+ try {
77
+ const j = JSON.parse(text);
78
+ said = (j.error?.message ?? said).replace(/\d{12,19}/g, '****');
79
+ }
80
+ catch { }
81
+ throw new UnionPayError(`the gateway answered ${res.status}: ${said}`, res.status);
82
+ }
83
+ return (text ? JSON.parse(text) : {});
84
+ }
85
+ /** The guest's cards UnionPay has bound - active ones only. */
86
+ async cardsOf(email) {
87
+ const r = await this.call('GET', `/v1/merchant-wallet/cards?memberRef=${encodeURIComponent(memberRefOf(email))}`);
88
+ return (r.cards ?? []).map((c) => ({ id: c.id, lastFour: c.panLastFour ?? '' }));
89
+ }
90
+ /** UnionPay's page for binding a card. Bound only once UnionPay says so - never by this answer. */
91
+ async enroll(email) {
92
+ const r = await this.call('POST', '/v1/merchant-wallet/cards', {
93
+ memberRef: memberRefOf(email),
94
+ });
95
+ if (!r.enrollUrl)
96
+ throw new UnionPayError('UnionPay gave no page to bind a card on');
97
+ return { url: r.enrollUrl };
98
+ }
99
+ async open(o) {
100
+ if (!o.cardId)
101
+ throw new UnionPayError('no UnionPay card to pay with - bind one first');
102
+ // The payment UnionPay's confirmation hangs on: priced by us as the
103
+ // merchant, at the total the guest was shown. It is never captured here -
104
+ // the hotel charges the one-time card (docs/huazhu-unionpay-apop.md).
105
+ const created = await this.call('POST', `/acp/${encodeURIComponent(this.opts.merchantId)}/checkout_sessions`, {
106
+ items: [{ id: o.ref, quantity: 1, unitPrice: o.amountMinor, name: o.title }],
107
+ currency: o.currency,
108
+ display: { merchantName: this.opts.merchantName, merchantUrl: this.opts.merchantUrl },
109
+ });
110
+ if (!created.id)
111
+ throw new UnionPayError('the gateway opened no payment');
112
+ let started;
113
+ try {
114
+ started = await startUaagCheckoutForLines({ apiBase: this.base, agentToken: this.opts.agentKey, fetch: this.fetch }, {
115
+ paymentIntentId: created.id,
116
+ cardId: o.cardId,
117
+ merchantName: ascii(this.opts.merchantName, 'Curless'),
118
+ merchantUrl: this.opts.merchantUrl,
119
+ amount: o.amountMinor,
120
+ items: [
121
+ {
122
+ name: ascii(o.label ?? o.title, 'Hotel stay'),
123
+ url: this.opts.merchantUrl,
124
+ unitPrice: o.amountMinor,
125
+ currency: o.currency,
126
+ quantity: 1,
127
+ sku: o.ref,
128
+ // A stay: nothing is shipped, so UnionPay asks for no address.
129
+ deliveryMethod: 'DIGITAL',
130
+ },
131
+ ],
132
+ buyer: { email: o.email, ...(o.name ? { name: ascii(o.name, '') || undefined } : {}) },
133
+ });
134
+ }
135
+ catch (err) {
136
+ throw new UnionPayError(`UnionPay did not take the order (${err.message})`);
137
+ }
138
+ if (!started.checkoutUrl)
139
+ throw new UnionPayError('UnionPay gave no page to confirm on');
140
+ return { sessionId: created.id, url: started.checkoutUrl };
141
+ }
142
+ async state(sessionId) {
143
+ let s;
144
+ try {
145
+ s = await checkoutState({ baseUrl: this.base, token: this.opts.agentKey, fetch: this.fetch }, sessionId);
146
+ }
147
+ catch (err) {
148
+ throw new UnionPayError(`the gateway did not say (${err.message})`);
149
+ }
150
+ if (s.issued)
151
+ return 'issued';
152
+ return ['canceled', 'cancelled', 'expired', 'failed'].includes(s.paymentIntentStatus)
153
+ ? 'closed'
154
+ : 'open';
155
+ }
156
+ /**
157
+ * The one-time card, from the gateway - which gives it once and then forgets
158
+ * it. ⚠️ THE GATEWAY'S SIDE IS NOT BUILT YET (总线程 asked to route it to the
159
+ * gateway, 2026-10-15): the path is the one proposed in
160
+ * docs/huazhu-unionpay-apop.md.
161
+ */
162
+ async card(sessionId) {
163
+ let r;
164
+ try {
165
+ r = await this.call('POST', `/v1/merchant/payment-intents/${encodeURIComponent(sessionId)}/uaag/credential`, {});
166
+ }
167
+ catch (err) {
168
+ // Taken already, or not issued: there is no card to hand on.
169
+ if (err instanceof UnionPayError &&
170
+ (err.status === 404 || err.status === 409 || err.status === 410))
171
+ return undefined;
172
+ throw err;
173
+ }
174
+ if (!r.cardNumber || !/^\d{12,19}$/.test(r.cardNumber) || !r.expMonth || !r.expYear)
175
+ return undefined;
176
+ return {
177
+ number: r.cardNumber,
178
+ expMonth: String(r.expMonth).padStart(2, '0'),
179
+ expYear: String(r.expYear).length === 2 ? `20${r.expYear}` : String(r.expYear),
180
+ ...(r.securityCode ? { securityCode: r.securityCode } : {}),
181
+ };
182
+ }
183
+ /**
184
+ * A payment handed to UnionPay cannot be cancelled at the gateway - and need
185
+ * not be: nothing is charged unless its card is handed on, which a lapsed
186
+ * booking never does. Says where it stands.
187
+ */
188
+ async close(sessionId) {
189
+ return this.state(sessionId);
190
+ }
191
+ }
29
192
  //# sourceMappingURL=unionpay.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"unionpay.js","sourceRoot":"","sources":["../../src/payments/unionpay.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,gDAAgD;AAChD,kEAAkE;AAClE,2EAA2E;AAC3E,2EAA2E;AAC3E,uEAAuE;AACvE,mBAAmB;AACnB,EAAE;AACF,2EAA2E;AAC3E,qEAAqE;AACrE,+EAA+E;AAC/E,8EAA8E;AAC9E,oEAAoE;AACpE,EAAE;AACF,0EAA0E;AAC1E,qBAAqB;AAkCrB,MAAM,OAAO,aAAc,SAAQ,KAAK;IAG3B;IAFX,YACE,OAAe,EACN,MAAe;QAExB,KAAK,CAAC,OAAO,CAAC,CAAC;QAFN,WAAM,GAAN,MAAM,CAAS;QAGxB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAwBD,qFAAqF;AACrF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAc,EAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvE,6DAA6D;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAc,EAAU,EAAE,CACnD,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC"}
1
+ {"version":3,"file":"unionpay.js","sourceRoot":"","sources":["../../src/payments/unionpay.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,gDAAgD;AAChD,kEAAkE;AAClE,2EAA2E;AAC3E,2EAA2E;AAC3E,uEAAuE;AACvE,mBAAmB;AACnB,EAAE;AACF,2EAA2E;AAC3E,qEAAqE;AACrE,+EAA+E;AAC/E,8EAA8E;AAC9E,oEAAoE;AACpE,EAAE;AACF,0EAA0E;AAC1E,qBAAqB;AAErB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAkC7F,MAAM,OAAO,aAAc,SAAQ,KAAK;IAG3B;IAFX,YACE,OAAe,EACN,MAAe;QAExB,KAAK,CAAC,OAAO,CAAC,CAAC;QAFN,WAAM,GAAN,MAAM,CAAS;QAGxB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAiCD,qFAAqF;AACrF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAc,EAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvE,6DAA6D;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAc,EAAU,EAAE,CACnD,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAoBnE;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAa,EAAU,EAAE,CACnD,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AAE7F,kFAAkF;AAClF,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,QAAgB,EAAU,EAAE;IACpD,MAAM,CAAC,GAAG,CAAC;SACR,SAAS,CAAC,MAAM,CAAC;SACjB,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;SAC5B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACV,OAAO,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,OAAO,eAAe;IAIG;IAHZ,KAAK,CAAe;IACpB,IAAI,CAAS;IAE9B,YAA6B,IAA4B;QAA5B,SAAI,GAAJ,IAAI,CAAwB;QACvD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,IAAI,CAAI,MAAsB,EAAE,IAAY,EAAE,IAAc;QACxE,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,EAAE;gBAC5C,MAAM;gBACN,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;oBAChD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACtE;gBACD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC;aAC3D,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,aAAa,CAAC,+BAAgC,GAAa,CAAC,OAAO,GAAG,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,wEAAwE;YACxE,qEAAqE;YACrE,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YAC5D,IAAI,CAAC;gBACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAqC,CAAC;gBAC/D,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YAClE,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,MAAM,IAAI,aAAa,CAAC,wBAAwB,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACrF,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAM,CAAC;IAC7C,CAAC;IAED,+DAA+D;IAC/D,KAAK,CAAC,OAAO,CAAC,KAAa;QACzB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CACvB,KAAK,EACL,uCAAuC,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAChF,CAAC;QACF,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,mGAAmG;IACnG,KAAK,CAAC,MAAM,CAAC,KAAa;QACxB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAgC,MAAM,EAAE,2BAA2B,EAAE;YAC5F,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC;SAC9B,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,CAAC,SAAS;YAAE,MAAM,IAAI,aAAa,CAAC,yCAAyC,CAAC,CAAC;QACrF,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAyC;QAClD,IAAI,CAAC,CAAC,CAAC,MAAM;YAAE,MAAM,IAAI,aAAa,CAAC,+CAA+C,CAAC,CAAC;QACxF,oEAAoE;QACpE,0EAA0E;QAC1E,sEAAsE;QACtE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAC7B,MAAM,EACN,QAAQ,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,oBAAoB,EACpE;YACE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;YAC5E,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;SACtF,CACF,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,MAAM,IAAI,aAAa,CAAC,+BAA+B,CAAC,CAAC;QAC1E,IAAI,OAA8D,CAAC;QACnE,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,yBAAyB,CACvC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EACzE;gBACE,eAAe,EAAE,OAAO,CAAC,EAAE;gBAC3B,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC;gBACtD,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;gBAClC,MAAM,EAAE,CAAC,CAAC,WAAW;gBACrB,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC;wBAC7C,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;wBAC1B,SAAS,EAAE,CAAC,CAAC,WAAW;wBACxB,QAAQ,EAAE,CAAC,CAAC,QAAQ;wBACpB,QAAQ,EAAE,CAAC;wBACX,GAAG,EAAE,CAAC,CAAC,GAAG;wBACV,+DAA+D;wBAC/D,cAAc,EAAE,SAAS;qBAC1B;iBACF;gBACD,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;aACvF,CACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,aAAa,CAAC,oCAAqC,GAAa,CAAC,OAAO,GAAG,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,WAAW;YAAE,MAAM,IAAI,aAAa,CAAC,qCAAqC,CAAC,CAAC;QACzF,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,SAAiB;QAC3B,IAAI,CAA4C,CAAC;QACjD,IAAI,CAAC;YACH,CAAC,GAAG,MAAM,aAAa,CACrB,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EACpE,SAAS,CACV,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,aAAa,CAAC,4BAA6B,GAAa,CAAC,OAAO,GAAG,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,CAAC,CAAC,MAAM;YAAE,OAAO,QAAQ,CAAC;QAC9B,OAAO,CAAC,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC;YACnF,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,MAAM,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,IAAI,CAKH,CAAC;QACF,IAAI,CAAC;YACH,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CACjB,MAAM,EACN,gCAAgC,kBAAkB,CAAC,SAAS,CAAC,kBAAkB,EAC/E,EAAE,CACH,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,6DAA6D;YAC7D,IACE,GAAG,YAAY,aAAa;gBAC5B,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC;gBAEhE,OAAO,SAAS,CAAC;YACnB,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,OAAO;YACjF,OAAO,SAAS,CAAC;QACnB,OAAO;YACL,MAAM,EAAE,CAAC,CAAC,UAAU;YACpB,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;YAC7C,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9E,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5D,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAK,CAAC,SAAiB;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;CACF"}
package/dist/server.d.ts CHANGED
@@ -28,7 +28,7 @@ export declare const INITIALIZE_PER_MINUTE = 300;
28
28
  * number. Found by reading the boot banner of a container that had just been
29
29
  * deployed (2026-09-22): seventeen tools listed, and "0.7.0" above them.
30
30
  */
31
- export declare const VERSION = "0.37.2";
31
+ export declare const VERSION = "0.38.0";
32
32
  /**
33
33
  * The card's resource URI.
34
34
  *
@@ -37,7 +37,7 @@ export declare const VERSION = "0.37.2";
37
37
  * connector went storefront-v35 → v40 in a single day of UI work for exactly
38
38
  * this reason.
39
39
  */
40
- export declare const CARD_URI = "ui://curless/hotel/booking-v72.html";
40
+ export declare const CARD_URI = "ui://curless/hotel/booking-v73.html";
41
41
  /**
42
42
  * The URI one deployment names its card by: `CARD_URI` with a short hash of
43
43
  * everything a host caches under it - the card itself, and the hosts it may
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -47,7 +47,7 @@ export const INITIALIZE_PER_MINUTE = 300;
47
47
  * number. Found by reading the boot banner of a container that had just been
48
48
  * deployed (2026-09-22): seventeen tools listed, and "0.7.0" above them.
49
49
  */
50
- export const VERSION = '0.37.2';
50
+ export const VERSION = '0.38.0';
51
51
  /**
52
52
  * The card's resource URI.
53
53
  *
@@ -56,7 +56,7 @@ export const VERSION = '0.37.2';
56
56
  * connector went storefront-v35 → v40 in a single day of UI work for exactly
57
57
  * this reason.
58
58
  */
59
- export const CARD_URI = 'ui://curless/hotel/booking-v72.html';
59
+ export const CARD_URI = 'ui://curless/hotel/booking-v73.html';
60
60
  /** The card as it ships, hashed once - what a host caches under the URI. */
61
61
  const CARD_HTML_SHA = createHash('sha256').update(HOTEL_CARD_HTML).digest('hex');
62
62
  /**
@@ -308,6 +308,15 @@ export const buildServer = (opts) => {
308
308
  // booking card over "can I bring a dog" puts a storefront in front of someone
309
309
  // who asked a question.
310
310
  const CARDLESS = new Set([brand.tools.policies, brand.tools.lookUp]);
311
+ // The card's own steps, which the host keeps from the model: paying with
312
+ // UnionPay is a press on the payment screen, never an assistant's decision.
313
+ // MCP Apps hosts read `ui.visibility`; ChatGPT reads `openai/visibility`.
314
+ const APP_ONLY = new Set([brand.tools.payWithUnionPay]);
315
+ const appOnly = (m) => ({
316
+ ...m,
317
+ ui: { ...m.ui, visibility: ['app'] },
318
+ 'openai/visibility': 'private',
319
+ });
311
320
  // Worked out per answer: an API backend's photographs arrive with its hotel
312
321
  // list, which is still filling in on a first boot.
313
322
  //
@@ -548,7 +557,7 @@ export const buildServer = (opts) => {
548
557
  return c.body(null, 202);
549
558
  if (method === 'tools/list') {
550
559
  return ok(c, id, {
551
- tools: listTools(TOOLS, OUTPUT_SCHEMAS, (name) => (CARDLESS.has(name) ? {} : meta()), TRIP_TOOLS),
560
+ tools: listTools(TOOLS, OUTPUT_SCHEMAS, (name) => (CARDLESS.has(name) ? {} : APP_ONLY.has(name) ? appOnly(meta()) : meta()), TRIP_TOOLS),
552
561
  });
553
562
  }
554
563
  if (method === 'resources/list') {