@curless/hotel-storefront 0.34.0 → 0.35.1
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/aggregate/make.d.ts.map +1 -1
- package/dist/aggregate/make.js +7 -1
- package/dist/aggregate/make.js.map +1 -1
- package/dist/backend.d.ts +2 -2
- package/dist/backend.d.ts.map +1 -1
- package/dist/card.generated.d.ts +1 -1
- package/dist/card.generated.js +2 -2
- package/dist/card.generated.js.map +1 -1
- package/dist/config.d.ts +24 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/huazhu/backend.d.ts +2 -2
- package/dist/huazhu/backend.d.ts.map +1 -1
- package/dist/huazhu/backend.js +119 -10
- package/dist/huazhu/backend.js.map +1 -1
- package/dist/huazhu/bookings.d.ts +2 -0
- package/dist/huazhu/bookings.d.ts.map +1 -1
- package/dist/huazhu/bookings.js.map +1 -1
- package/dist/huazhu/catalog.d.ts +7 -1
- package/dist/huazhu/catalog.d.ts.map +1 -1
- package/dist/huazhu/catalog.js +8 -4
- package/dist/huazhu/catalog.js.map +1 -1
- package/dist/huazhu/make.d.ts.map +1 -1
- package/dist/huazhu/make.js +44 -13
- package/dist/huazhu/make.js.map +1 -1
- package/dist/legal.d.ts.map +1 -1
- package/dist/legal.js +131 -83
- package/dist/legal.js.map +1 -1
- package/dist/payments/checkout.d.ts +49 -1
- package/dist/payments/checkout.d.ts.map +1 -1
- package/dist/payments/checkout.js +9 -0
- package/dist/payments/checkout.js.map +1 -1
- package/dist/payments/fake-stripe.d.ts +37 -0
- package/dist/payments/fake-stripe.d.ts.map +1 -0
- package/dist/payments/fake-stripe.js +123 -0
- package/dist/payments/fake-stripe.js.map +1 -0
- package/dist/payments/stripe-checkout.d.ts +44 -0
- package/dist/payments/stripe-checkout.d.ts.map +1 -0
- package/dist/payments/stripe-checkout.js +166 -0
- package/dist/payments/stripe-checkout.js.map +1 -0
- package/dist/server.d.ts +2 -2
- package/dist/server.js +2 -2
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +34 -20
- package/dist/surface.js.map +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +45 -23
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vocab.d.ts +20 -0
- package/dist/vocab.d.ts.map +1 -1
- package/dist/vocab.js +25 -2
- package/dist/vocab.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.generated.js","sourceRoot":"","sources":["../src/card.generated.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,wEAAwE;AACxE,gFAAgF;AAChF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAW,MAAM,CAAC,IAAI,CAChD,
|
|
1
|
+
{"version":3,"file":"card.generated.js","sourceRoot":"","sources":["../src/card.generated.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,wEAAwE;AACxE,gFAAgF;AAChF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAW,MAAM,CAAC,IAAI,CAChD,kvwzBAAkvwzB,EAClvwzB,QAAQ,CACT,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAEnB,6GAA6G;AAC7G,MAAM,CAAC,MAAM,qBAAqB,GAChC,kEAAkE,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -247,10 +247,17 @@ export type ApiSource = {
|
|
|
247
247
|
* is `<prefix>_GATEWAY_KEY` in the environment, never here.
|
|
248
248
|
*/
|
|
249
249
|
prepaid?: {
|
|
250
|
-
/**
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
250
|
+
/**
|
|
251
|
+
* Who takes the money: the agentbank gateway (the default), or Stripe
|
|
252
|
+
* directly - its hosted Checkout page and refunds, test mode only, the key
|
|
253
|
+
* in `<prefix>_STRIPE_KEY` (robin, 2026-10-15: Curless's acquiring is not
|
|
254
|
+
* connected yet, and no merchant can be opened there).
|
|
255
|
+
*/
|
|
256
|
+
provider?: 'gateway' | 'stripe';
|
|
257
|
+
/** The gateway, e.g. https://mcp.curless.ai. Needed for `gateway`. */
|
|
258
|
+
gatewayUrl?: string;
|
|
259
|
+
/** The Curless merchant the money is taken for (a test-mode one). Needed for `gateway`. */
|
|
260
|
+
merchantId?: string;
|
|
254
261
|
/** On the paying page as whose order it is. Default: the brand. */
|
|
255
262
|
merchantName?: string;
|
|
256
263
|
merchantUrl?: string;
|
|
@@ -269,6 +276,19 @@ export type ApiSource = {
|
|
|
269
276
|
* tester they hold a real room.
|
|
270
277
|
*/
|
|
271
278
|
sandbox?: boolean;
|
|
279
|
+
/**
|
|
280
|
+
* The group's own TEST environment (华住, 2026-10-15: test-*.huazhu.com): its
|
|
281
|
+
* test hotels, rates and photographs - the group's, not invented - and test
|
|
282
|
+
* bookings in its test system, which hold no room for anyone and are never
|
|
283
|
+
* paid. The payloads say `demo` and `test`, the card prints its strip, and
|
|
284
|
+
* the instructions and pages say it is a test system, never "simulated".
|
|
285
|
+
*
|
|
286
|
+
* ⚠️ NOT `sandbox`, and never both: a sandbox's hotels are made up and its
|
|
287
|
+
* pictures stock; a test system's are the group's own. Without either, an
|
|
288
|
+
* api source is taken to be real - and a test system taken for real would
|
|
289
|
+
* tell a tester they hold a room at a hotel.
|
|
290
|
+
*/
|
|
291
|
+
test?: boolean;
|
|
272
292
|
/**
|
|
273
293
|
* A directory this deployment may WRITE: the copy of the hotel list and the
|
|
274
294
|
* bookings it made. Absolute, or against the config file's directory - and
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,WAAW,GAAG;IACxB,sFAAsF;IACtF,EAAE,EAAE,MAAM,CAAC;IAEX,oFAAoF;IACpF,KAAK,EAAE,MAAM,CAAC;IAEd,qDAAqD;IACrD,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd;;;;;WAKG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB;;;;;;WAMG;QACH,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB;;;;;;;;WAQG;QACH,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB;;;;;;;;WAQG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB;;;;;;;;;;WAUG;QACH,OAAO,CAAC,EAAE,MAAM,GAAG;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACrE;;;;;;;;;;;;;;WAcG;QACH,KAAK,CAAC,EAAE;YACN,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;YAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;YACnB;;;;;eAKG;YACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;SACpC,CAAC;QACF;;;;;WAKG;QACH,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;IAEF;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,sFAAsF;QACtF,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF,iCAAiC;IACjC,IAAI,EAAE;QACJ;;;;;;;;WAQG;QACH,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,WAAW,CAAC;QACrC,2FAA2F;QAC3F,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;QAC7B,gFAAgF;QAChF,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,mDAAmD;QACnD,GAAG,CAAC,EAAE,SAAS,CAAC;QAChB;;;;;WAKG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB;;;WAGG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF;;;;;OAKG;IACH,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;KACzB,CAAC;IAEF,2GAA2G;IAC3G,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IAEF;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QAGf,6EAA6E;QAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB;;;;;WAKG;QACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IAEF,KAAK,EAAE;QACL,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,mEAAmE;QACnE,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF;;;;;;;;GAQG;AACH;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,0GAA0G;IAC1G,EAAE,EAAE,MAAM,CAAC;IACX,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,QAAQ,CAAC;IACnB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE;QACR;;;;;WAKG;QACH,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;QAChC,sEAAsE;QACtE,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,2FAA2F;QAC3F,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,mEAAmE;QACnE,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gCAAgC;QAChC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,0GAA0G;IAC1G,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CACjC,CAAC;AAQF;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,GAAI,QAAQ,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;CAiC5D,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC"}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAqVA,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE,CACjC,CAAC;KACE,WAAW,EAAE;KACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;KAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAE3B;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,MAAmC,EAAE,EAAE;IAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,IAAI,OAAO,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;IAC7D,OAAO;QACL,UAAU,EAAE,QAAQ,MAAM,GAAG,MAAM,EAAE;QACrC,QAAQ,EAAE,OAAO,MAAM,GAAG,IAAI,EAAE;QAChC,yEAAyE;QACzE,0EAA0E;QAC1E,+CAA+C;QAC/C,MAAM,EAAE,WAAW,MAAM,GAAG,MAAM,EAAE;QACpC,UAAU,EAAE,QAAQ,MAAM,QAAQ;QAClC,SAAS,EAAE,UAAU,MAAM,MAAM;QACjC,QAAQ,EAAE,QAAQ,MAAM,MAAM;QAC9B,SAAS,EAAE,SAAS,MAAM,MAAM;QAChC,cAAc,EAAE,WAAW,MAAM,SAAS;QAC1C,YAAY,EAAE,WAAW,MAAM,UAAU;QACzC,mBAAmB,EAAE,WAAW,MAAM,cAAc;QACpD,aAAa,EAAE,UAAU,MAAM,SAAS;QACxC,yEAAyE;QACzE,kEAAkE;QAClE,aAAa,EAAE,WAAW,MAAM,gBAAgB;QAChD,aAAa,EAAE,UAAU,MAAM,SAAS;QACxC,QAAQ,EAAE,OAAO,MAAM,GAAG,IAAI,WAAW;QACzC,wEAAwE;QACxE,2EAA2E;QAC3E,6DAA6D;QAC7D,OAAO,EAAE,WAAW,MAAM,GAAG,MAAM,EAAE;QACrC,SAAS,EAAE,QAAQ,MAAM,WAAW;QACpC,MAAM,EAAE,WAAW,MAAM,QAAQ;QACjC,OAAO,EAAE,YAAY,MAAM,QAAQ;QACnC,iBAAiB,EAAE,UAAU,MAAM,aAAa;KACxC,CAAC;AACb,CAAC,CAAC"}
|
package/dist/huazhu/backend.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type BackendCapabilities, type HotelBackend } from '../backend.js';
|
|
2
2
|
import { type BookingLimits } from '../limits.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { Checkout } from '../payments/checkout.js';
|
|
4
4
|
import type { Quote, ShownQuote } from '../types.js';
|
|
5
5
|
import { type BookingStore, type Reconciler, type StoredBooking } from './bookings.js';
|
|
6
6
|
import { type Catalog } from './catalog.js';
|
|
@@ -36,7 +36,7 @@ export type HuazhuHotelsOptions = {
|
|
|
36
36
|
* page before Huazhu is asked (`OPN`). A sandbox only - see `ApiSource.prepaid`.
|
|
37
37
|
*/
|
|
38
38
|
prepaid?: {
|
|
39
|
-
checkout:
|
|
39
|
+
checkout: Checkout;
|
|
40
40
|
payWithinMs?: number;
|
|
41
41
|
};
|
|
42
42
|
now?: () => number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/huazhu/backend.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,mBAAmB,EAExB,KAAK,YAAY,EAMlB,MAAM,eAAe,CAAC;AAavB,OAAO,EAAkB,KAAK,aAAa,EAAkC,MAAM,cAAc,CAAC;AAElG,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/huazhu/backend.ts"],"names":[],"mappings":"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"}
|
package/dist/huazhu/backend.js
CHANGED
|
@@ -129,6 +129,29 @@ const mealPlanOf = (s) => {
|
|
|
129
129
|
const plan = MEAL_PLAN[s.mealType];
|
|
130
130
|
return plan ? { plan, ...(s.mealCount > 0 ? { count: s.mealCount } : {}) } : undefined;
|
|
131
131
|
};
|
|
132
|
+
/**
|
|
133
|
+
* What kind of rate a Huazhu rate's name says it is - "门市价含早" is the
|
|
134
|
+
* standard rate - for a card to say in the guest's language (香格里拉,
|
|
135
|
+
* 2026-10-15). The more particular words first; a name that says none of
|
|
136
|
+
* them - "集团OTA双早" - has no kind, and the card shows it as it is.
|
|
137
|
+
*/
|
|
138
|
+
const RATE_KIND = [
|
|
139
|
+
['周中特惠', 'weekday-special'],
|
|
140
|
+
['限时特惠', 'flash-sale'],
|
|
141
|
+
['夜宵房', 'late-night'],
|
|
142
|
+
['精选套餐', 'package'],
|
|
143
|
+
['套餐', 'package'],
|
|
144
|
+
['会员价', 'member'],
|
|
145
|
+
['门市价', 'standard'],
|
|
146
|
+
['时租', 'hourly'],
|
|
147
|
+
['钟点', 'hourly'],
|
|
148
|
+
['特惠', 'special'],
|
|
149
|
+
];
|
|
150
|
+
const rateKindOf = (p) => {
|
|
151
|
+
const name = p.rateCodeName ?? '';
|
|
152
|
+
const said = RATE_KIND.find(([word]) => name.includes(word))?.[1];
|
|
153
|
+
return said ?? (p.checkinType === 'HOUR' ? 'hourly' : undefined);
|
|
154
|
+
};
|
|
132
155
|
/** Huazhu's bed names as codes; another is `other`, with its own word. */
|
|
133
156
|
const BED_KIND = { 大床: 'king', 双床: 'twin', 单人床: 'single' };
|
|
134
157
|
const bedTypesOf = (rt) => (rt?.bedTypeList ?? [])
|
|
@@ -457,7 +480,11 @@ export const createHuazhuHotels = (opts) => {
|
|
|
457
480
|
const ariTtl = opts.ariTtlMs ?? 60_000;
|
|
458
481
|
const productsTtl = opts.productsTtlMs ?? 10 * 60_000;
|
|
459
482
|
const allowTags = new Set(opts.allowTags ?? []);
|
|
460
|
-
const view = {
|
|
483
|
+
const view = {
|
|
484
|
+
language: opts.language,
|
|
485
|
+
tz: opts.tz,
|
|
486
|
+
...(opts.testEnvironment ? { test: true } : {}),
|
|
487
|
+
};
|
|
461
488
|
const en = opts.language === 'en';
|
|
462
489
|
/** A room type's name in the connector's language - see english.ts. */
|
|
463
490
|
const roomTypeOf = (p) => (en ? roomNameEn(p.roomTypeName) : undefined) ?? p.roomTypeName;
|
|
@@ -568,7 +595,7 @@ export const createHuazhuHotels = (opts) => {
|
|
|
568
595
|
/** A hotel's own name in each language Huazhu writes it in - beside every `hotelName`. */
|
|
569
596
|
const hotelNamesOf = (hotelId) => {
|
|
570
597
|
const raw = findHotel(hotelId);
|
|
571
|
-
return raw ? namesOf(raw).name : undefined;
|
|
598
|
+
return raw ? namesOf(raw, !!opts.testEnvironment).name : undefined;
|
|
572
599
|
};
|
|
573
600
|
/**
|
|
574
601
|
* Every hotel a name could be - the ones `findHotel` will not choose
|
|
@@ -928,7 +955,11 @@ export const createHuazhuHotels = (opts) => {
|
|
|
928
955
|
...(bedTypesOf(rt).length ? { bedTypes: bedTypesOf(rt) } : {}),
|
|
929
956
|
roomsLeft: s.roomsLeft,
|
|
930
957
|
roomType: { id: p.product.roomTypeCode, name: roomTypeOf(p.product) },
|
|
931
|
-
rate: {
|
|
958
|
+
rate: {
|
|
959
|
+
id: p.product.rateCode,
|
|
960
|
+
name: rateNameOf(p.product),
|
|
961
|
+
...(rateKindOf(p.product) ? { kind: rateKindOf(p.product) } : {}),
|
|
962
|
+
},
|
|
932
963
|
labels: rateLabels(p.product, { type: s.mealType, count: s.mealCount }),
|
|
933
964
|
// ⚠️ PREPAID ONLY WHERE THIS DEPLOYMENT TAKES PAYMENT - a sandbox's test
|
|
934
965
|
// mode (`opts.prepaid`); everywhere else `sell` leaves prepaid rates out
|
|
@@ -1140,7 +1171,9 @@ export const createHuazhuHotels = (opts) => {
|
|
|
1140
1171
|
kind: 'room',
|
|
1141
1172
|
hotelId: h.hotelId,
|
|
1142
1173
|
hotelName,
|
|
1143
|
-
...(namesOf(h
|
|
1174
|
+
...(namesOf(h, !!opts.testEnvironment).name
|
|
1175
|
+
? { hotelNames: namesOf(h, !!opts.testEnvironment).name }
|
|
1176
|
+
: {}),
|
|
1144
1177
|
roomRef: room.id,
|
|
1145
1178
|
title: room.name,
|
|
1146
1179
|
detail: [
|
|
@@ -1154,6 +1187,16 @@ export const createHuazhuHotels = (opts) => {
|
|
|
1154
1187
|
// The same as codes, for a card in another language: each of the
|
|
1155
1188
|
// detail's parts - beds · window · meals · hours (`hourly`) - so the
|
|
1156
1189
|
// card can say all of it, not some (香格里拉, 2026-10-14).
|
|
1190
|
+
// The rate part of the title - "门市价含早" of "高级大床房 · 门市价含早"
|
|
1191
|
+
// - and what kind of rate it is, for a card in another language.
|
|
1192
|
+
...(room.rate
|
|
1193
|
+
? {
|
|
1194
|
+
rate: {
|
|
1195
|
+
name: room.rate.name,
|
|
1196
|
+
...(room.rate.kind ? { kind: room.rate.kind } : {}),
|
|
1197
|
+
},
|
|
1198
|
+
}
|
|
1199
|
+
: {}),
|
|
1157
1200
|
...(room.bedTypes?.length ? { bedTypes: room.bedTypes } : {}),
|
|
1158
1201
|
...(room.window ? { window: room.window } : {}),
|
|
1159
1202
|
...(room.meal ? { meal: room.meal } : {}),
|
|
@@ -1587,7 +1630,8 @@ export const createHuazhuHotels = (opts) => {
|
|
|
1587
1630
|
const tries = (p.refund?.tries ?? 0) + 1;
|
|
1588
1631
|
const at = p.refund?.at ?? now();
|
|
1589
1632
|
try {
|
|
1590
|
-
|
|
1633
|
+
// Named by when it was decided: the same refund retried is the same refund.
|
|
1634
|
+
const r = await checkout.refund(p.sessionId, reason, `${row.distributorResId}-${at}`);
|
|
1591
1635
|
store.update(id, {
|
|
1592
1636
|
prepaid: { ...p, refund: { reason, at, requestId: r.requestId, status: r.status, tries } },
|
|
1593
1637
|
});
|
|
@@ -1603,6 +1647,7 @@ export const createHuazhuHotels = (opts) => {
|
|
|
1603
1647
|
}
|
|
1604
1648
|
};
|
|
1605
1649
|
/** Whether a booking paid in advance still has money work to do. */
|
|
1650
|
+
let ticking = false;
|
|
1606
1651
|
const moneyPending = (b) => {
|
|
1607
1652
|
const p = b.prepaid;
|
|
1608
1653
|
if (!p)
|
|
@@ -1611,6 +1656,9 @@ export const createHuazhuHotels = (opts) => {
|
|
|
1611
1656
|
return true;
|
|
1612
1657
|
if (!p.paidAt)
|
|
1613
1658
|
return false;
|
|
1659
|
+
// Booked: Huazhu's order number still to be written onto the payment, once.
|
|
1660
|
+
if (b.status === 'confirmed' && b.resId && !p.noted && !p.refund && checkout?.annotate)
|
|
1661
|
+
return true;
|
|
1614
1662
|
if (!p.refund?.requestId)
|
|
1615
1663
|
return !!p.refund || b.status === 'failed' || b.status === 'unconfirmed';
|
|
1616
1664
|
return !['refunded', 'failed', 'rejected'].includes(p.refund.status ?? '');
|
|
@@ -1642,6 +1690,36 @@ export const createHuazhuHotels = (opts) => {
|
|
|
1642
1690
|
return; // asked again on the next pass
|
|
1643
1691
|
}
|
|
1644
1692
|
if (state === 'paid') {
|
|
1693
|
+
// ⚠️ THE MONEY HELD TO THE QUOTE BEFORE ANYTHING IS BOOKED (总线程,
|
|
1694
|
+
// 2026-10-15): what the page took, to the fen and in the currency,
|
|
1695
|
+
// is the total the guest was shown. A page paid for anything else
|
|
1696
|
+
// books nothing, and all of what it took goes back.
|
|
1697
|
+
let took;
|
|
1698
|
+
try {
|
|
1699
|
+
took = await checkout.paidAmount(p.sessionId);
|
|
1700
|
+
}
|
|
1701
|
+
catch {
|
|
1702
|
+
return; // asked again on the next pass
|
|
1703
|
+
}
|
|
1704
|
+
const want = row.quote.total;
|
|
1705
|
+
if (!took || took.amountMinor !== want.minor || took.currency !== want.currency) {
|
|
1706
|
+
const said = took ? `${took.amountMinor} ${took.currency}` : 'an amount it could not say';
|
|
1707
|
+
store.update(row.id, {
|
|
1708
|
+
status: 'failed',
|
|
1709
|
+
prepaid: {
|
|
1710
|
+
...p,
|
|
1711
|
+
paidAt: now(),
|
|
1712
|
+
url: undefined,
|
|
1713
|
+
refund: {
|
|
1714
|
+
reason: `the payment page took ${said}, not the ${want.minor} ${want.currency} quoted - nothing was booked`,
|
|
1715
|
+
at: now(),
|
|
1716
|
+
tries: 0,
|
|
1717
|
+
},
|
|
1718
|
+
},
|
|
1719
|
+
});
|
|
1720
|
+
console.error(`[huazhu prepaid ${row.id}] ⚠️ paid ${said} against ${want.minor} ${want.currency} quoted: not booked, refunding`);
|
|
1721
|
+
return;
|
|
1722
|
+
}
|
|
1645
1723
|
store.update(row.id, { prepaid: { ...p, paidAt: now(), url: undefined } });
|
|
1646
1724
|
await bookPaid(row.id);
|
|
1647
1725
|
}
|
|
@@ -1655,6 +1733,22 @@ export const createHuazhuHotels = (opts) => {
|
|
|
1655
1733
|
}
|
|
1656
1734
|
if (!p.paidAt)
|
|
1657
1735
|
return;
|
|
1736
|
+
// ⚠️ HUAZHU'S ORDER NUMBER ON THE PAYMENT, ONCE (总线程, 2026-10-15), so
|
|
1737
|
+
// Stripe's dashboard and Huazhu's order are one look apart. Tried once:
|
|
1738
|
+
// a failure is said in the log and never touches the booking.
|
|
1739
|
+
if (row.status === 'confirmed' && row.resId && !p.noted && !p.refund && checkout.annotate) {
|
|
1740
|
+
store.update(row.id, { prepaid: { ...p, noted: now() } });
|
|
1741
|
+
try {
|
|
1742
|
+
await checkout.annotate(p.sessionId ?? '', {
|
|
1743
|
+
huazhu_res_id: row.resId,
|
|
1744
|
+
...(row.resCode ? { huazhu_res_code: row.resCode } : {}),
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
catch (err) {
|
|
1748
|
+
console.error(`[huazhu prepaid ${row.id}] Huazhu's order ${row.resId} could not be written onto payment ${p.sessionId}: ${err.message}`);
|
|
1749
|
+
}
|
|
1750
|
+
return;
|
|
1751
|
+
}
|
|
1658
1752
|
if (!p.refund?.requestId &&
|
|
1659
1753
|
(p.refund || row.status === 'failed' || row.status === 'unconfirmed')) {
|
|
1660
1754
|
await refundOf(row.id, p.refund?.reason ??
|
|
@@ -1707,7 +1801,9 @@ export const createHuazhuHotels = (opts) => {
|
|
|
1707
1801
|
failed.push({
|
|
1708
1802
|
hotelId: line.hotelId,
|
|
1709
1803
|
hotelName: named?.hotel ?? (raw ? toHotel(raw, view, now()).name : line.hotelId),
|
|
1710
|
-
...(raw && namesOf(raw
|
|
1804
|
+
...(raw && namesOf(raw, !!opts.testEnvironment).name
|
|
1805
|
+
? { hotelNames: namesOf(raw, !!opts.testEnvironment).name }
|
|
1806
|
+
: {}),
|
|
1711
1807
|
stay: line.stay,
|
|
1712
1808
|
...(line.hourly ? { hourly: line.hourly } : {}),
|
|
1713
1809
|
...(named?.room ? { roomName: named.room } : {}),
|
|
@@ -1857,6 +1953,7 @@ export const createHuazhuHotels = (opts) => {
|
|
|
1857
1953
|
try {
|
|
1858
1954
|
opened = await checkout.open({
|
|
1859
1955
|
ref: dres,
|
|
1956
|
+
code: row.confirmationCode,
|
|
1860
1957
|
title: `${plan.qline.hotelName} · ${plan.qline.title}`.slice(0, 200),
|
|
1861
1958
|
amountMinor: allIn,
|
|
1862
1959
|
currency: cur,
|
|
@@ -2064,9 +2161,19 @@ export const createHuazhuHotels = (opts) => {
|
|
|
2064
2161
|
* money going back.
|
|
2065
2162
|
*/
|
|
2066
2163
|
async prepaidTick() {
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2164
|
+
// ⚠️ ONE PASS AT A TIME: a pass slower than the ten seconds between
|
|
2165
|
+
// them would otherwise book a paid stay, or give money back, twice.
|
|
2166
|
+
if (ticking)
|
|
2167
|
+
return;
|
|
2168
|
+
ticking = true;
|
|
2169
|
+
try {
|
|
2170
|
+
for (const row of store.all())
|
|
2171
|
+
if (moneyPending(row))
|
|
2172
|
+
await settlePrepaid(row);
|
|
2173
|
+
}
|
|
2174
|
+
finally {
|
|
2175
|
+
ticking = false;
|
|
2176
|
+
}
|
|
2070
2177
|
},
|
|
2071
2178
|
imageDomains() {
|
|
2072
2179
|
const hosts = new Set();
|
|
@@ -2091,6 +2198,8 @@ export const createHuazhuHotels = (opts) => {
|
|
|
2091
2198
|
const ceilingHitAt = store.ceilingHitAt;
|
|
2092
2199
|
const ceiling = ceilingHitAt !== undefined && now() - ceilingHitAt < DAY_MS;
|
|
2093
2200
|
return {
|
|
2201
|
+
// Which Huazhu this is, for whoever checks a deployment: its test system or not.
|
|
2202
|
+
...(opts.testEnvironment ? { test: true } : {}),
|
|
2094
2203
|
catalog: catalog.state(),
|
|
2095
2204
|
bookings: rows.length,
|
|
2096
2205
|
pending: rows.filter((r) => r.pendingSince !== undefined).length,
|
|
@@ -2466,7 +2575,7 @@ export const createHuazhuHotels = (opts) => {
|
|
|
2466
2575
|
const name = hotel?.name ?? h.hotelName;
|
|
2467
2576
|
// 全季酒店(北京国贸店) already says 北京 - as the demonstration's do.
|
|
2468
2577
|
const city = hotel?.city && !name.includes(hotel.city) ? hotel.city : undefined;
|
|
2469
|
-
const names = namesOf(h).name;
|
|
2578
|
+
const names = namesOf(h, !!opts.testEnvironment).name;
|
|
2470
2579
|
return { id: h.hotelId, name, ...(city ? { city } : {}), ...(names ? { names } : {}) };
|
|
2471
2580
|
});
|
|
2472
2581
|
},
|