Skip to content

tonderio/rn-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Tonder React Native SDK

Tonder React Native SDK helps integrate Tonder's payment services into your React Native application, providing secure and flexible payment processing capabilities.

Table of Contents

Installation

npm install @tonder.io/rn-sdk
# OR
yarn add @tonder.io/rn-sdk

Requirements

  • react-native >= 0.70
  • react >= 16.8
  • react-native-svg >= 15.0.0
  • react-native-webview >= 13.6.0

Features

The SDK supports three integration types:

  • SDKType.INLINE: Full payment UI with built-in components and features

    • Pre-built UI components
    • Saved cards management
    • Multiple payment methods support
    • Built-in error handling and validation
    • Customizable styling and layout
    • Input field event handling (onChange, onFocus, onBlur)
  • SDKType.LITE: Individual components for custom UI implementations

    • Secure input components for custom payment forms
    • Card enrollment and management
    • Payment method handling
    • Card tokenization and storage
    • Card deletion capabilities
    • Manual payment flow control
    • Flexible UI customization
    • Input field event handling (onChange, onFocus, onBlur)
    • Direct access to all SDK features:
      • Payment processing
      • Card saving
      • Card listing
      • Card deletion
      • Card summary
      • Payment methods retrieval
  • SDKType.ENROLLMENT: Card saving functionality

    • Card tokenization
    • Card validation
    • Card summary
    • Secure storage
    • Input field event handling (onChange, onFocus, onBlur)

Each type can be specified when initializing the SDK through the TonderProvider:

// Full Payment UI
<TonderProvider
  config={{
    type: SDKType.INLINE,
    mode: Environment.stage,
    apiKey: 'your-api-key',
  }}
>
  <YourApp />
</TonderProvider>

// Custom UI with Individual Components
<TonderProvider
  config={{
    type: SDKType.LITE,
    mode: Environment.stage,
    apiKey: 'your-api-key',
  }}
>
  <YourApp />
</TonderProvider>

// Card Enrollment
<TonderProvider
  config={{
    type: SDKType.ENROLLMENT,
    mode: Environment.stage,
    apiKey: 'your-api-key',
  }}
>
  <YourApp />
</TonderProvider>

Secure token

For card-related operations (save, list, delete), you need a secure token. This should be obtained through your backend for security:

Important Note about SaveCard functionality: To properly implement the SaveCard feature, you must use a SecureToken. For detailed implementation instructions and best practices, please refer to our official documentation on How to use SecureToken for secure card saving.

Important: Never expose your API secret key in frontend code. It is recommended to implement token generation in your backend.

const getSecureToken = async (apiSecretKey: string) => {
  const response = await fetch(
    `${TONDER_ENVIRONMENT_URL}/api/secure-token/`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Token ${'YOUR-SECRET-API-KEY'}`,
        'Content-Type': 'application/json',
      },
    }
  );

  const data = await response.json();
  return data.access;
};

Usage

Provider Setup

First, wrap your application or payment screen with the TonderProvider:

import { TonderProvider, SDKType, Environment } from '@tonder.io/rn-sdk';

function App() {
  return (
    <TonderProvider
      config={{
        type: SDKType.INLINE,  // or SDKType.LITE or SDKType.ENROLLMENT
        mode: Environment.stage, // or production
        apiKey: 'your-api-key',
      }}
    >
      <YourApp />
    </TonderProvider>
  );
}

Full Payment Integration

The Full Payment integration provides a complete pre-built UI for payment processing Before create the mobile SDK, your checkout page should:

  • Obtain the security token for card functionalities (save, delete, list).
  • Show the products being purchased and the total amount
  • Collect any required customer information
import {
  TonderPayment,
  useTonder,
  SDKType,
  IBaseProcessPaymentRequest
} from '@tonder.io/rn-sdk';

export default function FullPaymentScreen() {
  const { create, reset } = useTonder<SDKType.INLINE>();

  const paymentData: IBaseProcessPaymentRequest = {
    customer: {
      email: 'test@example.com',
      firstName: 'John',
      lastName: 'Doe',
    },
    cart: {
      total: 399,
      items: [{
        name: 'Product',
        amount_total: 399,
        description: 'Description',
        price_unit: 399,
        quantity: 1,
      }]
    }
  };

  useEffect(() => {
    initializePayment();
  }, []);

  const initializePayment = async () => {
    const { error } = await create({
      secureToken: 'your-secure-token',
      paymentData,
      callbacks: {
        onFinishPayment: handlePaymentFinish
      }
    });

    if (error) {
      console.error('SDK initialization error:', error);
    }
  };

  const callbackFinish = async (response) => {
    console.log('Callback finish payment', response);

    // Reset the state and regenerate the SDK to use it again.
    reset();
    await initializePayment();
  };

  return (
    <SafeAreaView>
      <TonderPayment />
    </SafeAreaView>
  );
}

Lite Payment Integration

The Lite Payment integration provides individual components for a custom payment UI. Before create the mobile SDK, your checkout page should:

  • Obtain the security token for card functionalities (save, delete, list).
  • Show the products being purchased and the total amount
  • Collect any required customer information
import {
  CardHolderInput,
  CardNumberInput,
  CardExpirationMonthInput,
  CardExpirationYearInput,
  CardCVVInput,
  useTonder,
  SDKType
} from '@tonder.io/rn-sdk';

export default function LitePaymentScreen() {
  const { create, payment } = useTonder<SDKType.LITE>();

  const paymentData = {
    customer: {
      email: 'test@example.com',
      firstName: 'John',
      lastName: 'Doe',
    },
    cart: {
      total: 399,
      items: [{
        name: 'Product',
        amount_total: 399,
        description: 'Description',
        price_unit: 399,
        quantity: 1,
      }]
    }
  };

    useEffect(() => {
    initializePayment();
  }, []);

  const initializePayment = async () => {
    const { error } = await create({
      secureToken: 'your-secure-token',
      paymentData,
      customization: {
        saveCards: {
          autoSave: false,
        },
      },
    });

    if (error) {
      console.error('SDK initialization error:', error);
    }
  };

  const handlePayment = async () => {
    const { response, error } = await payment();
    if (error) {
      console.error('Payment error:', error);
      return;
    }
    console.log('Payment success:', response);
  };

  return (
    <SafeAreaView>
      <CardHolderInput />
      <CardNumberInput />
      <CardExpirationMonthInput />
      <CardExpirationYearInput />
      <CardCVVInput />
      <TouchableOpacity onPress={handlePayment}>
        <Text>Pay</Text>
      </TouchableOpacity>
    </SafeAreaView>
  );
}

Lite Payment with Saved Cards

When using the LITE SDK with saved cards, you can use the CardCVVInput component with the cardId prop to update the CVV of a specific saved card. This is particularly useful when displaying a list of saved cards, as some cards may have dynamic CVVs that change over time.

import {
  CardCVVInput,
  useTonder,
  SDKType,
  type ICard
} from '@tonder.io/rn-sdk';

export default function LitePaymentSavedCardsScreen() {
  const { create, payment, getCustomerCards } = useTonder<SDKType.LITE>();
  const [cards, setCards] = useState<ICard[]>([]);
  const [selectedCard, setSelectedCard] = useState<string | null>(null);

  const paymentData = {
    customer: {
      email: 'test@example.com',
      firstName: 'John',
      lastName: 'Doe',
    },
    cart: {
      total: 399,
      items: [{
        name: 'Product',
        amount_total: 399,
        description: 'Description',
        price_unit: 399,
        quantity: 1,
      }]
    }
  };

  useEffect(() => {
    initializePayment();
  }, []);

  const initializePayment = async () => {
    const { error } = await create({
      secureToken: 'your-secure-token',
      paymentData,
      customization: {
        saveCards: {
          autoSave: false,
        },
      },
    });

    if (error) {
      console.error('SDK initialization error:', error);
    }

    // Fetch saved cards
    await fetchCards();
  };

  const fetchCards = async () => {
    const { response } = await getCustomerCards();
    if (response?.cards) {
      setCards(response.cards);
    }
  };

  const handlePayment = async () => {
    if (!selectedCard) return;

    // Send payment data with selected card ID
    const paymentDataToSend = { ...paymentData, card: selectedCard };
    const { response, error } = await payment(paymentDataToSend);

    if (error) {
      console.error('Payment error:', error);
      return;
    }
    console.log('Payment response: ', response);

    // Validate the transaction status
    console.log('Payment status: ', response?.transaction_status );
  };

  return (
    <SafeAreaView>
      <ScrollView>
        {cards.map((card) => (
          <TouchableOpacity
            key={card.fields.skyflow_id}
            onPress={() => setSelectedCard(card.fields.skyflow_id)}
          >
            <Text>{card.fields.cardholder_name}</Text>
            <Text>•••• {card.fields.card_number.slice(-4)}</Text>

            {/* CVV input for the selected card */}
            {selectedCard === card.fields.skyflow_id && (
              <CardCVVInput
                placeholder="CVV"
                cardId={card.fields.skyflow_id}
              />
            )}
          </TouchableOpacity>
        ))}

        <TouchableOpacity
          onPress={handlePayment}
          disabled={!selectedCard}
        >
          <Text>Pay with Selected Card</Text>
        </TouchableOpacity>
      </ScrollView>
    </SafeAreaView>
  );
}

Card Enrollment Integration

For saving cards without processing payments. Before create the mobile SDK, your checkout page should:

  • Obtain the security token for card functionalities (save, delete, list).
  • Collect any required customer information

First, wrap your application or payment screen with the TonderProvider:

<TonderProvider
  config={{
    type: SDKType.ENROLLMENT,
    mode: Environment.stage, // or production
    apiKey: 'your-api-key',
  }}
>
  <YourApp />
</TonderProvider>
import {
  TonderEnrollment,
  useTonder,
  SDKType,
  ICustomer,
  type IBaseResponse,
  type ISaveCardResponse,
} from '@tonder.io/rn-sdk';

export default function EnrollmentScreen() {
  const { create, reset } = useTonder<SDKType.ENROLLMENT>();

  const customerData: ICustomer = {
    email: 'test@example.com',
    firstName: 'John',
    lastName: 'Doe'
  };

  useEffect(() => {
    initializeEnrollment();
  }, []);

  const initializeEnrollment = async () => {
    const { error } = await create({
      secureToken: 'your-secure-token',
      customer: customerData,
      callbacks: {
        onFinishSave: handleSaveFinish
      }
    });

    if (error) {
      console.error('Enrollment initialization error:', error);
    }
  };

  const handleSaveFinish = async (response: IBaseResponse<ISaveCardResponse>) => {
    console.log('Callback finish save card', response);

    if (response.error) {
      // Manage the error
      Alert.alert('Error', 'Failed to save card. Please try again.');
      console.log('Save Card ERROR', response.error);
      return;
    }
    console.log('Card saved successfully:', response);

    await handleGetSummaryCard(response.response.skyflow_id);
    // Reset the state and regenerate the SDK to use it again
    reset();
    await initializeEnrollment();
  };

  const handleGetSummaryCard = async (id: string) => {
    const { response, error } = await getCardSummary(id);
    if (error) {
      //Manage error
      Alert.alert('Error', 'Failed to get summary card');
      console.error('Error get summary card: ', error);
      return;
    }
    console.log('Response get summary: ', response);
  };

  return (
    <SafeAreaView>
      <TonderEnrollment />
    </SafeAreaView>
  );
}

Example with custom button

import {
  TonderEnrollment,
  useTonder,
  SDKType,
  ICustomer
} from '@tonder.io/rn-sdk';

export default function EnrollmentScreen() {
  const { create, reset, saveCustomerCard, getCardSummary } = useTonder<SDKType.ENROLLMENT>();

  const customerData: ICustomer = {
    email: 'test@example.com',
    firstName: 'John',
    lastName: 'Doe'
  };

  useEffect(() => {
    initializeEnrollment();
  }, []);

  const initializeEnrollment = async () => {
    const { error } = await create({
      secureToken: 'your-secure-token',
      customer: customerData,
      customization: {
        saveButton: {
          show: false, // hidde default button
        },
      },
    });

    if (error) {
      console.error('Enrollment initialization error:', error);
    }
  };

  const handleSaveCard = async () => {
    const { response, error } = await saveCustomerCard();
    if (error) {
      //Manage error
      console.error('Error saving card: ', error);
      return;
    }
    console.log('Response save card: ', response);

    // Get card summary using the skyflow_id from the save response
    await handleGetCardSummary(response.skyflow_id);
    // Reset the state and regenerate the SDK to use it again
    reset();
    await initializeEnrollment();
  };

  const handleGetCardSummary = async (skyflowId: string) => {
    const { response, error } = await getCardSummary(skyflowId);
    if (error) {
      console.error('Error getting card summary:', error);
      return;
    }
    console.log('Card summary:', response);
    // Response contains: user_id and card details
  };

  return (
    <SafeAreaView>
      <TonderEnrollment />
      {/*Custom button*/}
      <TouchableOpacity
        onPress={handleSaveCard}
      >
        <Text>Guardar</Text>
      </TouchableOpacity>
    </SafeAreaView>
  );
}

Card Enrollment Lite Integration

For saving cards with individual components, before create the mobile SDK, your checkout page should:

  • Obtain the security token for card functionalities (save, delete, list).
  • Collect any required customer information:

First, wrap your application or payment screen with the TonderProvider:

import { TonderProvider, SDKType, Environment } from '@tonder.io/rn-sdk';
<TonderProvider
  config={{
    type: SDKType.ENROLLMENT,
    mode: Environment.stage, // or production
    apiKey: 'your-api-key',
  }}
>
  <YourApp />
</TonderProvider>
import {
  CardHolderInput,
  CardNumberInput,
  CardExpirationMonthInput,
  CardExpirationYearInput,
  CardCVVInput,
  useTonder,
  SDKType,
  ICustomer
} from '@tonder.io/rn-sdk';

export default function EnrollmentLiteScreen() {
  const { create, saveCustomerCard, reset, getCardSummary } = useTonder<SDKType.ENROLLMENT>();

  const customerData: ICustomer = {
    email: 'test@example.com',
    firstName: 'John',
    lastName: 'Doe'
  };

  useEffect(() => {
    initializeEnrollment();
  }, []);

  const initializeEnrollment = async () => {
    const { error } = await create({
      secureToken: 'your-secure-token',
      customer: customerData,
    });

    if (error) {
      console.error('Enrollment initialization error:', error);
    }
  };

  const handleSaveCard = async () => {
    try {
      const { response, error } = await saveCustomerCard();
      if (error) {
        console.error('Error saving card:', error);
        return;
      }
      console.log('Card saved successfully:', response);
      // GET summary card
      await handleGetSummaryCard(response.skyflow_id);
      // Reset and reinitialize for next use
      reset();
      await initializeEnrollment();
    } catch (e) {
      console.error('Unexpected error:', e);
    }
  };

  const handleGetSummaryCard = async (id: string) => {
    const { response, error } = await getCardSummary(id);
    if (error) {
      //Manage error
      Alert.alert('Error', 'Failed to get summary card');
      console.error('Error get summary card: ', error);
      return;
    }
    console.log('Response get summary: ', response);
  };

  return (
    <SafeAreaView>
          <CardHolderInput />
          <CardNumberInput />
          <CardExpirationMonthInput />
          <CardExpirationYearInput />
          <CardCVVInput />
          <TouchableOpacity
            onPress={handleSaveCard}
          >
              <Text>Save Card</Text>
          </TouchableOpacity>
    </SafeAreaView>
  );
}

Configuration

Base Configuration

Property Type Required Description
mode 'development' | 'production' | 'sandbox' Yes Environment mode for the SDK
apiKey string Yes Your Tonder Public API key
type SDKType Yes Integration type (INLINE or LITE or ENROLLMENT)
returnURL string No URL for 3DS redirect completion
View Interface Definition
interface ISDKBaseConfig {
  mode: 'development' | 'production' | 'sandbox'; // Environment.stage
  apiKey: string;
  type: SDKType;
  returnURL?: string;
}

Inline Options

Provide this information when calling the create function.

Option Type Required Description
paymentData IBaseProcessPaymentRequest Yes Payment information including customer and cart data
customization IInlineCustomizationOptions No UI customization options
callbacks IInlineCallbacks No Payment process callback functions
events IEvents No Event handlers for card form input fields (onChange, onFocus, onBlur)
returnURL string No URL for 3D Secure redirect completion
View IInlineCheckoutOptions Interface
interface IInlineCheckoutOptions extends IBaseCreateOptions {
  paymentData: IBaseProcessPaymentRequest;
  customization?: IInlineCustomizationOptions;
  callbacks?: IInlineCallbacks;
  events?: IEvents;
  returnURL?: string;
}

Lite Options

Provide this information when calling the create function.

Option Type Required Description
paymentData IProcessPaymentRequest Yes Payment information including customer and cart data
customization ILiteCustomizationOptions No UI customization options
callbacks ILiteCallbacks No Payment process callback functions
returnURL string No URL for 3D Secure redirect completion
View IInlineCheckoutOptions Interface
interface ILiteCheckoutOptions extends IBaseCreateOptions {
  paymentData: IProcessPaymentRequest;
  customization?: ILiteCustomizationOptions;
  callbacks?: ILiteCallbacks;
  returnURL?: string;
}

Enrollment Options

Provide this information when calling the create function.

Option Type Required Description
customer ICustomer Yes Customer information
customization IEnrollmentCustomizationOptions No UI customization options
events IEvents No Event handlers for card form input fields (onChange, onFocus, onBlur)
callbacks IEnrollmentCallbacks No Enrollment process callback functions
View IInlineCheckoutOptions Interface
export interface IEnrollmentOptions extends IBaseCreateOptions {
  customer?: ICustomer;
  customization?: IEnrollmentCustomizationOptions;
  callbacks?: IEnrollmentCallbacks;
  events?: IEvents;
}

Inline Callbacks Structure

Callback Parameters Description Return
beforePayment none Called before the payment process begins. You can use this to show a loading state, validate additional data, or perform any pre-payment tasks. Promise
onFinishPayment response: IBaseResponse<ITransaction> Called when the payment process completes (success or error). Provides the transaction result or error details. Promise
beforeDeleteCard none Called before the delete card process begins. You can use this to show a loading state, validate additional data, or perform any pre-delete tasks. Promise
onFinishDeleteCard response: IBaseResponse<string> Called when the delete card process completes (success or error). Promise
View Callback Interface
export interface IInlineCallbacks {
  beforePayment?: () => Promise<void>;
  onFinishPayment?: (response: IBaseResponse<ITransaction>) => Promise<void>;
  beforeDeleteCard?: () => Promise<void>;
  onFinishDeleteCard?: (response: IBaseResponse<string>) => Promise<void>;
}

Lite Callbacks Structure

Callback Parameters Description Return
beforePayment none Called before the payment process begins. You can use this to show a loading state, validate additional data, or perform any pre-payment tasks. Promise
onFinishPayment response: IBaseResponse<ITransaction> Called when the payment process completes (success or error). Provides the transaction result or error details. Promise
View Callback Interface
export interface ILiteCallbacks {
  beforePayment?: () => Promise<void>;
  onFinishPayment?: (response: IBaseResponse<ITransaction>) => Promise<void>;
}

Enrollment Callbacks Structure

Callback Parameters Description Return
beforeSave none Called before the save card process begins. You can use this to show a loading state, validate additional data, or perform any pre-save-card tasks. Promise
onFinishSave response: IBaseResponse<ISaveCardResponse> Called when the save card process completes (success or error). Provides the transaction result or error details. Promise
View Callback Interface
export interface IEnrollmentCallbacks {
  beforeSave?: () => Promise<void>;
  onFinishSave?: (response: IBaseResponse<ISaveCardResponse>) => Promise<void>;
}

Payment Data Structure

Customer Information

Field Type Required Description
email string Yes Customer's email address
firstName string Yes Customer's first name
lastName string Yes Customer's last name
phone string No Customer's contact phone number
address string No Customer's street address
city string No Customer's city
state string No Customer's state/province
country string No Customer's country
postCode string No Customer's postal/ZIP code

Cart Information

Field Type Required Description
total number Yes Total amount of the transaction
items Array<IItem> Yes Array of items in the cart
metadata Record<string, any> No Additional custom data for the transaction
currency string No Currency code (default: MXN)

Cart Item Structure

Field Type Required Description
name string Yes Product name
amount_total number Yes Total amount for this item (quantity Ă— price)
description string Yes Product description
price_unit number Yes Unit price of the product
product_reference string Yes Unique identifier for the product
quantity number Yes Number of units
discount number No Discount amount applied
taxes number No Tax amount applied

Additional fields for LITE VERSION

Field Type Required Description
card string no The ID of the card selected by the user.
payment_method string no The payment method selected by the user.
View Complete Payment Data Interface
// FOR INLINE VERSION
interface IBaseProcessPaymentRequest {
  customer: {
    email: string;
    firstName: string;
    lastName: string;
    phone?: string;
    address?: string;
    city?: string;
    state?: string;
    country?: string;
    postCode?: string;
  };
  cart: {
    total: number;
    items: Array<{
      name: string;
      amount_total: number;
      description: string;
      price_unit: number;
      quantity: number;
      discount?: number;
      taxes?: number;
    }>;
  };
  metadata?: Record<string, any>;
  currency?: string;
}

// FOR LITE VERSION
interface IProcessPaymentRequest {
  customer: {
    email: string;
    firstName: string;
    lastName: string;
    phone?: string;
    address?: string;
    city?: string;
    state?: string;
    country?: string;
    postCode?: string;
  };
  cart: {
    total: number;
    items: Array<{
      name: string;
      amount_total: number;
      description: string;
      price_unit: number;
      quantity: number;
      discount?: number;
      taxes?: number;
    }>;
  };
  metadata?: Record<string, any>;
  currency?: string;
  card?: string;
  payment_method?: string;
}

Customization Options for Inline Version

Option Type Default Description
saveCards
saveCards.showSaveCardOption boolean true Shows a checkbox allowing users to choose whether to save their card for future purchases
saveCards.showSaved boolean true Displays a list of previously saved cards for the customer
saveCards.autoSave boolean false Automatically saves the card without showing the save option to the user
saveCards.showDeleteOption boolean true Shows a delete button for each saved card in the list
paymentButton
paymentButton.show boolean true Controls the visibility of the payment button
paymentButton.text string 'Pagar' Custom text to display on the payment button
paymentButton.showAmount boolean true Shows the payment amount on the button (e.g., "Pay $100")
paymentMethods
paymentMethods.show boolean true Controls the visibility of alternative payment methods section
cardForm
cardForm.show boolean true Controls the visibility of the card input form
General
showMessages boolean true Controls the visibility of error and success messages
labels object - Custom labels for form fields (see Form Labels)
placeholders object - Custom placeholder text for form inputs (see Form Placeholders)
styles object - Custom styles for UI components (see Styling section)
View Interface Definition
interface IInlineCustomizationOptions {
  saveCards?: {
    showSaveCardOption?: boolean;
    showSaved?: boolean;
    autoSave?: boolean;
    showDeleteOption?: boolean;
  };
  paymentButton?: {
    show?: boolean;
    text?: string;
    showAmount?: boolean;
  };
  paymentMethods?: {
    show?: boolean;
  };
  cardForm?: {
    show?: boolean;
  };
  showMessages?: boolean;
  labels?: IFormLabels;
  placeholders?: IFormPlaceholder;
  styles?: IStyles;
}

Customization Options for Lite Version

Option Type Default Description
saveCards
saveCards.autoSave boolean false Automatically saves the card without showing the save option to the user
View Interface Definition
interface ILiteCustomizationOptions {
  saveCards?: {
    autoSave?: boolean;
  };
}

Customization Options for Enrollment Version

Option Type Default Description
saveButton
saveButton.show boolean true Controls the visibility of the save button
saveButton.text string 'Guardar' Custom text to display on the save button
General
showMessages boolean true Controls the visibility of error and success messages
labels object - Custom labels for form fields (see Form Labels)
placeholders object - Custom placeholder text for form inputs (see Form Placeholders)
styles object - Custom styles for UI components (see Styling section)
View Interface Definition
interface IEnrollmentCustomizationOptions {
  paymentButton?: {
    show?: boolean;
    text?: string;
  };
  showMessages?: boolean;
  labels?: IFormLabels;
  placeholders?: IFormPlaceholder;
  styles?: IStyles;
}

Form Labels & Placeholders

These options allow you to customize the text of the labels and placeholders for the form fields.

Note: For the Lite version, you can pass the respective values directly when using Tonder's inputs.

Form Labels

Customization of field labels:

Property Type Default Description
name string "Titular de la tarjeta" Label for the cardholder's name field.
cardNumber string "NĂşmero de tarjeta" Label for the card number field.
cvv string "CVV" Label for the security code field.
expiryDate string "Fecha de expiraciĂłn" Label for the expiration date fields.
saveCardFuturePayment string "Guardar tarjeta para futuros pagos" Label for the save card for future payments.
saveCardCheckedIcon string "âś“" Label for checked icon of the save card for future payments checkbox.
expirationCard string "Exp." Label for the expiration card text.
payWithCard string "Pagar con tarjeta" Label for pay with card option.
View Form Labels Interface
interface IFormLabels {
 name?: string;
 cardNumber?: string;
 cvv?: string;
 expiryDate?: string;
 saveCardFuturePayment?: string;
 saveCardCheckedIcon?: string;
 expirationCard?: string;
 payWithCard?: string;
}

Form Placeholders

Customization of field placeholder:

Property Type Default Description
name string "Nombre como aparece en la tarjeta" Placeholder for the cardholder's name field.
cardNumber string "1234 1234 1234 1234" Placeholder for the card number field.
cvv string "3-4 dĂ­gitos" Placeholder for the security code field.
expiryMonth string "MM" Placeholder for the expiration month field.
expiryYear string "AA" Placeholder for the expiration year field.
View Form Placeholders Interface
interface IFormPlaceholder {
 name?: string;
 cardNumber?: string;
 cvv?: string;
 expiryMonth?: string;
 expiryYear?: string;

}

Components

Pre-built Components

The SDK provides two main pre-built components for full integrations:

  • TonderPayment: Complete payment form with built-in card management, payment methods, and validations (INLINE)
  • TonderEnrollment: Complete card enrollment form for saving cards (ENROLLMENT)

Individual Components

All individual components are available for LITE integrations. Each component includes built-in validations and secure data handling:

  • CardCVVInput
  • CardHolderInput
  • CardNumberInput
  • CardExpirationDateInput
  • CardExpirationMonthInput
  • CardExpirationYearInput

Individual Components Props

All individual components accept the following props:

Prop Type Required Available In Description
label string No All components Label text to display above the input
placeholder string No All components Placeholder text for the input field
style object No All components Custom styling for the input component
onChange function No All components Callback function triggered when the input value changes
onFocus function No All components Callback function triggered when the input receives focus
onBlur function No All components Callback function triggered when the input loses focus
cardId string No CardCVVInput only The Skyflow ID of a saved card. When provided, the CVV input will update the CVV for that specific saved card. This is useful when working with saved cards that may have dynamic CVVs that change over time.

Use Case for cardId prop (CardCVVInput only):

When displaying a list of saved cards in the LITE SDK, you may need to capture the CVV again for security purposes. By passing the cardId prop to the CardCVVInput component, the CVV input will be associated with that specific card, allowing you to update its CVV. This is particularly important for dynamic cards where the CVV may change periodically.

⚠️ Important Notes:

  1. Single Card Selection Only: The CardCVVInput component with cardId must only be displayed when a specific card is selected. It should be conditionally rendered based on the user's card selection.

  2. One CVV Input at a Time: You cannot display multiple CardCVVInput components with different cardId values simultaneously. Only one CVV update operation should be active at any given time.

  3. Mutually Exclusive with Card Form: The CardCVVInput with cardId cannot be shown at the same time as the full card enrollment form (CardNumberInput, CardholderNameInput, CardCVVInput without cardId, CardExpirationMonthInput, CardExpirationYearInput). These are two separate workflows:

    • Save New Card: Use the complete card form without cardId
    • Update CVV for Saved Card: Use CardCVVInput with cardId only

Example:

// Update CVV for a saved card
<CardCVVInput
  cardId="saved-card-skyflow-id"
  placeholder="Enter CVV"
/>

API Reference

Hook: useTonder

The SDK provides a custom hook for accessing SDK functionality based on the integration type.

const sdk = useTonder<SDKType>();

Common Methods

All SDK integrations (INLINE, LITE, ENROLLMENT) share these base methods:

  • create: Initializes the SDK with configuration.
  • reset: Resets the SDK state to its initial values and cleans up resources.
const {create, reset} = useTonder<SDKType>();

INLINE SDK Methods

The INLINE integration provides methods for handling full payment processing with built-in UI components.

  • payment: Processes a payment using the configured payment data.
const {create, payment, reset } = useTonder<SDKType.INLINE>();

Note: The payment function It is only necessary when you want to control the payment button on your own. Additionally, if there are any changes to the payment or customer data, you can pass the updated data again when calling the function.

Note: For card methods, it is necessary to obtain and use your secure token when calling the create function.

Example with custom payment button

export default function FullPaymentButtonScreen() {
  const { create, payment } = useTonder<SDKType.INLINE>();

  useEffect(() => {
    createSDK()
  }, [])

  const createSDK = async () => {
    const { error } = await create({
      secureToken: 'your-secure-token',
      paymentData: { ...paymentData },
      customization: {
        paymentButton: {
          show: false, // hide default button
        },
      },
    });

    if (error) {
      // Manage error
      console.error('Error creating SDK', error);
    }
  };

  const handlePayment = async () => {
    const { response, error } = await payment();

    if (error) {
      console.error('Error payment: ', error);
      return;
    }
    console.log('Response payment: ', response);
  };

  return (
    <SafeAreaView>
      <ScrollView>
        <TonderPayment />
        {/*Custom button*/}
        <TouchableOpacity onPress={handlePayment}>
           <Text>Pagar</Text>
        </TouchableOpacity>
      </ScrollView>
    </SafeAreaView>
  );
}

LITE SDK Methods

The LITE integration provides full control over the payment flow with individual components and direct access to all SDK functionalities.

  • payment: Processes a payment using the configured payment data.
  • saveCustomerCard: Tokenizes and saves the current card information.
  • getCustomerCards: Retrieves the list of saved cards for the customer.
  • getCardSummary: Retrieves detailed information about a saved card using its Skyflow ID.
  • getPaymentMethods: Retrieves available payment methods.
  • removeCustomerCard: Deletes a saved card.

Note: If there are any changes to the payment or customer data, you can pass the updated data again when calling the payment function**.

Note: For card methods, it is necessary to obtain and use your secure token when calling the create function.

const { create, payment, saveCustomerCard, getCustomerCards, getCardSummary,
        removeCustomerCard, getPaymentMethods, reset } = useTonder<SDKType.LITE>();

Enrollment SDK Methods

The ENROLLMENT integration provides methods for handling full enrollment with built-in UI components.

  • saveCustomerCard: Tokenizes and saves the current card information.

  • getCardSummary: Retrieves detailed information about a saved card using its Skyflow ID.

    Input Interface
    Parameter Type Description
    skyflowId string The Skyflow ID of the card to retrieve
    Response Interface

    IBaseResponse

    The response follows the base response pattern:

    export type IBaseResponse<T> =
      | { response: ICardsSummaryResponse; error?: TonderError }
      | { response?: never; error: TonderError };

    Success Response (ICardsSummaryResponse)

    Property Type Description
    user_id number The ID of the user who owns the card
    card object Object containing the card fields

    Card Fields (ICardSkyflowFields)

    Property Type Description
    card_number string The masked card number
    expiration_month string The expiration month of the card
    expiration_year string The expiration year of the card
    skyflow_id string The unique Skyflow identifier for the card
    card_scheme string The card brand (e.g., Visa, Mastercard)
    cardholder_name string The name of the cardholder

Note: The saveCustomerCard It is only necessary when you want to control the enrollment button on your own.

Note: For card methods, it is necessary to obtain and use your secure token when calling the create function.

const { create, saveCustomerCard, getCardSummary, reset } = useTonder<SDKType.ENROLLMENT>();

Events

The SDK provides event handling capabilities for card form input fields, supporting both Full/Enrollment SDK and Lite SDK implementations.

Note: Values of TonderInputs will be returned in element state object only in Develop environment, but in case of CARD_NUMBER type element when the environment is production for all the card types except AMEX, it will return first eight digits, for AMEX it will return first six digits and rest all digits in masked format.

Event Types

Each event object supports:

  • onChange: Called when input value changes
  • onFocus: Called when input receives focus
  • onBlur: Called when input loses focus
View Interface
export interface IEvents {
  onChange?: (event: IEventSecureInput) => void;
  onFocus?: (event: IEventSecureInput) => void;
  onBlur?: (event: IEventSecureInput) => void;
}

Input event properties

Property Type Description
elementType string Type of input element (e.g. 'CARDHOLDER_NAME', 'CARD_NUMBER', 'EXPIRATION_YEAR', 'EXPIRATION_MONTH', 'CVV')
isEmpty boolean Whether the input field has a value
isFocused boolean Whether the input field currently has focus
isValid boolean Whether the input value passes validation rules
value string Current value of the input field
View Interface
export interface IEventSecureInput {
  elementType: string;
  isEmpty: boolean;
  isFocused: boolean;
  isValid: boolean;
  value: string;
}

Full/Enrollment SDK Events

Events are configured during SDK initialization.

Available Events

Event Object Description
cardHolderEvents Events for cardholder name input
cardNumberEvents Events for card number input
cvvEvents Events for CVV input
monthEvents Events for expiration month input
yearEvents Events for expiration year input
View Interface
export interface IEvents {
  cardHolderEvents?: IEvents;
  cardNumberEvents?: IEvents;
  cvvEvents?: IEvents;
  monthEvents?: IEvents;
  yearEvents?: IEvents;
}

Example

const { create } = useTonder<SDKType.INLINE>();

const { error } = await create({
  secureToken: 'your-secure-token',
  paymentData: { ...paymentData },
  events: {
    cardHolderEvents: {
      onChange: (event) => console.log('Card holder changed:', event),
      onFocus: (event) => console.log('Card holder focused:', event),
      onBlur: (event) => console.log('Card holder blurred:', event)
    },
    cardNumberEvents: {
      onChange: (event) => console.log('Card number changed:', event)
    }
    // ... other input events
  }
});

Lite SDK Events

For Lite SDK implementations, events are passed directly to individual input components.

View Interface
export interface InputProps extends IEvents {
  label?: string;
  placeholder?: string;
  style?: IElementStyle;
}

Example

  <CardHolderInput
    onChange={(event) => console.log('Card holder changed:', event)}
    onFocus={(event) => console.log('Card holder focused:', event)}
    onBlur={(event) => console.log('Card holder blurred:', event)}
  />

  <CardNumberInput
    onChange={(event) => console.log('Card number changed:', event)}
  />

Styling

The SDK provides flexible styling options to customize the appearance of the components.

Note: For the Lite version, you can pass the respective values directly when using Tonder's inputs.

View Interface
export interface IStyles {
  sdkCard?: StylesBaseVariant;
  cardForm?: StylesBaseVariant & IElementStyle;
  paymentMethods?: StylesSelectVariant;
  savedCards?: StylesSavedCardsVariant;
  paymentRadio?: StylesSelectVariant;
  paymentButton?: StylesBaseVariant;
  errorMessage?: StylesBaseVariant;
  successMessage?: StylesBaseVariant;
}

Inline & Enrollment Styling

The style customization for Full integrations (INLINE and ENROLLMENT) is done through a styles object in the SDK configuration.

Component Description Properties
sdkCard Main container of the SDK base: StylesBaseVariant
cardForm Card form section - base: StylesBaseVariant
- inputStyles: CollectInputStylesVariant
- labelStyles: CollectInputStylesVariant
- errorStyles:StylesBaseVariant
- saveCardOption:StylesCheckboxVariant
savedCards Saved cards list section - base: StylesBaseVariant
- radioBase: StylesBaseVariant
- radioInner: StylesBaseVariant
- radioSelected: StylesBaseVariant
- cardIcon: StylesBaseVariant
- deleteButton: StylesBaseVariant
-deteleIcon: StylesBaseVariant
paymentMethods Payment methods section - base: StylesBaseVariant
- radioBase: StylesBaseVariant
- radioInner: StylesBaseVariant
- radioSelected: StylesBaseVariant
paymentRadio Payment method selector - base: StylesBaseVariant
- radioBase: StylesBaseVariant
- radioInner: StylesBaseVariant
- radioSelected: StylesBaseVariant
paymentButton Payment button base: StylesBaseVariant
errorMessage Error message display base: TextStyle
successMessage Success message display base: TextStyle
skeletonCard Skeleton - base: StylesBaseVariant
- fullField: StylesBaseVariant
- compactField: StylesBaseVariant
- compactRow: StylesBaseVariant
- animatedBGColors: [string, string]

Full customization example

const styles = {
  sdkCard: {
    base: {
      backgroundColor: '#f9f9f9',
      borderRadius: 10,
      padding: 16,
      boxShadow: '0px 4px 12px rgba(0, 0, 0, 0.1)',
    },
  },
  cardForm: {
    base: {
      backgroundColor: '#ffffff',
      borderRadius: 10,
      padding: 16,
      borderWidth: 1,
      borderColor: '#e3e3e3',
      marginVertical: 8,
    },
    inputStyles: {
      base: {
        borderWidth: 1,
        borderColor: '#cccccc',
        borderRadius: 6,
        padding: 12,
        fontSize: 16,
        marginBottom: 10,
        color: '#333',
      },
    },
    labelStyles: {
      base: {
        fontSize: 14,
        color: '#666',
        marginBottom: 6,
      },
    },
    saveCardOption: {
      base: {
        marginTop: 15,
        color: '#4a4a4a',
      },
      checkboxBase: {
        borderColor: '#4a4a4a',
      },
      checkboxCheckedBase: {
        backgroundColor: '#35c6c1',
      },
      checkedIcon: {
        color: '#2c2929',
      },
    },
  },
  savedCards: {
    base: {
      backgroundColor: '#f9f9f9',
      borderRadius: 8,
      padding: 10,
      marginVertical: 6,
      borderWidth: 1,
      borderColor: '#e3e3e3',
    },
    cardItem: {
      base: {
        borderBottomColor: '#e2e8f0',
      },
    },
  },
  paymentRadio: {
    base: {
      flexDirection: 'row',
      alignItems: 'center',
      padding: 10,
      backgroundColor: '#f9f9f9',
      borderRadius: 8,
      borderWidth: 1,
      borderColor: '#e3e3e3',
    },
  },
  paymentButton: {
    base: {
      backgroundColor: '#007AFF',
      paddingVertical: 15,
      paddingHorizontal: 20,
      borderRadius: 8,
      alignItems: 'center',
      fontSize: 18,
      color: '#fff',
      fontWeight: '600',
    },
  },
  paymentMethods: {
    base: {
      paddingVertical: 10,
      backgroundColor: '#f9f9f9',
    },
    radioBase: {
      width: 20,
      height: 20,
      borderRadius: 10,
      borderWidth: 2,
      borderColor: '#007AFF',
      marginHorizontal: 10,
    },
  },
  successMessage: {
    base: {
      color: '#28a745',
      fontWeight: '600',
      fontSize: 16,
      textAlign: 'center',
      marginTop: 20,
    },
  },
  errorMessage: {
    base: {
      color: '#9a0832',
      fontWeight: '600',
      fontSize: 16,
      textAlign: 'center',
      marginTop: 20,
    },
  },
  skeletonCard: {
    base: {
      backgroundColor: '#F9F9F9',
    },
    fullField: {
      base: {
        borderRadius: 8,
      },
    },
    animatedBGColors: ['#e0e0e0', '#c8c7c7'],
  },
};

const { create } = useTonder<SDKType.INLINE>();

 const { error } = await create({
      secureToken: 'your-secure-token',
      paymentData: { ...paymentData },
      customization: {
        saveCards: {
          showSaveCardOption: true,
          showSaved: true,
        },
        paymentButton: {
          show: true,
          showAmount: false,
        },
        labels: {
          name: 'Cardholder Name',
          cvv: 'CVV',
          cardNumber: 'Card Number',
          expiryDate: 'Expiration Date',
        },
        placeholders: {
          cvv: '123',
          name: 'John Doe',
          cardNumber: '4242 4242 4242 4242',
          expiryMonth: 'MM',
          expiryYear: 'YY',
        },
        styles: styles,
      },
      callbacks: {
        onFinishPayment: callbackFinish,
      },
    });

Lite Styling

The individual components of the LITE integration accept custom styles through the style prop. Each component can be styled independently

View Interface
export interface InputProps {
  label?: string;
  placeholder?: string;
  style?: IElementStyle;
}
interface IElementStyle {
  inputStyles: {
    base?: ViewStyle & TextStyle;
    focus?: Record<string, any>;
    complete?: Record<string, any>;
    invalid?: Record<string, any>;
    empty?: Record<string, any>;
    container?: Record<string, any>;
  };
  labelStyles: {
    base?: TextStyle;
    requiredAsterisk?: Record<string, any>;
    focus?: Record<string, any>;
  };
  errorStyles?: {
    base: TextStyle;
  };
}

Lite customization example

  <CardNumberInput
    placeholder="1234 5678 9012 3456"
    style={{
      inputStyles,
      labelStyles,
      errorStyles
    }}
  />

const inputStyles = {
  base: {
    backgroundColor: 'transparent',
    borderBottomColor: '#cbd5e1',
    borderBottomWidth: 1,
    paddingVertical: 8,
    fontSize: 16,
    color: '#111827',
    marginBottom: 15,
  },
  focus: {
    borderBottomColor: '#0ea5e9',
    boxShadow: '0 0 0 4px rgba(14, 165, 233, 0.2)',
  },
};

const labelStyles = {
  base: {
    fontSize: 14,
    color: '#6b7280',
    marginBottom: 5,
  },
};

const errorStyles = {
  base: {
    color: '#ef4444',
    fontSize: 12,
    marginTop: 4,
  },
};

Examples

Check the /example directory in the repository for complete implementation examples:

  • Full Payment Implementation
  • Lite Payment Implementation
  • Card Enrollment Implementation
  • Examples with custom configurations and styles

About

Tonder react native SKD

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •