1.0.37 • Published 4 months ago

tf-checkout-react-native v1.0.37

Weekly downloads
-
License
MIT
Repository
-
Last release
4 months ago

tf-checkout-react-native

React 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.

Requirements

Configure ReactNative environment for desired platforms (iOS, Android or both).

React Native

  • Suggested ReactNative version 0.66.3
  • Suggested Flipper version 0.99.0
  • React version 0.17.1
  • Node version 16.10.0

Android

  • 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.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

iOS

  • Compatible with apps targeting iOS 13.0 or above.
  • Pods version 1.10.1
  • Command Line Tools version 13.0

To download the PDFs, add the following flags to Info.plist file:

- UIFileSharingEnabled: Application supports iTunes file sharing
- LSSupportsOpeningDocumentsInPlace: Supports opening documents in place

Installation

yarn add tf-checkout-react-native

or

npm install tf-checkout-react-native

Make sure to install all the required dependencies in your project.

Metro

Add the following to your metro.config.js in the resolver property:

sourceExts: ['jsx', 'js', 'ts', 'tsx']

Result:

module.exports = {
  watchFolders: [moduleRoot],
  resolver: {
    sourceExts: ['jsx', 'js', 'ts', 'tsx'],
    extraNodeModules: {
      react: path.resolve(__dirname,
    }
    .... 

Required for Android

Add below dependency to your app/build.gradle file with specified version (in our example we are using 1.4.0).

implementation 'com.google.android.material:material:<version>'

Set appropriate style in your styles.xml file.

<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
  <!-- ... -->
</style>

Set your configuration

Import the function from the library.

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.

const 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 <Tickets 
    isCheckingCurrentSession 
  />
}

setConfig set your event's configuration, with the following options:

{
  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
  }
}

Props

PropertyDescription
EVENT_ID Specify the event's ID.
CLIENTSpecify your client designated name example ttf.
ENVSets the environment to any of the following environments: Production, Staging or Development. Receives the following values: PROD, DEV, STAG. Defaults to PROD.
CLIENT_IDSet your CLIENT_ID.
CLIENT_SECRETSet your CLIENT_SECRET.
BRANDSet your BRAND so users can only see this brand in their orders.
TIMEOUTSet custom timeout for the APIs requests.
ARE_SUB_BRANDS_INCLUDEDIf true will include orders from the BRAND sub-brands. Default false.
AUTHObject 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:

Login

Used to authenticate the user and request password restore.

Tickets

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.

Billing information

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.

Checkout

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.

Purchase confirmation

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.

My Orders

Will show the purchased orders for the logged user.

My Order details

Will show the details for the selected Order, it also allows the user to download the Ticket PDF.

Tickets Resale

Let the user to resale their tickets. They can choose between selling them to a friend or to any other user.

Reset Password

After opening and URL with the corresponding schema, use this component to let the user reset its password.

Exported functions

  • setConfig: Sets config for the library

  • refreshAccessToken: Let refresh the expired access token.

Component styling

Button

interface IButtonStyles {
  container?: StyleProp<ViewStyle>
  button?: StyleProp<ViewStyle>
  text?: StyleProp<TextStyle>
}

Input

interface IInputStyles {
  color?: ColorValue
  container?: StyleProp<ViewStyle>
  input?: StyleProp<TextStyle>
  lineWidth?: number
  activeLineWidth?: number
  baseColor?: ColorValue
  errorColor?: ColorValue
}

Checkbox

interface ICheckboxStyles {
  container?: StyleProp<ViewStyle>
  content?: StyleProp<ViewStyle>
  indicator?: StyleProp<ViewStyle>
  indicatorDisabled?: StyleProp<ViewStyle>
  text?: StyleProp<TextStyle>
  box?: StyleProp<ViewStyle>
  icon?: StyleProp<ImageStyle>
}

Exported functions

setConfig

Set the configuration for the library.

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.

const response: IFetchAccessTokenResponse = await refreshAccessToken(refreshToken?: string)

Returns the new access token data or error.

accessTokenError?: {
  code?: number
  message: string
}
accessTokenData?: {
  accessToken: string
  refreshToken: string
  tokenType: string
  scope: string
}

Exported handlers

SessionCoreHandle

Exports function to refresh access token.

refreshAccessToken

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

const sessionHandleRef = useRef<SessionHandleType>(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

Login

Tickets

BillingInfo

Checkout

Purchase Confirmation

My Orders

My Order Details

Resale

Reset Password


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

import { Login } from 'tf-checkout-react-native'

Then add it to the render function.

<Login
  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<ViewStyle>
    image1?: ImageSourcePropType
    image1Style?: StyleProp<ImageStyle>
    image2?: ImageSourcePropType
    image2Style?: StyleProp<ImageStyle>
  }
  styles?: ILoginViewStyles
  texts?: ILoginViewTexts

  isShowPasswordButtonVisible?: boolean

  //Restore password
  onRestorePasswordError?: (error: IError) => void
  onRestorePasswordSuccess?: () => void
/>

Data Types

IUserProfile

{
  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

{
  accessToken: string
  refreshToken: string
  tokenType: string
  scope: string
}

Props

PropertyDescription
onLoginSuccessful: (userProfile: IUserProfile, accessToken: string)` |When login was successful, return userProfile data and the access token to use if for future API requests.
onLoginFailure?: (error: string)When login fails will return the error received.
onFetchUserProfileFailure?: (error: string)This is used if the authentication worked but the fetch of the userProfile failed.
onFetchAccessTokenFailure?: (error: string)When the fetch of the access token failed.
isLoginDialogVisible: booleanFlag to show or hide the login dialog.
showLoginDialog: () => voidCallback to show the Login dialog.
hideLoginDialog: () => voidCallback to hide the Login dialog.
onLogoutSuccess?: () => voidUse it to logout the authenticated user. It will delete all the stored data, including access token. Please make sure to update the userFirstName prop so the component will show the logged out view.
onLogoutFail?: () => voidWill be called if something went wrong while deleting the local data.
styles?: ILoginViewStylesUse this to style your components.
texts?: ILoginViewTextsUse this to change some texts that appear in this component.
userFirstName?: stringOnce authenticated send the received firstName data to this prop, so the component can render the Logged in view.
brandImages?: ILoginBrandImagesReceives up to 2 images with their styles and the container style for the images.
onRestorePasswordError?: (error: string)When restore password fails will return the error received.
onRestorePasswordSuccess?Called when restore password request was successful

styles

interface ILoginViewStyles {
  guest?: {
    loginButton?: IButtonStyles
    linesContainer?: StyleProp<ViewStyle>
    line1?: StyleProp<TextStyle>
    line2?: StyleProp<TextStyle>
    message?: StyleProp<TextStyle>
  }
  dialog?: {
    container?: StyleProp<ViewStyle>
    loginButton?: IButtonStyles
    loginButtonDisabled?: IButtonStyles
    input?: IInputStyles
    title?: StyleProp<TextStyle>
    message?: StyleProp<TextStyle>
  }
  loggedIn?: {
    container?: StyleProp<ViewStyle>
    placeholder?: StyleProp<TextStyle>
    value?: StyleProp<TextStyle>
    button?: IButtonStyles
    message?: StyleProp<TextStyle>
  }
  restorePassword?: {
    rootContainer?: StyleProp<ViewStyle>
    restorePasswordButton?: {
      container?: StyleProp<ViewStyle>
      button?: StyleProp<ViewStyle>
      text?: StyleProp<TextStyle>
    }
    cancelRestorePasswordButton?: {
      container?: StyleProp<ViewStyle>
      button?: StyleProp<ViewStyle>
      text?: StyleProp<TextStyle>
    }
    input?: IInputStyles
    title?: StyleProp<TextStyle>
    message?: StyleProp<TextStyle>
    apiError?: StyleProp<TextStyle>
  }
  restorePasswordSuccess?: {
    rootContainer?: StyleProp<ViewStyle>
    title?: StyleProp<TextStyle>
    message?: StyleProp<TextStyle>
    button?: {
      container?: StyleProp<ViewStyle>
      button?: StyleProp<ViewStyle>
      text?: StyleProp<TextStyle>
    }
  }
}

*Note: Logos images styles are passed from the brandImages prop.

texts

{
  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
  }
}

Tickets UI

This component will first fetch for the Event's data, if data is ok, then will fetch the tickets for this event.

Password protected 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.

import { Tickets } from 'tf-checkout-react-native'

Then add it to the render function.

const sessionHandleRef = useRef<SessionHandleType>(null)

<Tickets 
  ref={sessionHandleRef}
  onAddToCartSuccess={handleOnAddToCartSuccess} />

Props

{
  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:

{
  isBillingRequired: boolean
  isPhoneRequired?: boolean
  isAgeRequired?: boolean
  minimumAge?: number
  isNameRequired?: boolean
}

config prop

Configure the component's behavior

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.

styles

{
  rootContainer?: ViewStyle
  container?: ViewStyle
  title?: TextStyle
  getTicketsButtonDisabled?: IButtonStyles
  getTicketsButtonActive?: IButtonStyles
  promoCode?: {
    rootContainer?: ViewStyle
    contentWrapper?: ViewStyle
    content?: StyleProp<ViewStyle>
    input?: TextInputProps['style']
    inputPlaceholderColor?: string

    mainButton?: IButtonStyles
    applyButton?: IButtonStyles
    applyDisabledButton?: IButtonStyles

    errorMessage?: StyleProp<TextStyle>
    validMessage?: StyleProp<TextStyle>

    cancelButton?: StyleProp<ViewStyle>
    cancelIcon?: StyleProp<ImageStyle>
  }
  ticketList?: {
    sectionHeader?: {
      container?: StyleProp<ViewStyle>
      title?: StyleProp<TextStyle>
    }
    listContainer?: ViewStyle
    item?: {
      container?: ViewStyle
      ticketName?: TextStyle
      price?: TextStyle
      oldPrice?: TextStyle
      fees?: TextStyle
      soldOutText?: TextStyle
      soldOutContainer?: ViewStyle
      dropdown?: IDropdownStyles
      pricesContainer?: StyleProp<ViewStyle>
    }
  }
  loading?: {
    animation?: {
      color?: ActivityIndicatorProps['color']
      size?: ActivityIndicatorProps['size']
    }
    content?: ViewStyle
    text?: TextStyle
  }
  waitingList?: {
    rootContainer?: StyleProp<ViewStyle>
    title?: StyleProp<TextStyle>
    button?: IButtonStyles
    input?: IInputStyles
    buttonDisabled?: IButtonStyles
    success?: {
      container?: StyleProp<ViewStyle>
      title?: StyleProp<ViewStyle>
      message?: StyleProp<ViewStyle>
    }
  }
  loggedIn?: {
    rootContainer?: StyleProp<ViewStyle>
    myOrdersButton?: IButtonStyles
    logOutButton?: IButtonStyles
  }
  enterPassword?: {
    input?: IInputStyles
    title?: StyleProp<TextStyle>
    error?: StyleProp<TextStyle>
    button?: IButtonStyles
    rootContainer?: StyleProp<ViewStyle>
    contentContainer?: StyleProp<ViewStyle>
  }
}

texts

{
  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
  }
}

BillingInfo UI

Import the component from the library

import { BillingInfo } from 'tf-checkout-react-native'

Add it to the render function.

const sessionHandleRef = useRef<SessionHandleType>(null)


<BillingInfo
  ref={sessionHandleRef}
  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<ViewStyle>
      dialogContainer?: StyleProp<ViewStyle>
      brandImage?: StyleProp<ImageStyle>
      text?: StyleProp<TextStyle>
      activityIndicator?: {
        color?: ColorValue
        size?: 'large' | 'small'
      }
    }
    brandImage?: ImageSourcePropType
    isActivityIndicatorVisible?: boolean
  }

  loginBrandImages?:  {
    containerStyle?: StyleProp<ViewStyle>
    image1?: ImageSourcePropType
    image1Style?: StyleProp<ImageStyle>
    image2?: ImageSourcePropType
    image2Style?: StyleProp<ImageStyle>
  }

  config?: {
    isCheckoutAlwaysButtonEnabled?: boolean
    shouldHideTicketHolderSectionOnSingleTicket?: boolean 
  }
/>

DataTypes

ILoginSuccessData

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
  }
}

Props

PropertyDescription
cartPropsReceived from the Tickets component
onCheckoutSuccessWill return Order data from the Checkout action
loginBrandImages Receives styles and images sources to show in the Login component
skipBillingConfigConfigure the skipping component, visible when isBillingRequired is set to false 

texts

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
  }
}

styles

interface IBillingInfoViewStyles {
  rootContainer?: StyleProp<ViewStyle>
  loginStyles?: ILoginViewStyles
  checkoutButton?: IButtonStyles
  checkoutButtonDisabled?: IButtonStyles
  passwordTitle?: StyleProp<TextStyle>

  inputStyles?: IInputStyles
  dropdownStyles?: IDropdownStyles
  dropdownMaterialStyles?: {
    container?: StyleProp<ViewStyle>
    button?: StyleProp<ViewStyle>
    icon?: StyleProp<ImageStyle>
    label?: StyleProp<TextStyle>
    dialog?: StyleProp<ViewStyle>
    flatListContainer?: StyleProp<ViewStyle>
    listItem?: {
      container?: StyleProp<ViewStyle>
      button?: StyleProp<ViewStyle>
      buttonSelected?: StyleProp<ViewStyle>
      text?: StyleProp<TextStyle>
      textSelected?: StyleProp<TextStyle>
    }
    input?: IInputStyles
  }
  
  checkboxStyles?: {
    container?: StyleProp<ViewStyle>
    content?: StyleProp<ViewStyle>
    indicator?: StyleProp<ViewStyle>
    indicatorDisabled?: StyleProp<ViewStyle>
    text?: StyleProp<TextStyle>
    box?: StyleProp<ViewStyle>
    icon?: StyleProp<ImageStyle>
    error?: StyleProp<TextStyle>
  }

  screenTitle?: StyleProp<TextStyle>
  ticketHoldersTitle?: StyleProp<TextStyle>
  ticketHolderItemHeader?: StyleProp<TextStyle>

  texts?: StyleProp<TextStyle>
  customCheckbox?: ICheckboxStyles

  datePicker?: IDatePickerStyles
  
  privacyPolicyLinkStyle?: StyleProp<TextStyle>

  phoneInput?: {
    rootContainer?: StyleProp<ViewStyle>
    errorColor?: ColorValue
    country?: {
      container?: StyleProp<ViewStyle>
      button?: StyleProp<ViewStyle>
    }
    input?: IInputStyles
  }

  cartTimer?:  {
    rootContainer?: StyleProp<ViewStyle>
    contentContainer?: StyleProp<ViewStyle>
    textsContainer?: StyleProp<ViewStyle>
    icon?: StyleProp<ImageStyle>
    message?: StyleProp<TextStyle>
    time?: StyleProp<TextStyle>
  }

  privacyPolicyLinkStyle?: StyleProp<TextStyle>
}

Checkout UI

Import the component from the library

import { Checkout } from 'tf-checkout-react-native'

Add it to the render function.

const sessionHandleRef = useRef<SessionHandleType>(null)

<Checkout
  ref={sessionHandleRef}
  hash={hash}
  total={total}
  onPaymentSuccess={handleOnPaymentSuccess}
  onPressExit={handleStripeError}
  areLoadingIndicatorsEnabled={false}
  styles={styles}
  {...props}
/>

Props

{
  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
}
PropertyDescription
hashretrieved from the onCheckoutSuccess callback in the BillingInfocomponent. 
totalretrieved from the onCheckoutSuccess callback in the BillingInfo component.
onPaymentSuccesswill handle the success in the payment process. Will return the hash.
areLoadingIndicatorsEnabledwhether or not show the Loading Indicator, default: true.
areAlertsEnabledwhether or not show the Error Alerts, default: true.

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.

styles

{
  rootStyle?: ViewStyle
  title?: StyleProp<TextStyle>
  subTitle?: StyleProp<TextStyle>
  missingStripeConfig?: {
    container?: StyleProp<ViewStyle>
    message?: StyleProp<TextStyle>
    exitButton?: IButtonStyles
  }
  freeRegistrationButton?: IButtonStyles
  orderReview?: IOrderReviewStyles
  payment?: {
    container?: StyleProp<ViewStyle>
    title?: StyleProp<TextStyle>
    cardBackgroundColor?: string
    cardContainer?: StyleProp<ViewStyle>
    button?: IButtonStyles
    buttonDisabled?: IButtonStyles
  }
  cartTimer?: {
    rootContainer?: StyleProp<ViewStyle>
    contentContainer?: StyleProp<ViewStyle>
    textsContainer?: StyleProp<ViewStyle>
    icon?: StyleProp<ImageStyle>
    message?: StyleProp<TextStyle>
    time?: StyleProp<TextStyle>
  }
}

Stripe

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.


Purchase Confirmation UI

Import the component from the library

import { PurchaseConfirmation, SessionHandleType } from 'tf-checkout-react-native'

Add it to the render function.

const sessionHandleRef = useRef<SessionHandleType>(null)

<PurchaseConfirmation
  ref={sessionHandleRef}
  orderHash={checkoutProps!.hash}
  onComplete={handleOnComplete}

  styles?: {
    rootContainer?: StyleProp<ViewStyle>
    title?: StyleProp<TextStyle>

    message?: {
      container?: StyleProp<ViewStyle>
      line1?: StyleProp<TextStyle>
      line2?: StyleProp<TextStyle>
    }
    exitButton?: {
      container?: StyleProp<ViewStyle>
      button?: StyleProp<ViewStyle>
      text?: StyleProp<TextStyle>
    }
  }

  texts?: {
    title?: string
    message?: {
      line1?: string
      line2?: string
    }
    exitButton?: string
  }
/>

Props

PropertyDescription
orderHashThe hash returned in the BillingInfo component
onCompleteTo handle the completion of the flow. Here you can handle the unmount of the component or navigate to another screen
stylesStyles for the component
textsTexts for the component

My Orders UI

If there is a valid session, there will appear a button to access MyOrders in the Tickets component.

Import the component from the library.

import { MyOrders, SessionHandleType } from 'tf-checkout-react-native'

Props

{
  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<ViewStyle>
    listContainer?: StyleProp<ViewStyle>
    eventsContainer?: StyleProp<ViewStyle>
    eventsTitle?: StyleProp<TextStyle>
    refreshControlColor?: ColorValue
    eventsDropdown?: IDropdownStyles
    rootContainer?: StyleProp<ViewStyle>
    eventsSelectionContainer?: StyleProp<ViewStyle>
    clearEventSelectionIcon?: StyleProp<ImageStyle>
    timeFilters?: {
      container?: StyleProp<ViewStyle>
      dropdown?: IDropdownStyles
      selectionContainer?: StyleProp<ViewStyle>
      clearSelectionIcon?: StyleProp<ImageStyle>
    }
  }
  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

{
  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

{
  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
  }[]
}

styles

{
  orderListItem?: {
    rootContainer?: StyleProp<ViewStyle>
    contentContainer?: StyleProp<ViewStyle>
    infoContainer?: StyleProp<ViewStyle>
    infoTopContainer?: StyleProp<ViewStyle>
    infoBottomContainer?: StyleProp<ViewStyle>
    imageContainer?: StyleProp<ViewStyle>
    image?: StyleProp<ImageStyle>
    infoRootContainer?: StyleProp<ViewStyle>
    iconNextContainer?: StyleProp<ViewStyle>
    iconNext?: StyleProp<ImageStyle>
    orderId?: StyleProp<TextStyle>
    orderDate?: StyleProp<TextStyle>
    eventName?: StyleProp<TextStyle>
    priceContainer?: StyleProp<ViewStyle>
    price?: StyleProp<TextStyle>
    currency?: StyleProp<TextStyle>
  }
  safeArea?: StyleProp<ViewStyle>
  listContainer?: StyleProp<ViewStyle>
  eventsContainer?: StyleProp<ViewStyle>
  eventsTitle?: StyleProp<TextStyle>
  refreshControlColor?: ColorValue
  eventsDropdown?: {
    container?: StyleProp<ViewStyle>
    button?: StyleProp<ViewStyle>
    icon?: StyleProp<ImageStyle>
    label?: StyleProp<TextStyle>
    dialog?: StyleProp<ViewStyle>
    flatListContainer?: StyleProp<ViewStyle>
    listItem?: {
      container?: StyleProp<ViewStyle>
      button?: StyleProp<ViewStyle>
      buttonSelected?: StyleProp<ViewStyle>
      text?: StyleProp<TextStyle>
      textSelected?: StyleProp<TextStyle>
    }

  }
  rootContainer?: StyleProp<ViewStyle>
  eventsSelectionContainer?: StyleProp<ViewStyle>
  clearEventSelectionIcon?: StyleProp<ImageStyle>
}

MyOrder Details UI

When user selects an order from the MyOrders component, will show it details.

Import the component from the library.

import { MyOrderDetails, SessionHandleType } from 'tf-checkout-react-native'

Props

{
  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<ImageStyle>

  ticketActionsIcons?: {
    downloadPdf?: ImageSourcePropType
    sell?: ImageSourcePropType
    removeFromSale?: ImageSourcePropType
    refund?: ImageSourcePropType
  }

  styles?: {
    rootContainer?: StyleProp<ViewStyle>
    header?: {
      container?: StyleProp<ViewStyle>
      title?: StyleProp<TextStyle>
      subTitle?: StyleProp<TextStyle>

      shareLink?: {
        container?: StyleProp<ViewStyle>
        text?: StyleProp<TextStyle>
        link?: StyleProp<TextStyle>
        copyContainer?: StyleProp<ViewStyle>
        copyText?: StyleProp<TextStyle>
        copyIcon?: StyleProp<ImageStyle>
        copyIconTint?: ColorValue
        copyIconTintActive?: ColorValue
        message?: StyleProp<TextStyle>
        referrals?: StyleProp<TextStyle>
        referralValue?: StyleProp<TextStyle>
      }
    }
    section0Footer?: {
      container?: StyleProp<ViewStyle>
      label?: StyleProp<TextStyle>
      value?: StyleProp<TextStyle>
    }
    sectionHeader?: StyleProp<TextStyle>

    listItem?: {
      container?: StyleProp<ViewStyle>
      innerLeftContainer?: StyleProp<ViewStyle>
      innerRightContainer?: StyleProp<ViewStyle>
      rowPlaceholder?: StyleProp<TextStyle>
      rowValue?: StyleProp<TextStyle>
    }
    ticketItem?: {
      rootContainer?: StyleProp<ViewStyle>
      leftContent?: StyleProp<ViewStyle>
      rightContent?: StyleProp<ViewStyle>
      rowPlaceholder?: StyleProp<TextStyle>
      rowValue?: StyleProp<TextStyle>
      downloadButton?: IButtonStyles
      moreButton?: StyleProp<ViewStyle>
      moreButtonIcon?: StyleProp<ImageStyle>
    }
    downloadButton?: {
      container?: StyleProp<ViewStyle>
      button?: StyleProp<ViewStyle>
      text?: StyleProp<TextStyle>
    }
    bottomSheetModal?: {
      rootContainer?: StyleProp<ViewStyle>
      headerContainer?: StyleProp<ViewStyle>
      content?: StyleProp<ViewStyle>
      title?: StyleProp<TextStyle>
      closeButton?: StyleProp<ViewStyle>
      closeButtonIcon?: StyleProp<ImageStyle>
      contentContainer?: StyleProp<ViewStyle>
    }
  ticketActions?: {
    rootScrollViewContainer?: StyleProp<ViewStyle>
    buttonContainer?: StyleProp<ViewStyle>
    buttonContent?: StyleProp<ViewStyle>
    icon?: StyleProp<ImageStyle>
    text?: StyleProp<TextStyle>
  }
  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
    }
  }
}

Resale Tickets UI

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.

import { ResaleTickets, SessionHandleType } from 'tf-checkout-react-native'

Props

{
  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<ViewStyle>
    title?: StyleProp<TextStyle>
    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
  }
}

Reset Password UI

After opening and URL with the corresponding schema and token, use this component to let the user reset its password.

Usage

Import the component from the library.

import { ResetPassword } from 'tf-checkout-react-native'

Then add it to the render function.

<ResetPassword
  styles={myStyles}
  token={resetToken}
  onPressResetButton={handleOnPressResetButton}
  onPressCancelButton={handleOnPressCancelButton}
  onResetPasswordSuccess={handleOnResetPasswordSuccess}
  onResetPasswordError={handleOnResetPasswordError}
/>

Props

{
  token: string
  styles?: {
    rootContainer?: StyleProp<ViewStyle>
    contentContainer?: StyleProp<ViewStyle>
    title?: StyleProp<TextStyle>
    resetButton?: IButtonStyles
    cancelButton?: IButtonStyles
    input?: IInputStyles
    apiError?: StyleProp<TextStyle>
    apiSuccess?: StyleProp<TextStyle>
  }
  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
}

Core Components

⚠️ Remember that you first need to set your configuration using the setConfig function. ⚠️

Index

TicketsCore

WaitingListCore

BillingCore

CheckoutCore

PurchaseConfirmationCore

MyOrdersCore

OrderDetailsCore

LoginCore

ResetPasswordCore


SessionCoreHandle

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:

IFetchAccessTokenResponse {
  accessTokenError?: {
    code?: number
    message: string
    extraData?: any
  }
  accessTokenData?: {
    accessToken: string
    refreshToken: string
    tokenType: string
    scope: string
  }
}

Example:

Import the component from the library

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.

const ticketsCoreRef = useRef<TicketsCoreHandle>(null)

Then add it to the render function and assign the reference to the corresponding component.

<TicketsCore ref={ticketsCoreRef}>
  <YourComponent />
</TicketsCore>

Use the reference to access the component methods.

const handleGetTickets = async () => {
  const res = await ticketsCoreRef.current.refreshAccessToken()
}

TicketsCore

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.

{
  // 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
      waitingListMaxQuantity: number
    }
  }>

  // Adds selected tickets to the cart.
  addToCart(
    options: {  
      optionName: string
      ticketId: string
      quantity: number
      price: number
    }
  ): Promise<{
    error?: {
      code?: number
      message: string
      extraData?: any
    }
    data?: {
      isBillingRequired: boolean
      isPhoneRequired?: boolean
      isAgeRequired?: boolean
      minimumAge?: number
      isNameRequired?: boolean
      isTicketFree?: boolean
      isPhoneHidden?: boolean
    }

    postReferralVisit(referralId: string): Promise<
      postReferralError?: {
        code?: number
        message: string
        extraData?: any
      }
      postReferralData?: {
      message: string
      status: number
    }>
    refreshAccessToken(refreshToken?: string): Promise<IFetchAccessTokenResponse>

    getAccountTickets({
      page: number
      limit?: number
      filter?: string
      from?: MyOrderRequestFromType
    }): Promise<
      data?: {
        attributes: {
          page: number
          limit: number
          total_count: number
          total_pages: number
          filter?: any
          brand_filter: string
          sub_brands: boolean
          purchased_events: {
            url_name: string
            event_name: string
          }[]
          tickets: {
            id: string
            orderId: string
            hash: string
            qrData: string
            ticketType: string
            ticketTypeHash: string
            description?: any
            descriptionPlain?: any
            currency: string
            price: string
            retainAmountOnSale: number
            status: string
            holderName: string
            holderEmail?: any
            holderPhone?: any
            isTable: boolean
            isSellable: boolean
            isOnSale: boolean
            createdAt: Date
            pdfLink: string
            eventId: string
            eventName: string
            eventUrl: string
            eventTimezone: string
            eventStartDate: Date
            eventEndDate: Date
            eventSalesStartDate?: any
            eventSalesEndDate: Date
            eventImage: string
            eventBackgroundImage: string
            eventIsOnlineEvent: boolean
            venueCountry: string
            venueCity: string
            venueState: string
            hideVenueUntil?: any
            hideVenue: boolean
            venueName?: string //Optional
            venueGooglePlaceId?: string //Optional
            venueLatitude?: string //Optional
            venueLongitude?: string //Optional
            venuePostalCode?: string //Optional
            venueStreet?: string //Optional
            venueStreetNumber?: string //Optional
          }[]
        }
        relationships: any[]
        type: string
      },  
      error?: IError>
  }>
}

MyOrderRequestFromType

MyOrderRequestFromType =
  | 'upcoming_events'
  | 'ongoing_and_upcoming_events'
  | 'ongoing_events'
  | 'past_events'
  | ''

Import the component from the library

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.

const ticketsCoreRef = useRef<TicketsCoreHandle>(null)

Then add it to the render function and assign the reference to the corresponding component.

<TicketsCore ref={ticketsCoreRef}>
  <YourComponent />
</TicketsCore>

Use the reference to access the component methods.

const handleGetTickets = async () => {
  const res = await ticketsCoreRef.current.getTickets()
}

WaitingListCore

This component must appear after getting the response from getTickets() and the property isInWaitingList is set to true.

Exposes the following functions:

{
  addToWaitingList(
    params: {
      firstName: string
      lastName: string
      email: string
    }
  ): Promise<{
    addToWaitingListError?: {
      code?: number
      message: string
      extraData?: any
    }
    addToWaitingListData?: {
      error: boolean
      message: string
      status: number
      success: boolean
    }
  }>
  refreshAccessToken(refreshToken?: string): Promise<IFetchAccessTokenResponse>
}

addToWaitingList Receives params with the following properties:

firstName: string
lastName: string 
email: string

And returns a Promise with the following object:

{
  addToWaitingListError?: {
    code?: number // If it was a server error, this will be the error code
    message: string //Error message that you could use it in your UI
    extraData?: any // If there is a relevant extra data, it will be returned here
  }
  addToWaitingListData?: {
    error: boolean // If there was an error, this will be true
    message: string // message that you could use it in your UI, could be due an error or a success message
    status: number // Status code
    success: boolean // If there was no error, this will be true
  }
}

Import the component from the library

import { 
  WaitingListCore 
  WaitingListCoreHandle // You can import the Handle to use as type it in the useRef hook
} from 'tf-checkout-react-native'

Declare a reference to pass it to the component.

const waitingListCoreRef = useRef<WaitingListCoreHandle>(null)

Then add it to the render function and assign the reference to the corresponding component.

<WaitingListCore ref={waitingListCoreRef}>
  <YourComponent />
</WaitingListCore>

Use the reference to access the component methods.

const handleAddToWaitingList = async (params: IAddToWaitingListCoreParams) => {
  const res = await waitingListCoreRef.current.addToWaitingList(params)
}

BillingCore

This component collects user's billing information and checks the order out. If the entered user data is already in the system it will perform checkout, other wise it will perform a registration and then the checkout.

Exposes the following functions:

getCart Fetches the current cart information, needed to know how many ticket holders data is needed.

getCountries Fetches the countries list.

getStates Fetches the states list.

getUserProfile Fetches the user profile information.

registerNewUser Registers a new user. Returns accessTokens data.

checkoutOrder Performs the checkout.

{
  // Fetches the current cart information, needed to know how many ticket holders data is needed.
  getCart(): Promise<{
    cartError?: {
      code?: number
      message: string
      extraData?: any
    }
    cartData?: {
      quantity: number
      isTfOptInHidden?: boolean
      isTfOptIn: boolean // Ticket fairy
      isMarketingOptedIn: boolean // Brand
    }
  }>

  // Performs the checkout.
  checkoutOrder(body: ICheckoutBody): Promise<{
    error?: {
      code?: number
      message: string
      extraData?: any
    }
    data?: {
      id: string
      hash: string
      total: string
      status: string
    }
  }>

  // Fetches the country list.
  getCountries(): Promise<{
     countriesError?: {
       code?: number
       message: string
       extraData?: any
     }
    countriesData?:  {
      code: string
      id: string
      name: string
    }[]
  }>

  // Fetches the states list.
  getStates(countryId: string): Promise<{
    statesError?: {
       code?: number
       message: string
       extraData?: any
     }
    statesData?: {
      [key: number | string]: string
    }
  }>

  // Fetches the user profile information.
  getUserProfile(): Promise<{
    userProfileError?: {
       code?: number
       message: string
       extraData?: any
     }
    userProfileData?: {
      customerId: string
      firstName: string
      lastName: string
      email: string
      phone: string
      streetAddress: string
      zipCode: string
      countryId: string
      company?: string
      state: string
      stateId: string
      city: string
    }
  }>

  // Registers a new user.
  registerNewUser(data: FormData): Promise<{
    registerNewUserResponseError?: {
      isAlreadyRegistered?: boolean
      message?: string
      raw?: any
    }
    registerNewUserResponseData?: {
      accessTokenData: {
        accessToken: string
        refreshToken: string
        tokenType: string
        scope: string
      }
      userProfile: {
        firstName: string
        lastName: string
        email: string
      }
    }
  }>

  refreshAccessToken(refreshToken?: string): Promise<IFetchAccessTokenResponse>
}

CheckoutCore

Shows the event conditions, purchase details and process the payment and free registration to an event.

You will need to install and use the ReactNative Stripe SDK (we recommend version 0.2.3). Follow their documentation to implement it. Our backend is already prepared to process the payments.

Remember that you will need the publishableKey.

After you collect the card information and call the confirmPayment function, you will need to call the paymentSuccess function to complete the payment.

Exposes the following functions:

getEventConditions Get event conditions for the current event.

getPurchaseOrderDetails Get purchase order details for the current event.

getOrderReview Get order review for the current event.

freeRegistration Free registration to an event.

paymentSuccess Payment success.

refreshAccessToken Refreshes access token.

// Get event conditions for the Event Id set on the setConfig.
getEventConditions(): Promise<any>

// Get purchase order details for the current event.
getPurchaseOrderDetails(orderId: string): Promise<{
  orderDetailsError?: {
    code?: number
    message: string
    extraData?: any
  }
  orderDetailsData?: {
    header: {
      isReferralDisabled: boolean
      shareLink: string
      total: string
      salesReferred: string
    }
    items: {
      isActive: boolean
      currency: string
      discount: string
      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: true
      pdfLink: string
      qrData: string
      resaleFeeAmount: number
      status: string
      ticketType: string
    }[]
  }
}>

// Get order review for the current event.
getOrderReview(orderHash: string): Promise<{
  orderReviewError?: {
    code?: number
    message: string
    extraData?: any
  }
  orderReviewData?: {
    reviewData: {
      event: string
      price: string
      ticketType: string
      total: string
      numberOfTickets: string
      currency: string
    }
    paymentData: {
      id: string
      name: string
      stripeClientSecret?: string
      stripeConnectedAccount?: string
      stripePublishableKey?: string
1.0.37

4 months ago

1.0.36

4 months ago

1.0.35

4 months ago

1.0.34

4 months ago

1.0.33

5 months ago

1.0.32

6 months ago

1.0.29

12 months ago

1.0.31

11 months ago

1.0.30

12 months ago

1.0.26

1 year ago

1.0.25

1 year ago

1.0.24

1 year ago

1.0.28

1 year ago

1.0.27

1 year ago

1.0.22

2 years ago

1.0.23

2 years ago

1.0.21

2 years ago

1.0.20

2 years ago

1.0.19

2 years ago

1.0.18

2 years ago

1.0.17

2 years ago

1.0.16

2 years ago

1.0.15

2 years ago

1.0.14

2 years ago

1.0.11

2 years ago

1.0.13

2 years ago

1.0.12

2 years ago

1.0.10

2 years ago

1.0.9

2 years ago

1.0.8

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago