TheTicketFairy ReactNative Checkout library
npm install tf-checkout-react-nativeReact Native library for Ticket Fairy checkout.
For Single Sign-On (SSO) Please be aware that this is the first version of the implementation, we are working to release a V2, that will cover other use cases, in the near future.
Configure ReactNative environment for desired platforms (iOS, Android or both).
- React Native version 0.81.4
- React version 19.1.0
- Node version 20.18.3 or later
- Android 5.0 (API level 21) and above
- Gradle plugin version 7.3.1
- Gradle version 7.5.1
- Compile Sdk Version and Target Sdk Version 33
- Build Tools Version 33.0.0
- Java version 1.8
- Kotlin version 1.5.31
Add the following to your Android Manifest as activity property.
To download the PDFs, add the WRITE_EXTERNAL_STORAGE permission to the Android's Manifest file.
``xml`
- Compatible with apps targeting iOS 13.0 or above.1.10.1
- Pods version 13.0
- Command Line Tools version
To download the PDFs, add the following flags to Info.plist file:
``
- UIFileSharingEnabled: Application supports iTunes file sharing
- LSSupportsOpeningDocumentsInPlace: Supports opening documents in place
đź”— Required peer dependencies
This package relies on several React Native native modules. You need to install them in your app for the SDK to work properly:
If you are running on bare React Native, you will need to install the following dependencies:
`shUsing pnpm
pnpm add tf-checkout-react-native \
@react-native-async-storage/async-storage@^2.0.0 \
@react-native-clipboard/clipboard@^1.14.0 \
@react-native-community/datetimepicker@^8.0.0 \
react-native-background-timer@^2.4.1 \
react-native-device-country@^1.1.1 \
react-native-fs@^2.18.0 \
@stripe/stripe-react-native@^0.54.0
If you are running on expo, you will need to install the following dependencies:
`sh
Using pnpm
pnpm add tf-checkout-react-native \
@react-native-async-storage/async-storage@^2.0.0 \
@react-native-clipboard/clipboard@^1.14.0 \
react-native-background-timer@^2.4.1Using yarn
yarn add tf-checkout-react-native \
@react-native-async-storage/async-storage@^2.0.0 \
@react-native-clipboard/clipboard@^1.14.0 \
react-native-background-timer@^2.4.1Using npm
npm install tf-checkout-react-native \
@react-native-async-storage/async-storage@^2.0.0 \
@react-native-clipboard/clipboard@^1.14.0 \
react-native-background-timer@^2.4.1
`Make sure to install all the required dependencies in your project.
$3
Add the following to your
metro.config.js in the resolver property:sourceExts: ['jsx', 'js', 'ts', 'tsx']Result:
`js
module.exports = {
watchFolders: [moduleRoot],
resolver: {
sourceExts: ['jsx', 'js', 'ts', 'tsx'],
extraNodeModules: {
react: path.resolve(__dirname,
}
....
`$3
Add below dependency to your
app/build.gradle file with specified version (in our example we are using 1.4.0).`java
implementation 'com.google.android.material:material:'
`Set appropriate style in your styles.xml file.
`xml
`Set your configuration
Import the function from the library.
`ts
import { setConfig } from 'tf-checkout-react-native'
`Use it in your initial useEffect function, please keep in mind this is an
async function. It is highly recommended that you track when setConfig is finished, and pass that control prop to the Tickets component.`tsconst YourComponent: FC () => {
const [isCheckingCurrentSession, setIsCheckingCurrentSession] = useState(true)
useEffect(() => {
const initConfig = async () => {
setIsCheckingCurrentSession(true)
await setConfig({
EVENT_ID: '4344',
CLIENT: 'ttf',
ENV: 'STAG',
CLIENT_ID: '3emd9023349dfn',
CLIENT_SECRET: 'CCEw33o4030e4df',
AUTH: {
ACCESS_TOKEN: 'token393939',
REFRESH_TOKEN: 'dee2030edmd',
TOKEN_TYPE: 'bearer',
SCOPE: 'scope',
}
})
setIsCheckingCurrentSession(false)
}
initConfig()
}, [])
return isCheckingCurrentSession
/>
}
`setConfig set your event's configuration, with the following options:`ts
{
EVENT_ID?: string | number,
CLIENT?: string,
ENV?: 'PROD' | 'DEV' | 'STAG',
CLIENT_ID?: string,
CLIENT_SECRET?: string,
TIMEOUT?: number,
BRAND?: string,
ARE_SUB_BRANDS_INCLUDED?: boolean
AUTH?: {
ACCESS_TOKEN: string
REFRESH_TOKEN: string
TOKEN_TYPE: string
SCOPE: string
}
}
`$3
| Property | Description |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| EVENT_ID | Â Specify the event's ID. |
| CLIENT | Specify your client designated name example
ttf. |
| ENV | Sets the environment to any of the following environments: Production, Staging or Development. Receives the following values: PROD, DEV, STAG. Defaults to PROD. |
| CLIENT_ID | Set your CLIENT_ID. |
| CLIENT_SECRET | Set your CLIENT_SECRET. |
| BRAND | Set your BRAND so users can only see this brand in their orders. |
| TIMEOUT | Set custom timeout for the APIs requests. |
| ARE_SUB_BRANDS_INCLUDED | If true will include orders from the BRAND sub-brands. Default false. |
| AUTH | Object that receives data for Single Sign On (SSO). |Run the example app
1. Clone this repo.
2. In the App.tsx file, update the
EVENT_ID const with the assigned ID to be able to retrieve data from the server.
3. cd into the _root project_ folder and yarn or npm install.
4. cd into the _example_ folder and yarn or npm install.
- If running on iOS, cd into ios folder and pod install && cd ...
5. Run yarn ios or npm run ios to initialize and run in the iPhone simulator.
6. If running on Android, run yarn android or npm run android to run it in the Android emulator or connected physical device.Features
This library exports the following components:
$3
Used to authenticate the user and request password restore.
$3
Will retrieve and show a list of tickets corresponding to
eventId. It also includes a PromoCode component that validates it and updates the tickets list.User can select what ticket type wants to buy and the quantity of tickets.
$3
User will need to enter its data into a form to create a Ticket Fairy account. Also, depending on the number of tickets selected, will need to fill the information of each one of them.
$3
Will show the order details and a card form that the user will need to fill with its card details.
TicketFairy doesn't store any card related data, we use Stripe as payments solution.
$3
This is shown once the payment is successfully completed, could show components to share the purchase in social media or refer it with friends to get discounts on the purchase.
$3
Will show the purchased orders for the logged user.
$3
Will show the details for the selected Order, it also allows the user to download the Ticket PDF.
$3
Let the user to resale their tickets. They can choose between selling them to a friend or to any other user.
$3
After opening and URL with the corresponding schema, use this component to let the user reset its password.
$3
- setConfig: Sets config for the library
- refreshAccessToken: Let refresh the expired access token.
React Hooks API
As of the latest version, we're introducing a new hooks-based API that provides a more modern and flexible approach to implementing the checkout flow. The hooks-based implementation replaces the Core components (
BillingCore and CheckoutCore) which are now deprecated.Available Hooks
$3
Wrapping with CheckoutProvider
All checkout components & hooks (CheckoutV2, CustomCheckout, or your own flow) must be wrapped in CheckoutProvider to work correctly.
| Hook | Description |
| ---------------------- | ---------------------------------------------------------------------------------- |
|
useCheckoutFlow() | Complete checkout flow with form management, data fetching, and payment processing |
| useCart() | Fetch cart data with automatic expiration countdown |
| useCheckout() | Process checkout with payment information |
| useAddToCart() | Add items to cart |
| useTickets() | Fetch available tickets for an event |
| useEventInfo() | Fetch event information |
| usePaymentData() | Get payment data for an order |
| usePaymentSuccess() | Process payment success |
| useEventConditions() | Fetch event conditions |
| useAddons() | Fetch and manage event add-ons |
| useUpdateCheckout() | Update checkout with add-ons |$3
| Hook | Description |
| ---------------------- | ----------------------------------- |
|
useCountries() | Fetch countries list |
| useStates(countryId) | Fetch states for a specific country |$3
| Hook | Description |
| ------------------- | -------------------------------- |
|
useUserProfile() | Fetch authenticated user profile |
| useRegisterUser() | Register a new user |Migration from Core Components
If you're currently using
BillingCore or CheckoutCore components, please refer to the Migration Guide for detailed instructions on how to update your code to use the new hooks-based API.Example Usage
`tsx
import { useCheckoutFlow, CheckoutForm, CheckoutProvider } from 'tf-checkout-react-native'const CheckoutScreen = () => {
const {
onSubmit,
initialValues,
countries,
states,
orderItems,
secondsLeft,
isSubmitting,
isInitialLoading
} = useCheckoutFlow({
onCartExpired: () => navigation.navigate('ExpiredScreen'),
onCheckoutSuccess: ({ hash, total, values }) => {
// Handle checkout success
},
onPaymentSuccess: (result) => {
// Handle payment success
}
})
if (isInitialLoading) {
return
}
return (
onSubmit={onSubmit}
initialValues={initialValues}
countries={countries}
states={states}
orderItems={orderItems}
secondsLeft={secondsLeft}
isSubmitting={isSubmitting}
/>
)
}
export default MyCustomCheckout() => {
return (
)
}
`Component styling
$3
`ts
interface IButtonStyles {
container?: StyleProp
button?: StyleProp
text?: StyleProp
}
`$3
`ts
interface IInputStyles {
color?: ColorValue
container?: StyleProp
input?: StyleProp
lineWidth?: number
activeLineWidth?: number
baseColor?: ColorValue
errorColor?: ColorValue
}
`$3
`ts
interface ICheckboxStyles {
container?: StyleProp
content?: StyleProp
indicator?: StyleProp
indicatorDisabled?: StyleProp
text?: StyleProp
box?: StyleProp
icon?: StyleProp
}
`Exported functions
setConfig
Set the configuration for the library.
`ts
export interface IConfig {
EVENT_ID: string | number
CLIENT?: string
ENV?: EnvType
CLIENT_ID?: string
CLIENT_SECRET?: string
TIMEOUT?: number
BRAND?: string
ARE_SUB_BRANDS_INCLUDED?: boolean
// AUTH is used for single sign on v1.
// It receives the needed information for the authenticated user.
AUTH?: {
ACCESS_TOKEN: string
REFRESH_TOKEN: string
TOKEN_TYPE: string
SCOPE: string
}
}
`refreshAccessToken
Let refresh the expired access token, it can use the internal stored refresh token, passing nothing to it, or you can pass a
string refresh token.`ts
const response: IFetchAccessTokenResponse = await refreshAccessToken(refreshToken?: string)
`Returns the new access token data or error.
`ts
accessTokenError?: {
code?: number
message: string
}
accessTokenData?: {
accessToken: string
refreshToken: string
tokenType: string
scope: string
}
`Exported handlers
SessionCoreHandle
Exports function to refresh access token.
$3
Allows to refresh access token inside the component. It will automatically re-fetch the component's data from the server. You will need to create a
ref object with the corresponding type.Example:
In your parent component
`ts
const sessionHandleRef = useRef(null)// Call the refreshAccessToken function by using
await sessionHandleRef.current?.refreshAccessToken()
`Exported components
Depending on your needs, you can use the UI Components or the Core Components.
UI Components use the Core Components at their core but also exposes an UI that you can configure with your own styles. There is no need to create any kind of logic with them, only setConfig and implement the callbacks to get their data.
Core Components are wrappers that don't include any UI neither validation logics, they only act as a Middleware to retrieve and send data from the server and return it to your implementation components. They are useful when your design cannot be achieved by the UI components. You will need to use references to access their exposed functions.
UI Components
---
Session handle
In all components with the exception of Login and Reset Password, you can pass a
ref with type SessionHandleType to access two functions:refreshAccessToken After a successful access token refresh, it will re-fetch component's data from server when applicable.
reloadData It will re-fetch component's data from server.---
Login UI
Import the component from the library
`tsx
import { Login } from 'tf-checkout-react-native'
`Then add it to the render function.
`tsx
onLoginSuccessful: (
userProfile: IUserProfile,
accessTokenData?: IFetchAccessTokenData
) => void
onLoginError?: (error: IError) => void onFetchUserProfileError?: (error: IError) => void
onFetchUserProfileSuccess?: (data: any) => void
onFetchAccessTokenError?: (error: IError) => void
onFetchAccessTokenSuccess?: () => void
isLoginDialogVisible: boolean
showLoginDialog: () => void
hideLoginDialog: () => void
//Logout
onLogoutSuccess?: () => void
onLogoutError?: () => void
userFirstName={loggedUserName}
refs={{
inputs?: {
email?: any
password?: any
}
button?: {
containerView?: any
touchableOpacity?: any
loadingView?: any
activityIndicator?: any
loadingText?: any
}}
brandImages={
containerStyle?: StyleProp
image1?: ImageSourcePropType
image1Style?: StyleProp
image2?: ImageSourcePropType
image2Style?: StyleProp
}
styles?: ILoginViewStyles
texts?: ILoginViewTexts
isShowPasswordButtonVisible?: boolean
//Restore password
onRestorePasswordError?: (error: IError) => void
onRestorePasswordSuccess?: () => void
/>
`$3
#### IUserProfile
`ts
{
customerId: string
firstName: string
lastName: string
email: string
phone: string
streetAddress: string
zipCode: string
countryId: string
company?: string
state: string
stateId: string
city: string
}
`#### IFetchAccessTokenData
`ts
{
accessToken: string
refreshToken: string
tokenType: string
scope: string
}
`$3
| Property | Description |
| -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| onLoginSuccessful: (userProfile: IUserProfile, accessToken: string)
| When login was successful, return userProfile data and the access token to use if for future API requests. |userFirstName prop so the component will show the logged out view. |``js`
interface ILoginViewStyles {
guest?: {
loginButton?: IButtonStyles
linesContainer?: StyleProp
line1?: StyleProp
line2?: StyleProp
message?: StyleProp
}
dialog?: {
container?: StyleProp
loginButton?: IButtonStyles
loginButtonDisabled?: IButtonStyles
input?: IInputStyles
title?: StyleProp
message?: StyleProp
}
loggedIn?: {
container?: StyleProp
placeholder?: StyleProp
value?: StyleProp
button?: IButtonStyles
message?: StyleProp
}
restorePassword?: {
rootContainer?: StyleProp
restorePasswordButton?: {
container?: StyleProp
button?: StyleProp
text?: StyleProp
}
cancelRestorePasswordButton?: {
container?: StyleProp
button?: StyleProp
text?: StyleProp
}
input?: IInputStyles
title?: StyleProp
message?: StyleProp
apiError?: StyleProp
}
restorePasswordSuccess?: {
rootContainer?: StyleProp
title?: StyleProp
message?: StyleProp
button?: {
container?: StyleProp
button?: StyleProp
text?: StyleProp
}
}
}
\*Note: Logos images styles are passed from the brandImages prop.
`js`
{
loginButton?: string
logoutButton?: string
line1?: string
line2?: string
message?: string
dialog?: {
loginButton?: string
message?: string
title?: string
}
logoutDialog?: {
title?: string
message?: string
confirm?: string
cancel?: string
}
loggedIn?: {
loggedAs?: string
notYou?: string
}
restorePassword?: {
restorePasswordButton?: string
cancelButton?: string
message?: string
inputLabel?: string
title?: string
}
restorePasswordSuccess?: {
title?: string
message?: string
button?: string
}
}
---
This component will first fetch for the Event's data, if data is ok, then will fetch the tickets for this event.
If the Event's response returns a 401 error, then it means it's password protected and need to authenticate with a password. Then the EnterPassword component will be shown for the user to enter the password.
Import the component from the library.
`js`
import { Tickets } from 'tf-checkout-react-native'
Then add it to the render function.
`js
const sessionHandleRef = useRef
onAddToCartSuccess={handleOnAddToCartSuccess} />
`
`js
{
ref?: SessionHandleType
// Callbacks for when user taps on GET Tickets button
onAddToCartSuccess: (data: {
isBillingRequired: boolean
isPhoneRequired?: boolean
isAgeRequired?: boolean
minimumAge?: number
isNameRequired?: boolean
isTicketFree?: boolean
isPhoneHidden?: boolean
}) => void
onAddToCartError?: (error: {
code: number
message: string
extraData?: any
}) => void
// Callbacks for fetching the tickets
onFetchTicketsError?: (error: {
code: number
message: string
extraData?: any
}) => void
// Callbacks for fetching the Event base on the eventId prop
onFetchTicketsSuccess?: (data: {
tickets: ITicket[]
promoCodeResponse: {
success?: boolean
message?: string
}
isInWaitingList: boolean
isAccessCodeRequired: boolean
}) => void
onFetchEventError?: (error: {
code: number
message: string
extraData?: any
}) => void
// Callbacks for Waiting list
onAddToWaitingListSuccess?: (data: any) => void
onAddToWaitingListError?: (error: {
code: number
message: string
extraData?: any
}) => void
styles?: ITicketsViewStyles
texts?: ITicketsViewTexts
isPromoEnabled?: boolean
isAccessCodeEnabled?: boolean
onPressMyOrders: () => void
onPressLogout?: () => void
onLoadingChange?: (isLoading: boolean) => void
promoCodeCloseIcon?: ImageSourcePropType
// Event password protected
onPressSubmitEventPassword?: (password: string) => void
passwordProtectedEventData?: {
isPasswordProtected?: boolean
message?: string
apiError?: string
isLoading?: boolean
}
// Configure the Component behavior
config: {
areActivityIndicatorsEnabled?: boolean
areAlertsEnabled?: boolean
areTicketsSortedBySoldOut?: boolean
areTicketsGrouped?: boolean
}
// For SSO
isCheckingCurrentSession?: boolean
// Referral discounts
referrerId?: string
}
`
eventId is required in order to fetch the tickets from this event.onAddToCartSuccess is called after the Add to Cart was completed successfully, it will return the following data:
`js`
{
isBillingRequired: boolean
isPhoneRequired?: boolean
isAgeRequired?: boolean
minimumAge?: number
isNameRequired?: boolean
}
Configure the component's behavior
`ts`
config: {
// Whether or not show the loading indicators.
areActivityIndicatorsEnabled?: boolean
// Whether or not show the alerts.
areAlertsEnabled?: boolean
// Whether or not the Ticket should be sorted by Sold Out.
areTicketsSortedBySoldOut?: boolean
// Whether or not the tickets should be grouped, they need to be configured as groups in the Tickets admin.
areTicketsGrouped?: boolean
}
You can then call the BillingInfo component and pass them as props in the cartProps prop.
onFetchTicketsSuccess When tickets fetching was successful, will return fetched data, including promoCodeResponse.
`js
{
rootContainer?: ViewStyle
container?: ViewStyle
title?: TextStyle
getTicketsButtonDisabled?: IButtonStyles
getTicketsButtonActive?: IButtonStyles
promoCode?: {
rootContainer?: ViewStyle
contentWrapper?: ViewStyle
content?: StyleProp
input?: TextInputProps['style']
inputPlaceholderColor?: string
mainButton?: IButtonStyles
applyButton?: IButtonStyles
applyDisabledButton?: IButtonStyles
errorMessage?: StyleProp
validMessage?: StyleProp
cancelButton?: StyleProp
cancelIcon?: StyleProp
}
ticketList?: {
sectionHeader?: {
container?: StyleProp
title?: StyleProp
}
listContainer?: ViewStyle
item?: {
container?: ViewStyle
ticketName?: TextStyle
price?: TextStyle
oldPrice?: TextStyle
fees?: TextStyle
soldOutText?: TextStyle
soldOutContainer?: ViewStyle
dropdown?: IDropdownStyles
pricesContainer?: StyleProp
}
}
loading?: {
animation?: {
color?: ActivityIndicatorProps['color']
size?: ActivityIndicatorProps['size']
}
content?: ViewStyle
text?: TextStyle
}
waitingList?: {
rootContainer?: StyleProp
title?: StyleProp
button?: IButtonStyles
input?: IInputStyles
buttonDisabled?: IButtonStyles
success?: {
container?: StyleProp
title?: StyleProp
message?: StyleProp
}
}
loggedIn?: {
rootContainer?: StyleProp
myOrdersButton?: IButtonStyles
logOutButton?: IButtonStyles
}
enterPassword?: {
input?: IInputStyles
title?: StyleProp
error?: StyleProp
button?: IButtonStyles
rootContainer?: StyleProp
contentContainer?: StyleProp
}
}
`
`js`
{
promoCode?: {
promoCodeButton?: string
inputPlaceHolder?: string
apply?: string
cancel?: string
mainButton?: string
title?: string
}
getTicketsButton?: string
title?: string
waitingList?: {
title?: string
firstName?: string
lastName?: string
email?: string
button?: string
successTitle?: string
successMessage?: string
}
loggedInTexts?: {
logoutDialog?: {
title?: string
message?: string
confirmButton?: string
cancelButton?: string
}
myOrderButtonText?: string
logOutButtonText?: string
}
listItem?: {
soldOut?: string
salesNotStarted?: string
salesEnded?: string
inclFees?: string
exclFees?: string
free?: string
ticket?: string
}
enterPassword?: {
inputLabel?: string
title?: string
buttonText?: string
}
}
---
Import the component from the library
`js`
import { BillingInfo } from 'tf-checkout-react-native'
Add it to the render function.
`js
const sessionHandleRef = useRef
cartProps: {
isBillingRequired: boolean
isNameRequired: boolean
isAgeRequired: boolean
isPhoneRequired: boolean
minimumAge: number
}
// registerNewUser
onRegisterSuccess?: (data: {
accessTokenData: {
accessToken: string
refreshToken: string
tokenType: string
scope: string
}
userProfile: {
firstName: string
lastName: string
email: string
}
}) => void
onRegisterError?: (error: {
isAlreadyRegistered?: boolean
message?: string
raw?: any
}) => void
onCheckoutSuccess: (data: {
id: string
hash: string
total: string
status: string
}) => void
onCheckoutError?: (error: IError) => void
// See ILoginSuccessData data type below.
onLoginSuccess: (data: ILoginSuccessData) => void
onLoginError?: (error: IError) => void
onFetchUserProfileSuccess?: (data: any) => void
onFetchUserProfileError?: (error: IError) => void
//fetchCart
onFetchCartError?: (error: IError) => void
onFetchCartSuccess?: () => void
// fetchCountries
onFetchCountriesError?: (error: IError) => void
onFetchCountriesSuccess?: (data: {
code: string
id: string
name: string
}[]) => void
// fetchState
onFetchStatesError?: (error: IError) => void
onFetchStatesSuccess?: () => void
// fetch Token
onFetchAccessTokenError?: (error: IError) => void
onFetchAccessTokenSuccess?: () => void
styles?: IBillingInfoViewStyles
texts?: IBillingInfoViewTexts
styles?: IBillingInfoViewStyles
texts?: IBillingInfoViewTexts
// Configure the skipping component visible, when isBillingRequired is false
skipBillingConfig?: {
styles?: {
rootContainer?: StyleProp
dialogContainer?: StyleProp
brandImage?: StyleProp
text?: StyleProp
activityIndicator?: {
color?: ColorValue
size?: 'large' | 'small'
}
}
brandImage?: ImageSourcePropType
isActivityIndicatorVisible?: boolean
}
loginBrandImages?: {
containerStyle?: StyleProp
image1?: ImageSourcePropType
image1Style?: StyleProp
image2?: ImageSourcePropType
image2Style?: StyleProp
}
config?: {
isCheckoutAlwaysButtonEnabled?: boolean
shouldHideTicketHolderSectionOnSingleTicket?: boolean
}
/>
`
ILoginSuccessData
`ts`
interface ILoginSuccessData {
userProfile: {
customerId: string
firstName: string
lastName: string
email: string
phone: string
streetAddress: string
zipCode: string
countryId: string
company?: string
state: string
stateId: string
city: string
}
accessTokenData?: {
accessToken: string
refreshToken: string
tokenType: string
scope: string
}
}
| Property | Description |
| ----------------- | ----------------------------------------------------------------------------------- |
| cartProps | Received from the Tickets component |
| onCheckoutSuccess | Will return Order data from the Checkout action |
| loginBrandImages | Â Receives styles and images sources to show in the Login component |isBillingRequired
| skipBillingConfig | Configure the skipping component, visible when is set to false |
`js`
interface IBillingInfoViewTexts {
loginTexts?: ILoginViewTexts
checkoutButton?: string
skippingMessage?: string
invalidPhoneNumberError?: string
form?: {
firstName?: string
lastName?: string
email?: string
confirmEmail?: string
password?: string
confirmPassword?: string
phone?: string
street?: string
city?: string
country?: string
state?: string
zipCode?: string
dateOfBirth?: string
isSubToBrand?: string // your brand's checkbox label
ticketHoldersTitle?: string
ticketHolderItem?: string
holderFirstName?: string
holderLastName?: string
holderEmail?: string
holderPhone?: string
getYourTicketsTitle?: string
emailsAdvice?: string
choosePassword?: string
optional?: string
phoneInput?: {
label?: string
customError?: string
}
ttfPrivacyPolicyRequiredError?: string
}
cartTimer?: {
message?: string
}
}
`js
interface IBillingInfoViewStyles {
rootContainer?: StyleProp
loginStyles?: ILoginViewStyles
checkoutButton?: IButtonStyles
checkoutButtonDisabled?: IButtonStyles
passwordTitle?: StyleProp
inputStyles?: IInputStyles
dropdownStyles?: IDropdownStyles
dropdownMaterialStyles?: {
container?: StyleProp
button?: StyleProp
icon?: StyleProp
label?: StyleProp
dialog?: StyleProp
flatListContainer?: StyleProp
listItem?: {
container?: StyleProp
button?: StyleProp
buttonSelected?: StyleProp
text?: StyleProp
textSelected?: StyleProp
}
input?: IInputStyles
}
checkboxStyles?: {
container?: StyleProp
content?: StyleProp
indicator?: StyleProp
indicatorDisabled?: StyleProp
text?: StyleProp
box?: StyleProp
icon?: StyleProp
error?: StyleProp
}
screenTitle?: StyleProp
ticketHoldersTitle?: StyleProp
ticketHolderItemHeader?: StyleProp
texts?: StyleProp
customCheckbox?: ICheckboxStyles
datePicker?: IDatePickerStyles
privacyPolicyLinkStyle?: StyleProp
phoneInputStyles?: {
rootContainer?: StyleProp
errorColor?: ColorValue
country?: {
container?: StyleProp
button?: StyleProp
}
input?: IInputStyles
}
cartTimer?: {
rootContainer?: StyleProp
contentContainer?: StyleProp
textsContainer?: StyleProp
icon?: StyleProp
message?: StyleProp
time?: StyleProp
}
privacyPolicyLinkStyle?: StyleProp
}
`
---
Import the component from the library
`js`
import { Checkout } from 'tf-checkout-react-native'
Add it to the render function.
`js
const sessionHandleRef = useRef
hash={hash}
total={total}
onPaymentSuccess={handleOnPaymentSuccess}
onPressExit={handleStripeError}
areLoadingIndicatorsEnabled={false}
styles={styles}
{...props}
/>
`
`js
{
ref?: SessionHandleType
hash: string
total: string
onFetchOrderReviewError?: (error: IError) => void
onFetchOrderReviewSuccess?: (data: any) => void
onFetchEventConditionsError?: (error: IError) => void
onFetchEventConditionsSuccess?: (data: any) => void
onCheckoutCompletedSuccess?: (data: any) => void
onCheckoutCompletedError?: (error: IError) => void
onPaymentSuccess: (data: any) => void
onPaymentError?: (error: IError) => void
onStripeInitializeError?: (error: string) => void
onPressExit: () => void
texts?: {
title?: string
subTitle?: string
missingStripeConfigMessage?: string
exitButton?: string
payButton?: string
freeRegistrationButton?: string
providePaymentInfo?: string
orderReviewItems?: {
event?: string
ticketType?: string
numberOfTickets?: string
price?: string
total?: string
}
cartTimer?: {
message?: string
}
}
styles?: ICheckoutStyles
onLoadingChange?: (isLoading: boolean) => void
onSkippingStatusChange?: (status: | 'skipping'
| 'fail'
| 'success'
| 'false'
| undefined) => void
areAlertsEnabled?: boolean
areLoadingIndicatorsEnabled?: boolean
}
`
| Property | Description |
| --------------------------- | ------------------------------------------------------------------------------- |
| hash | retrieved from the onCheckoutSuccess callback in the BillingInfocomponent. |onCheckoutSuccess
| total | retrieved from the callback in the BillingInfo component. |hash
| onPaymentSuccess | will handle the success in the payment process. Will return the . |default: true
| areLoadingIndicatorsEnabled | whether or not show the Loading Indicator, . |default: true
| areAlertsEnabled | whether or not show the Error Alerts, . |
_Note: If the you need to modify the card container, use the styles.payment.cardContainer prop. Useful if the card is to short and the zip code is not visible._
`ts`
{
rootStyle?: ViewStyle
title?: StyleProp
subTitle?: StyleProp
missingStripeConfig?: {
container?: StyleProp
message?: StyleProp
exitButton?: IButtonStyles
}
freeRegistrationButton?: IButtonStyles
orderReview?: IOrderReviewStyles
payment?: {
container?: StyleProp
title?: StyleProp
cardBackgroundColor?: string
cardContainer?: StyleProp
button?: IButtonStyles
buttonDisabled?: IButtonStyles
}
cartTimer?: {
rootContainer?: StyleProp
contentContainer?: StyleProp
textsContainer?: StyleProp
icon?: StyleProp
message?: StyleProp
time?: StyleProp
}
}
Currently, Stripe card is not customizable. Please see the open issues in their Github.
Additionally, if you are encountering problems with building your project, please take a look at the Stripe troubleshooting.
Import the component from the library
`js`
import { PurchaseConfirmation, SessionHandleType } from 'tf-checkout-react-native'
Add it to the render function.
`ts
const sessionHandleRef = useRef
orderHash={checkoutProps!.hash}
onComplete={handleOnComplete}
styles?: {
rootContainer?: StyleProp
title?: StyleProp
message?: {
container?: StyleProp
line1?: StyleProp
line2?: StyleProp
}
exitButton?: {
container?: StyleProp
button?: StyleProp
text?: StyleProp
}
}
texts?: {
title?: string
message?: {
line1?: string
line2?: string
}
exitButton?: string
}
/>
`
| Property | Description |
| ---------- | -------------------------------------------------------------------------------------------------------------------- |
| orderHash | The hash returned in the BillingInfo component |
| onComplete | To handle the completion of the flow. Here you can handle the unmount of the component or navigate to another screen |
| styles | Styles for the component |
| texts | Texts for the component |
---
If there is a valid session, there will appear a button to access MyOrders in the Tickets component.
Import the component from the library.
`js`
import { MyOrders, SessionHandleType } from 'tf-checkout-react-native'
`ts
{
ref={SessionHandleType}
onSelectOrder: (order: {
order: {
header: {
currency: string
date: string
eventEndDate: string
eventId: string
eventName: string
eventSalesEndDate: string
eventSalesStartDate: string
eventStartDate: string
eventUrl: string
hideVenueUntil: string | null
id: string
image: string
isReferralDisabled: boolean
isVenueHidden: boolean
salesReferred: string
shareLink: string
timeZone: string
total: string
venue: {
city: string
country: string
googlePlaceId?: string
latitude?: string
longitude?: string
name?: string
postalCode?: string
state: string
street?: string
streetNumber?: string
}
},
items: [
{
name: string
currency: string
price: string
discount: string
quantity: string
total: string
},
{...}
],
tickets: [
{
hash: string
ticketType: string
holderName?: string
holderEmail?: string
holderPhone?: string
status: string
pdfLink?: string
qrData?: string
isSellable?: boolean
description?: string
descriptionPlain?: string
},
{...}
]
}
}) => void
onFetchMyOrdersSuccess?: (data: IMyOrdersData) => void
onFetchMyOrdersError?: (error: IError) => void
onFetchOrderDetailsSuccess?: (data: IMyOrderDetailsData) => void
onFetchOrderDetailsError?: (error: IError) => void
onLoadingChange?: (isLoading: boolean) => void
styles?: {
orderListItem?: IOrderListItemStyles
safeArea?: StyleProp
listContainer?: StyleProp
eventsContainer?: StyleProp
eventsTitle?: StyleProp
refreshControlColor?: ColorValue
eventsDropdown?: IDropdownStyles
rootContainer?: StyleProp
eventsSelectionContainer?: StyleProp
clearEventSelectionIcon?: StyleProp
timeFilters?: {
container?: StyleProp
dropdown?: IDropdownStyles
selectionContainer?: StyleProp
clearSelectionIcon?: StyleProp
}
}
config?: {
isEventsDropdownHidden?: boolean
areActivityIndicatorsEnabled?: boolean
areAlertsEnabled?: boolean
isTimeFilterDropdownHidden?: boolean
}
texts?: {
selectEventPlaceholder?: string
selectTimeFilterPlaceholder?: string
title?: string
timeFilters?: {
upcoming?: string
ongoingAndUpcoming?: string
ongoing?: string
past?: string
}
}
}
`
IMyOrdersData
`ts`
{
events: {
event_name: string
url_name: string
}[]
orders: {
amount: string
currency: string
date: string
eventEndDate: string
eventId: string
eventName: string
eventSalesEndDate: string
eventSalesStartDate: string | null
eventStartDate: string
eventUrl: string
hideVenue: boolean
hideVenueUntil: string | null
id: string
image: string
timezone: string
venueCity: string
venueCountry: string
venueGooglePlaceId?: string
venueLatitude?: string
venueLongitude?: string
venueName?: string
venuePostalCode?: string
venueState: string
venueStreet?: string
venueStreetNumber?: string
}[]
//Those mark with ? are only included if the venue is not hidden
filter?: string
brandFilter?: string
subBrands?: boolean
pagination: {
page: number
limit: number
totalCount: number
totalPages: number
}
}
IMyOrderDetailsData
`ts`
{
header: {
currency: string
date: string
eventEndDate: string
eventId: string
eventName: string
eventSalesEndDate: string
eventSalesStartDate: string
eventStartDate: string
eventUrl: string
hideVenueUntil: string | null
id: string
image: string
isReferralDisabled: boolean
isVenueHidden: boolean
salesReferred: string
shareLink: string
timeZone: string
total: string
venue: {
city: string
country: string
googlePlaceId?: string
latitude?: string
longitude?: string
name?: string
postalCode?: string
state: string
street?: string
streetNumber?: string
}
//Those mark with ? are only included if the venue is not hidden
}
items?: {
currency: string
discount: string
hash: string
isActive: boolean
name: string
price: string
quantity: string
total: string
}[]
tickets: {
currency: string
description: string
descriptionPlain?: string
eventName: string
hash: string
holderEmail?: string
holderName: string
holderPhone?: string
isOnSale: boolean
isSellable: boolean
isTable: boolean
pdfLink: string
qrData: string
resaleFeeAmount: number
status: string
ticketType: string
ticketTypeHash: string
}[]
}
`js
{
orderListItem?: {
rootContainer?: StyleProp
contentContainer?: StyleProp
infoContainer?: StyleProp
infoTopContainer?: StyleProp
infoBottomContainer?: StyleProp
imageContainer?: StyleProp
image?: StyleProp
infoRootContainer?: StyleProp
iconNextContainer?: StyleProp
iconNext?: StyleProp
orderId?: StyleProp
orderDate?: StyleProp
eventName?: StyleProp
priceContainer?: StyleProp
price?: StyleProp
currency?: StyleProp
}
safeArea?: StyleProp
listContainer?: StyleProp
eventsContainer?: StyleProp
eventsTitle?: StyleProp
refreshControlColor?: ColorValue
eventsDropdown?: {
container?: StyleProp
button?: StyleProp
icon?: StyleProp
label?: StyleProp
dialog?: StyleProp
flatListContainer?: StyleProp
listItem?: {
container?: StyleProp
button?: StyleProp
buttonSelected?: StyleProp
text?: StyleProp
textSelected?: StyleProp
}
}
rootContainer?: StyleProp
eventsSelectionContainer?: StyleProp
clearEventSelectionIcon?: StyleProp
}
`
---
When user selects an order from the MyOrders component, will show it details.
Import the component from the library.
`js`
import { MyOrderDetails, SessionHandleType } from 'tf-checkout-react-native'
`tsx
{
ref={SessionHandleType}
data: IMyOrderDetailsData
// Used to navigate to the Resale Tickets screen
onPressResaleTicket: (
ticket: IMyOrderDetailsTicket,
isTicketTypeActive: boolean
) => void
onRemoveTicketFromResaleSuccess: (message: string) => void
onRemoveTicketFromResaleError?: (error: IError) => void
config?: {
areActivityIndicatorsEnabled?: boolean
areAlertsEnabled?: boolean
}
onDownloadStatusChange?: (status?:
'downloading' |
'downloaded' |
'failed'
) => void
downloadStatusIcons?: {
success?: ImageSourcePropType
error?: ImageSourcePropType
}
onAndroidWritePermission?: (permission?: boolean) => void
onLinkCopied?: (copied?: boolean) => void
moreButtonIcon?: StyleProp
ticketActionsIcons?: {
downloadPdf?: ImageSourcePropType
sell?: ImageSourcePropType
removeFromSale?: ImageSourcePropType
refund?: ImageSourcePropType
}
styles?: {
rootContainer?: StyleProp
header?: {
container?: StyleProp
title?: StyleProp
subTitle?: StyleProp
shareLink?: {
container?: StyleProp
text?: StyleProp
link?: StyleProp
copyContainer?: StyleProp
copyText?: StyleProp
copyIcon?: StyleProp
copyIconTint?: ColorValue
copyIconTintActive?: ColorValue
message?: StyleProp
referrals?: StyleProp
referralValue?: StyleProp
}
}
section0Footer?: {
container?: StyleProp
label?: StyleProp
value?: StyleProp
}
sectionHeader?: StyleProp
listItem?: {
container?: StyleProp
innerLeftContainer?: StyleProp
innerRightContainer?: StyleProp
rowPlaceholder?: StyleProp
rowValue?: StyleProp
}
ticketItem?: {
rootContainer?: StyleProp
leftContent?: StyleProp
rightContent?: StyleProp
rowPlaceholder?: StyleProp
rowValue?: StyleProp
downloadButton?: IButtonStyles
moreButton?: StyleProp
moreButtonIcon?: StyleProp
}
downloadButton?: {
container?: StyleProp
button?: StyleProp
text?: StyleProp
}
bottomSheetModal?: {
rootContainer?: StyleProp
headerContainer?: StyleProp
content?: StyleProp
title?: StyleProp
closeButton?: StyleProp
closeButtonIcon?: StyleProp
contentContainer?: StyleProp
}
ticketActions?: {
rootScrollViewContainer?: StyleProp
buttonContainer?: StyleProp
buttonContent?: StyleProp
icon?: StyleProp
text?: StyleProp
}
texts?: {
title?: string
subTitle?: string
referralLink?: string
referral?: {
soFar?: string
tickets?: string
}
listItem?: {
title?: string
ticketType?: string
price?: string
quantity?: string
total?: string
}
ticketItem?: {
ticketType: string
holderName: string
ticketId: string
status: string
download: string
sellTicket: string
removeTicketFromResale: string
}
downloadNotification?: {
successMessage?: string
errorMessage?: string
}
copyText?: {
copy?: string
copied?: string
}
sellTicket?: string
removeTicketFromResale?: string
ticketsTitle?: string
bottomSheetModal?: {
title?: string
}
ticketActions?: {
downloadPdf?: string
sell?: string
removeFromSale?: string
refund?: string
}
}
}
`
Allows the user to resale the tickets they bought. They can decide wether sell it to a friend or to any other user.
Import the component from the library.
`js`
import { ResaleTickets, SessionHandleType } from 'tf-checkout-react-native'
`ts`
{
ref={SessionHandleType}
ticket: {
currency: string
description: string
descriptionPlain?: string
eventName: string
hash: string
holderEmail?: string
holderName: string
holderPhone?: string
isOnSale: boolean
isSellable: boolean
pdfLink: string
qrData: string
resaleFeeAmount: number
status: string
ticketType: string
}
styles?: {
rootContainer?: StyleProp
title?: StyleProp
terms?: IResaleTermsStyles
resaleTicketsButton?: IButtonStyles
resaleTicketsButtonDisabled?: IButtonStyles
resaleTicketsButtonLoading?: IButtonStyles
ticketOrderDetails?: ITicketOrderDetailsStyles
ticketBuyerForm?: ITicketBuyerFormStyles
termsCheckbox?: ICheckboxStyles
}
onResaleTicketsSuccess: (
resaleTicketData: {
message: string
},
ticket: {
currency: string
description: string
descriptionPlain?: string
eventName: string
hash: string
holderEmail?: string
holderName: string
holderPhone?: string
isOnSale: boolean
isSellable: boolean
pdfLink: string
qrData: string
resaleFeeAmount: number
status: string
ticketType: string
}
) => void
onResaleTicketsError?: (error: {
code?: number
message: string
extraData?: any
}) => void
config?: {
areAlertsEnabled?: boolean
areActivityIndicatorsEnabled?: boolean
}
texts?: {
title?: string
orderDetails?: {
title?: string
eventName?: string
orderedBy?: string
orderId?: string
}
sellToWhom?: {
title?: string
friend?: string
anyone?: string
}
friendForm?: {
firstName?: string
lastName?: string
email?: string
emailConfirm?: string
}
terms?: {
title?: string
paragraph1?: string
paragraph2_1?: string
paragraph2_2?: string
paragraph3_1?: string
paragraph3_2?: string
}
agree?: string
resaleTicketsButton?: string
}
}
After opening and URL with the corresponding schema and token, use this component to let the user reset its password.
Import the component from the library.
`ts`
import { ResetPassword } from 'tf-checkout-react-native'
Then add it to the render function.
`xml`
token={resetToken}
onPressResetButton={handleOnPressResetButton}
onPressCancelButton={handleOnPressCancelButton}
onResetPasswordSuccess={handleOnResetPasswordSuccess}
onResetPasswordError={handleOnResetPasswordError}
/>
`ts`
{
token: string
styles?: {
rootContainer?: StyleProp
contentContainer?: StyleProp
title?: StyleProp
resetButton?: IButtonStyles
cancelButton?: IButtonStyles
input?: IInputStyles
apiError?: StyleProp
apiSuccess?: StyleProp
}
texts?: {
title?: string
resetButton?: string
cancelButton?: string
newPasswordLabel?: string
confirmNewPasswordLabel?: string
}
onResetPasswordSuccess?: (data: {
message: string
status?: number
}) => void
onResetPasswordError?: (error: {
code?: number
message: string
extraData?: any
}) => void
onPressResetButton?: () => void
onPressCancelButton?: () => void
}
**⚠️ Remember that you first need to set your configuration using the setConfig
function. ⚠️**
---
All Core components with the exception of Login and ResetPassword exposes the refreshAccessToken function to re-authenticate the user after the access token is expired. This is through the corresponding CoreHandle ref.
It returns the IFetchAccessTokenResponse object:
`ts`
IFetchAccessTokenResponse {
accessTokenError?: {
code?: number
message: string
extraData?: any
}
accessTokenData?: {
accessToken: string
refreshToken: string
tokenType: string
scope: string
}
}
Import the component from the library
`js`
import {
TicketsCore
TicketsCoreHandle // You can import the Handle to use it as type in the useRef hook
} from 'tf-checkout-react-native'
Declare a reference to pass it to the component.
`js`
const ticketsCoreRef = useRef < TicketsCoreHandle > null
Then add it to the render function and assign the reference to the corresponding component.
`js`
Use the reference to access the component methods.
`js`
const handleGetTickets = async () => {
const res = await ticketsCoreRef.current.refreshAccessToken()
}
---
This is the initial component to show. It will retrieve the tickets, event, present My Orders and Logout buttons if the user is logged in, and will add the selected tickets to the cart.
Exposes the following functions:
getTickets Fetches the tickets from the event set in the config function. It receives a promoCode and referrerId parameters to apply to the tickets. PromoCode is higher priority than referrerId
getEvent Fetches the event from the eventId set in the config function.
addToCart Adds the selected tickets to the cart.
postReferralVisit Posts a referral visit to the server.
refreshAccessToken : Refreshes expired access token.
getAccountTickets: Fetches the tickets purchased for the user that logged in.
``js
{
// Fetches the tickets from the event set in the config function. It receives a promoCode parameter to apply to the tickets.
getTickets({ promoCode?: string, referredId?: string }): Promise<{
tickets?: {
sortOrder: number
displayTicket?: boolean
salesEnded: boolean
salesStarted: boolean
id: string
displayName: string
optionName: string
optionValue: string
isTable: string
feeIncluded: boolean
price: number
basePrice: number
chosen: number
priceCurrency: string
priceSymbol: string
taxesIncluded: boolean
taxName: string
minQuantity: number
maxQuantity: number
multiplier: number
tags: []
allowMultiplePurchases: number
priceReplacementText: string
waitingListEnabled: boolean
soldOut?: boolean
soldOutMessage: string
minGuests?: number
maxGuests?: number
buyButtonText?: string
totalStock: number
guestPrice?: number
alwaysAvailable: string
feeText: string
x_face_value: number
sold_out?: boolean
oldPrice?: number
oldBasePrice?: number
descriptionRich?: string
}[]
error?: {
code?: number
message: string
extraData?: any
}
promoCodeResult?: {
isValid: boolean | number
message: string
}
isInWaitingList?: boolean
isAccessCodeRequired?: boolean
}>
// Fetches the event from the eventId set in the config function.
getEvent(): Promise<{
eventError?: {
code?: number
message: string
extraData?: any
}
eventData?: {
affirmAllowed: boolean
alwaysShowWaitingList?: any
backgroundImage: string
backgroundVideo?: string
brandCheckoutPixels?: string
brandConversionPixels?: string
brandGoogleAnalyticsKey?: string
brandPagePixels?: string
checkoutPixels?: string
conversionPixels?: string
country: string
currency: {
currency: string
decimal_places: number
symbol: string
}
date: string
description?: string
descriptions: any
enableWaitingList: boolean
endDate: string
eventType: any
facebookEvent?: string
faq: []
feeMode: string
feesIncluded?: any
formattedDate: string
fullTitleReplacement?: any
hideTopInfluencers: boolean
hideVenue?: boolean
hideVenueUntil?: string
imageUrl: string
imageUrlHd: string
imageURLs: any
isTimeSlotEvent: boolean
l10nLanguages: []
minimumAge?: any
name: string
ogImage?: string
pagePixels?: string
passwordAuthenticated: boolean
passwordProtected: boolean
preregEnabled: boolean
preregistered: []
presalesEnded: boolean
presalesStarted: boolean
productImage: string
redirectUrl?: string
referrals: []
referralsEnabled: boolean
relatedProducts: []
salesEnd: string
salesEnded: boolean
salesStart?: string
salesStarted: boolean
slug: string
startDate: string
subHeading?: any
tableMapEnabled: boolean
tags: []
ticketsSold: number
timezone: string
title: string
titleReplacementHeight?: any
titleReplacementImage?: any
titleReplacementImageSvg?: any
twitterImage?: string
venueCity?: string
venueCountry: string
venueGooglePlaceId?: string
venueLatitude?: string
venueLongitude?: string
venueName?: string
venuePostalCode?: string
venueState?: string
venueStreet?: string
venueStreetNumber?: string
waitingListMaxQuanti