tf-checkout-react 2.0.0-beta.22 → 2.0.0-beta.23
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/README.md +102 -96
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,44 +1,36 @@
|
|
|
1
1
|
# tf-checkout-react
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
selection, add-ons, buyer details, payment
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
The 2.x source is maintained in
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
The Ticket Fairy checkout for the web. Use the embedded flow or compose its
|
|
4
|
+
ticket selection, add-ons, buyer details, payment and confirmation sections.
|
|
5
|
+
Available features depend on the event, backend and payment provider.
|
|
6
|
+
|
|
7
|
+
The 2.x source is maintained in `tf-shared-libraries/packages/tf-checkout-react`;
|
|
8
|
+
the source repository requires access.
|
|
9
|
+
The shared core is private and bundled into both platform packages. Use React
|
|
10
|
+
18+, React DOM 18+ and React Query 5 on web.
|
|
10
11
|
Never put a confidential OAuth client secret in browser or mobile code. Public
|
|
11
12
|
checkout integrations use registered SDK client IDs and owned buyer sessions.
|
|
12
13
|
|
|
13
|
-
## Prepared paired beta.22
|
|
14
|
-
|
|
15
|
-
[Beta.22 source preparation](../../docs/releases/2.0.0-beta.22.md) adds optional
|
|
16
|
-
captured push-registration context to shared sign-out. Web checkout, storage and
|
|
17
|
-
cache defaults are unchanged. The native package requires an explicit secure
|
|
18
|
-
storage adapter; that migration does not apply to web. Beta.22 is not published
|
|
19
|
-
yet; the verified beta.21 installation below remains the registry checkpoint.
|
|
20
|
-
|
|
21
14
|
## Install
|
|
22
15
|
|
|
23
|
-
|
|
16
|
+
This README describes `2.0.0-beta.23`, the paired 2.x prerelease. Pin it
|
|
17
|
+
explicitly to use this version. `beta` and `latest` are mutable npm tags, not
|
|
18
|
+
guarantees about the highest version; an unqualified install can still resolve
|
|
19
|
+
a stable 1.x package. Check the current dist-tags when choosing a version.
|
|
20
|
+
Publication does not by itself establish backend rollout, device compatibility
|
|
21
|
+
or provider/payment acceptance.
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
records exact archive/member/SHA/SRI proof. Both stable `latest` tags are unchanged.
|
|
29
|
-
Pin the exact version below; `@beta` follows the most recent prerelease. Publication
|
|
30
|
-
does not establish API rollout, app delivery or device/provider acceptance.
|
|
23
|
+
```bash
|
|
24
|
+
npm view tf-checkout-react dist-tags
|
|
25
|
+
```
|
|
31
26
|
|
|
32
27
|
This version preserves quantities across rotating encrypted ticket IDs using
|
|
33
28
|
the API's optional canonical `selectionKey`, while quantity/change APIs and cart
|
|
34
29
|
requests retain the latest encrypted IDs. Deploy and verify the canonical
|
|
35
30
|
base/dated key and dated numeric context before relying on that behavior:
|
|
36
31
|
`display_price`, `price_with_fees`, `fee_included`, `price_currency` and
|
|
37
|
-
`price_symbol`.
|
|
38
|
-
|
|
39
|
-
rotation-retention claim. The [beta.21 notes](https://github.com/theticketfairy/tf-shared-libraries/blob/main/docs/releases/2.0.0-beta.21.md)
|
|
40
|
-
and [app integration contract](https://github.com/theticketfairy/tf-shared-libraries/blob/main/docs/integration/app-sdk.md)
|
|
41
|
-
record API rollout requirements and separate deployment/provider/device gates.
|
|
32
|
+
`price_symbol`. Missing optional keys retain opaque-ID compatibility without a
|
|
33
|
+
rotation-retention claim. The deployed API must provide and validate that data.
|
|
42
34
|
|
|
43
35
|
Post-purchase upgrade waiting is a separate server-owned contract. Only valid
|
|
44
36
|
change-options targets can expose Join or Leave; malformed target IDs, labels
|
|
@@ -47,14 +39,18 @@ must explicitly offer that organizer-configured flow; local receiver validation
|
|
|
47
39
|
does not prove its deployed availability or a completed join.
|
|
48
40
|
|
|
49
41
|
```bash
|
|
50
|
-
npm install tf-checkout-react@2.0.0-beta.
|
|
42
|
+
npm install tf-checkout-react@2.0.0-beta.23 @tanstack/react-query react react-dom
|
|
51
43
|
```
|
|
52
44
|
|
|
53
|
-
`@tanstack/react-query`, `react`, and `react-dom` are peer dependencies
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
`@tanstack/react-query`, `react`, and `react-dom` are peer dependencies. Install
|
|
46
|
+
compatible versions in the host and ensure each context provider uses the same
|
|
47
|
+
React and React Query instances as the SDK. The private shared core and seat
|
|
48
|
+
renderer are bundled; npm installs the package's other declared dependencies.
|
|
49
|
+
Payment-provider scripts and account configuration are separate requirements.
|
|
56
50
|
|
|
57
|
-
|
|
51
|
+
The entry imports its stylesheet, so the host bundler must support CSS imports.
|
|
52
|
+
The stylesheet is also exported as `tf-checkout-react/checkout.css` for hosts
|
|
53
|
+
that need to import it explicitly.
|
|
58
54
|
|
|
59
55
|
## Use it
|
|
60
56
|
|
|
@@ -73,7 +69,7 @@ export const App = () => (
|
|
|
73
69
|
)
|
|
74
70
|
```
|
|
75
71
|
|
|
76
|
-
|
|
72
|
+
`configureCheckout` runs once at app start and
|
|
77
73
|
defaults token storage to `localStorage` (SSR-safe — it no-ops on the server).
|
|
78
74
|
|
|
79
75
|
### Environments
|
|
@@ -91,7 +87,7 @@ configureCheckout({ env: 'STAG', clientId: 'PUBLIC_SDK_CLIENT_ID', clientSecret:
|
|
|
91
87
|
| Prop | Type | Default | Does |
|
|
92
88
|
| ----------------------------------- | ----------------------------------- | ----------- | ----------------------------------------------------------------------- |
|
|
93
89
|
| `eventId` | `string` | — | The event to sell. Required. |
|
|
94
|
-
| `onComplete` | `(order: PlaceOrderResult) => void` | — |
|
|
90
|
+
| `onComplete` | `(order: PlaceOrderResult) => void` | — | Receives the order result, including a possible pending payment. |
|
|
95
91
|
| `confirmationMode` | `'inline' \| 'redirect'` | `'inline'` | `redirect` leaves routing to `onComplete`. |
|
|
96
92
|
| `initialView` | `'tickets' \| 'seats'` | `'tickets'` | Opening screen — preserves an existing `/seat-map` route. |
|
|
97
93
|
| `onViewChange` | `(view) => void` | — | Reports the visible view so hosts can coordinate UI. |
|
|
@@ -100,14 +96,14 @@ configureCheckout({ env: 'STAG', clientId: 'PUBLIC_SDK_CLIENT_ID', clientSecret:
|
|
|
100
96
|
| `collectTicketHolders` | `boolean` | `true` | One named holder per ticket. |
|
|
101
97
|
| `collectHolderContact` | `boolean` | `true` | Also collect holder email/phone. |
|
|
102
98
|
| `skipBillingWhenProfileComplete` | `boolean` | `false` | Skip billing for complete signed-in profiles. Payment is never skipped. |
|
|
103
|
-
| `auth` | `false \|
|
|
99
|
+
| `auth` | `false \| EmbeddedCheckoutAuthOptions` | built-in | Configure or remove the login modal. |
|
|
104
100
|
| `onLogin` | `(email?: string) => void` | — | Open your own login UI instead of the built-in modal. |
|
|
105
101
|
| `privacyPolicy` | `CheckoutPrivacyPolicy` | — | Your privacy policy link and brand name. |
|
|
106
102
|
| `additionalConditions` | `EventCondition[]` | — | Extra required/optional acknowledgements. |
|
|
107
103
|
| `ttfOptInLabel` / `brandOptInLabel` | `string` | — | Override the marketing opt-in copy. |
|
|
108
104
|
| `initialPromoCode` | `string` | — | Apply a promo code on load. |
|
|
109
105
|
| `referrer` | `string \| number` | — | Attribute the sale. |
|
|
110
|
-
| `readAttributionFromUrl` | `boolean` |
|
|
106
|
+
| `readAttributionFromUrl` | `boolean` | `true` | Read supported promo/referrer parameters from the query string. |
|
|
111
107
|
| `showTestCardHint` | `boolean` | `false` | Show sandbox card copy. Demos only. |
|
|
112
108
|
| `theme` | `CheckoutTheme` | — | Recolor via design tokens. |
|
|
113
109
|
| `className` | `string` | — | Class on the root element. |
|
|
@@ -117,6 +113,19 @@ configureCheckout({ env: 'STAG', clientId: 'PUBLIC_SDK_CLIENT_ID', clientSecret:
|
|
|
117
113
|
`<ResumedCheckout />` attaches to a cart created elsewhere — an accepted resale
|
|
118
114
|
invitation, or a session restored after a redirect.
|
|
119
115
|
|
|
116
|
+
### Link attribution and conditional fields
|
|
117
|
+
|
|
118
|
+
The web ticket picker reads `promo` or `promo_code`, and `ttf_r` or
|
|
119
|
+
`referrer_id`, unless URL attribution is disabled. Explicit props take
|
|
120
|
+
precedence. It does not classify an ambiguous numeric `?r=` link. A numeric
|
|
121
|
+
value can represent a promotion or referral; do not pass it as `referrer`
|
|
122
|
+
without authoritative classification. Native hosts must supply explicit
|
|
123
|
+
attribution themselves.
|
|
124
|
+
|
|
125
|
+
This beta leaves conditional custom-field requiredness to the backend and does
|
|
126
|
+
not reproduce all hosted-checkout conditional visibility. Verify the event's
|
|
127
|
+
field behavior against the deployed checkout before relying on parity.
|
|
128
|
+
|
|
120
129
|
## Theming
|
|
121
130
|
|
|
122
131
|
Pass design tokens; the component maps them to CSS variables.
|
|
@@ -136,13 +145,15 @@ Tokens cover color (`accent`, `accentHover`, `accentContrast`, `surface`,
|
|
|
136
145
|
`surfaceMuted`, `text`, `muted`, `border`, `error`, `success`), shape
|
|
137
146
|
(`radiusCard`, `radiusControl`), and typography.
|
|
138
147
|
|
|
139
|
-
|
|
140
|
-
|
|
148
|
+
Checkout section styles use `.tf-checkout` and `tf-checkout-*` classes. Review
|
|
149
|
+
the bundled third-party phone and seat-map styles and standalone component
|
|
150
|
+
styles when integrating them into an existing page.
|
|
141
151
|
|
|
142
152
|
## Composing your own layout
|
|
143
153
|
|
|
144
154
|
Every section reads the same `useCheckout()` store from the provider, so you can
|
|
145
|
-
arrange them however you like.
|
|
155
|
+
arrange them however you like. Mount this under a `QueryClientProvider` as in
|
|
156
|
+
the quickstart.
|
|
146
157
|
|
|
147
158
|
```tsx
|
|
148
159
|
import {
|
|
@@ -152,24 +163,19 @@ import {
|
|
|
152
163
|
BillingInfo,
|
|
153
164
|
Payment,
|
|
154
165
|
OrderSummary,
|
|
155
|
-
useCheckout,
|
|
156
166
|
} from 'tf-checkout-react'
|
|
157
167
|
|
|
158
|
-
const MyCheckout = () =>
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
<
|
|
163
|
-
<
|
|
164
|
-
<
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
<Payment />
|
|
170
|
-
</CheckoutProvider>
|
|
171
|
-
)
|
|
172
|
-
}
|
|
168
|
+
const MyCheckout = () => (
|
|
169
|
+
<CheckoutProvider theme={{ colorScheme: 'dark' }}>
|
|
170
|
+
<Tickets eventId="14304" />
|
|
171
|
+
<AddOns eventId="14304" />
|
|
172
|
+
<div className="my-two-column">
|
|
173
|
+
<BillingInfo />
|
|
174
|
+
<OrderSummary />
|
|
175
|
+
</div>
|
|
176
|
+
<Payment />
|
|
177
|
+
</CheckoutProvider>
|
|
178
|
+
)
|
|
173
179
|
```
|
|
174
180
|
|
|
175
181
|
**Sections** — `Tickets`, `SeatMap`, `AddOns`, `BillingInfo`, `Payment`,
|
|
@@ -190,7 +196,7 @@ leaderboard, who their link has brought in, what they can still win, their pack,
|
|
|
190
196
|
and the card they share.
|
|
191
197
|
|
|
192
198
|
`<OrderConfirmation/>` renders it for you whenever the confirmation response
|
|
193
|
-
carries a `rewards` object:
|
|
199
|
+
carries a `rewards` object. The host supplies `hash` in these examples:
|
|
194
200
|
|
|
195
201
|
```tsx
|
|
196
202
|
<OrderConfirmation orderHash={hash} /> // rewards included
|
|
@@ -206,12 +212,12 @@ import { Rewards } from 'tf-checkout-react'
|
|
|
206
212
|
|
|
207
213
|
It fetches through `ttf` rather than react-query, so it works on a confirmation
|
|
208
214
|
page with no `<QueryClientProvider>`. If your app already has one, fetch with
|
|
209
|
-
`hooks.useOrderRewards(hash)` and pass the
|
|
215
|
+
`hooks.useOrderRewards(hash)` and pass the query's `data` payload to `Rewards`.
|
|
210
216
|
|
|
211
217
|
**Sharing.** The buttons are the channels the organiser enabled, filtered to
|
|
212
|
-
what this browser can do. On a phone the OS share sheet
|
|
213
|
-
share card as a file
|
|
214
|
-
|
|
218
|
+
what this browser can do. On a phone the OS share sheet is attempted and may
|
|
219
|
+
include the share card as a file. Other options use link intents or copy; the
|
|
220
|
+
browser or user can deny an individual share or clipboard operation.
|
|
215
221
|
|
|
216
222
|
**Snapchat is opt-in.** It loads a third-party script (`sdk.snapkit.com`) that
|
|
217
223
|
your page's content policy has to allow, so it renders only when you ask:
|
|
@@ -232,40 +238,38 @@ in `en-GB` and `es-MX`.
|
|
|
232
238
|
`useCheckout()` gives you the whole flow with no UI at all.
|
|
233
239
|
|
|
234
240
|
```tsx
|
|
235
|
-
|
|
241
|
+
import { useCheckout, type TicketSelection } from 'tf-checkout-react'
|
|
236
242
|
|
|
237
|
-
|
|
238
|
-
checkout
|
|
239
|
-
checkout.
|
|
240
|
-
|
|
241
|
-
const order = await checkout.placeOrder('card')
|
|
243
|
+
function Reserve({ eventId, selections }: { eventId: string; selections: TicketSelection[] }) {
|
|
244
|
+
const checkout = useCheckout()
|
|
245
|
+
return <button onClick={() => { void checkout.setTickets(eventId, selections) }}>Reserve</button>
|
|
246
|
+
}
|
|
242
247
|
```
|
|
243
248
|
|
|
244
|
-
|
|
249
|
+
Build `selections` from the current event catalog, then collect applicable
|
|
250
|
+
billing, holder and consent data before calling `placeOrder`. The hook exposes
|
|
251
|
+
the live snapshot (status, cart, pricing, errors), `isBusy`,
|
|
245
252
|
`secondsLeft` for the reservation countdown, `buyerFields` (the extra fields
|
|
246
253
|
this event gates — render them from data), `missingRequiredAddonNames`, and
|
|
247
254
|
`isLoggedIn`.
|
|
248
255
|
|
|
249
|
-
|
|
250
|
-
is
|
|
256
|
+
The engine coordinates concurrent placement and retains an order when a payment
|
|
257
|
+
outcome is uncertain. Confirm the authoritative order and provider status before
|
|
258
|
+
retrying or fulfilling; this is not a guarantee of exactly-once charging across
|
|
259
|
+
all hosts and providers.
|
|
251
260
|
|
|
252
261
|
### Starting a new checkout
|
|
253
262
|
|
|
254
|
-
`reset()`
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
of the order, such as an expired reservation, releases it.
|
|
265
|
-
|
|
266
|
-
To know which happened, await `resetWhenSettled()` instead. It resolves `true`
|
|
267
|
-
once the checkout is reset, or `false` when it kept the order. In that case,
|
|
268
|
-
show the buyer `PAID_ORDER_PENDING_MESSAGE`. While it waits for a payment
|
|
263
|
+
`reset()` returns nothing and starts a reset. If payment is in flight, the
|
|
264
|
+
engine waits for that operation; it retains an order when its recorded state
|
|
265
|
+
indicates money may have moved. A closed provider page or network error is not
|
|
266
|
+
proof that no payment occurred. Reconcile the order with the backend and payment
|
|
267
|
+
provider before retrying or fulfilling it.
|
|
268
|
+
|
|
269
|
+
To know whether reset completed, await `resetWhenSettled()` instead. It resolves
|
|
270
|
+
`true` after reset or `false` when reset cannot proceed, including a retained
|
|
271
|
+
order or a retired checkout. For a payment that may have moved, show the buyer
|
|
272
|
+
`PAID_ORDER_PENDING_MESSAGE` and reconcile it. While it waits for a payment
|
|
269
273
|
(`status === 'placing'`), tell the buyer, for example "Finishing your
|
|
270
274
|
payment…":
|
|
271
275
|
|
|
@@ -274,16 +278,18 @@ if (checkout.status === 'placing') setNotice('Finishing your payment…')
|
|
|
274
278
|
if (!(await checkout.resetWhenSettled())) setNotice(PAID_ORDER_PENDING_MESSAGE)
|
|
275
279
|
```
|
|
276
280
|
|
|
277
|
-
A custom `providerPage` must resolve `'dismiss'` when it closes or
|
|
278
|
-
|
|
281
|
+
A custom `providerPage` must resolve `{ event: 'dismiss' }` when it closes or
|
|
282
|
+
unmounts, and other custom ports must settle too, or `resetWhenSettled()` waits.
|
|
279
283
|
|
|
280
|
-
A custom confirmer
|
|
281
|
-
`paymentProviderError(message,
|
|
282
|
-
|
|
284
|
+
A custom confirmer can classify a failure with
|
|
285
|
+
`paymentProviderError(message, outcome)`, where `outcome` is `declined`,
|
|
286
|
+
`cancelled`, `notStarted` or `unknown`. Use the first three only when the
|
|
287
|
+
provider confirms that no charge occurred. An unknown outcome needs
|
|
288
|
+
reconciliation, not an assumption that payment failed.
|
|
283
289
|
|
|
284
|
-
For direct API access, the
|
|
285
|
-
`
|
|
286
|
-
|
|
290
|
+
For direct API access, the shared SDK exports are available from this package,
|
|
291
|
+
including `ttf`, hooks, types and the engine. The package's TypeScript
|
|
292
|
+
declarations describe its public exports.
|
|
287
293
|
|
|
288
294
|
## Card fields
|
|
289
295
|
|
|
@@ -303,11 +309,12 @@ pnpm run start:react
|
|
|
303
309
|
`pnpm run playground:react` opens the docs-style playground instead, with a
|
|
304
310
|
live preview and source for each panel.
|
|
305
311
|
|
|
306
|
-
|
|
312
|
+
Use only public, non-secret configuration in `example/.env`; never put a
|
|
313
|
+
confidential credential in browser code.
|
|
307
314
|
|
|
308
315
|
---
|
|
309
316
|
|
|
310
|
-
|
|
317
|
+
The checkout monorepo is available to authorised repository collaborators.
|
|
311
318
|
|
|
312
319
|
|
|
313
320
|
Public checkout sign-in uses event-scoped server-only buyer binding, without a bundled
|
|
@@ -315,6 +322,5 @@ client secret. The checkout's auth modal supplies the event automatically; stand
|
|
|
315
322
|
`AuthModal` callers pass `checkoutEventId` and can receive the narrow
|
|
316
323
|
`onCheckoutAuthenticated(CheckoutBuyerProfile)` callback. Password/signup/email/phone
|
|
317
324
|
proofs still complete required two-factor verification. These credentials cannot read
|
|
318
|
-
private account preferences or tickets.
|
|
319
|
-
scope, retry, logout and configuration ownership. Existing confidential OAuth clients
|
|
325
|
+
private account preferences or tickets. Existing confidential OAuth clients
|
|
320
326
|
are trusted-server integrations; never distribute their secrets in browser/native code.
|
package/package.json
CHANGED