The Tonder Flutter SDK Lite is a solution for integrating our system into your mobile application. This solution ensures PCI DSS (Payment Card Industry Data Security Standard) by securely collecting and tokenizing sensitive data in the browser, without exposing your front-end infrastructure to any sensitive data.

With the Lite SDK, you can create personalized designs and workflows to register your customers’ cards in the vault. This gives you with the flexibility to customize the registration process according to your business needs and preferences.

This guide will walk you through all the steps, from installation and configuring our SDK to fit your application.

Installation

Tonder’s Flutter SDK Lite can be installed using the following command, or by adding the dependency directly into your project:

flutter pub add tonder_sdk_lite

Requirements

To deploy to Android or MacOS you need to add the following:

To deploy to Android, you need to edit your AndroidManifest.xml file, adding the internet permission to it:

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

Configuration

With Tonder’s SDK installed, and requirements met, you are ready to configure and use our SDK. The following step-by-step process takes you through everything, from starting a new instance, to using the available methods:

1

Import the SDK into your file

You need to start by adding the import statement for the liteCheckout class in your file. Following you find an example of how to import the liteCheckout:

import 'package:tonder_sdk_lite/network/liteCheckout.dart';
2

Initialize Tonder's SDK Instance

Initialize the Tonder’s Flutter SDK instance with the following parameters:

FieldDescription
baseUrlTonderTonder’s API base URL.
-> Live server: https://stage.tonder.io
-> Mock Server: https://stoplight.io/mocks/tonder/tonder-api-v1-2/3152148
apiKeyTonderYour Tonder API key. You can find it in your Tonder dashboard.
const String baseUrlTonder = 'https://stage.tonder.io';
const String apiKeyTonder = '00d17d61e9240c6e0611fbdb1558e636ed6389db';

LiteCheckout sdkTonder = LiteCheckout(baseUrlTonder, apiKeyTonder);

Ensure all API keys and sensitive data are secured and not hardcoded in production applications. Use environment variables or a secure way to load such configurations.

3

Use the methods available

After initializing the SDK, you have at your disposal a set of methods, allowing you full control over the checkout process. Refer to the Class Methods section to learn more about each one.

Class Methods

After configuring your Lite Checkout instance, you have at your hand various methods to work with Tonder. Below you will find all the available methods, with an example of the data returned by each so you can understand how they work:

Get Business

This method retrieves all the information about your business. Get details on providers public keys, vault information, and more. To call it, do the following:

Future<GetBusinessResponse> getBusiness() async {
  GetBusinessResponse response = await sdkTonder.getBusiness();
  print(response);
}

Customer register

The customerRegister allows you to retrieve a customer’s authorization token by adding their email address as the only parameter to this method. To retrieve it, execute the following:

const String email = 'user@email.com';

Future<CustomerRegisterResponse> customerRegister(String email) async {
  CustomerRegisterResponse response = await sdkTonder.customerRegister(email);
  print(response);
}

Create order

To create a new order with the Lite SDK, use the createOrder method. This method requires an object as parameter with the following data:

FieldDescription
businessYour business’s API key.
clientAuthentication token for the client recovered with the customerRegister method.
billing_address_idID of the billing address (null if not available).
shipping_address_idID of the shipping address (null if not available).
amountTotal amount of the order.
statusStatus of the order.
referenceReference information for the order. Recovered with the getBusiness method.
is_oneclickBoolean indicating one-click order (true/false).
itemsList of items in the shopping cart.

Where each item has the following properties:

FieldDescription
descriptionA textual description of the item.
quantityThe quantity of the item.
price_unitThe price per unit of the item.
discountThe discount applied to the item, if any.
taxesThe taxes applicable to the item.
product_referenceA numerical reference or identifier for the item.
nameThe name of the item.
amount_totalThe total amount for the item, including taxes and discounts.

With the data, call the method like presented below:

CreateOrderRequest order = CreateOrderRequest(
  business: 'Business123',
  client: 'Client456',
  billingAddressId: 789,
  shippingAddressId: 1011,
  amount: 29.40,
  status: 'Pending',
  reference: 'Ref001',
  isOneclick: false,
  items: [
    OrderItem(
      description: 'A premium quality widget',
      quantity: 10,
      priceUnit: 2.99,
      discount: 0.5,
      taxes: 0.6,
      productReference: 987654,
      name: 'Widget',
      amountTotal: 29.40
    )
  ]
);

Future<CreateOrderResponse> createOrder(CreateOrderRequest order) async {
  CreateOrderResponse response = await sdkTonder.createOrder(order);
  print(response);
}

Create payment

To create a new payment with the Lite SDK, use the createPayment method. This method requires the following parameters:

FieldDescription
business_pkThe primary key or identifier for the business associated with the payment.
amountThe total amount of the payment.
dateThe date when the payment is made or processed.
orderThe identifier for the order associated with this payment.
CreatePaymentRequest paymentItems = CreatePaymentRequest(
  business_pk: 'Business123',
  amount: 789,
  date: '2024-04-10',
  order: 'Order456' 
);

Future<CreatePaymentResponse> createPayment(CreatePaymentRequest paymentItems) async {
  CreatePaymentResponse response = await sdkTonder.createPayment(paymentItems);
  print(response);
}

Start checkout router

The startCheckoutRouter method initiates the checkout process for the customer. This method requires the following to be added as parameter object:

Field NameDescription
cardCard details used in the transaction.
nameThe first name of the client or customer.
last_nameThe last name of the client or customer.
email_clientThe client’s email address.
phone_numberThe client’s phone number.
return_urlURL to which users should be redirected after payment.
id_productIdentifier for the product being purchased.
quantity_productOptional numerical value indicating the quantity of the product ordered.
id_shipIdentifier for the shipping information.
instance_id_shipIdentifier related to a specific instance of shipping.
amountThe total amount of the transaction.
title_shiptitle or name for the shipping method.
descriptionThe transaction or product details.
device_session_idDynamic field typically used for fraud prevention, identifying the device.
token_idToken associated with the payment method.
order_idThe order identifier.
business_idThe business identifier associated with the transaction.
payment_idThe payment identifier.
sourceThe source or origin of the transaction.

To call this method, use the example below:

StartCheckoutRequest routerData = StartCheckoutRequest(
    card: {
      'number': '4111111111111111',
      'expiryMonth': '08',
      'expiryYear': '24',
      'cvc': '123'
    },
    name: "John",
    last_name: "Doe",
    email_client: "johndoe@example.com",
    phone_number: "1234567890",
    return_url: "https://example.com/checkout/complete",
    id_product: "SKU123",
    quantity_product: 1,
    id_ship: "SHIP123",
    instance_id_ship: "SHIP_INSTANCE123",
    amount: 59.99,
    title_ship: "Standard Shipping",
    description: "A premium quality widget",
    device_session_id: "device1234567890",
    token_id: "token1234567890",
    order_id: "order1234567890",
    business_id: "business123",
    payment_id: "payment123",
    source: "web"
  );

Future<StartCheckoutResponse> startCheckoutRouter(StartCheckoutRequest routerData) async {
  StartCheckoutResponse response = await sdkTonder.startCheckoutRouter(routerData);
  print(response);
}

Get vault token

Use the getVaultToken to retrieve the vault credential that is required to register a customer’s card. Use the following example to call this method:

Future<GetVaultTokenResponse> getVaultToken() async {
  GetVaultTokenResponse response = await sdkTonder.getVaultToken();
  print(response);
}

Register customer card

Using the customer’s token and the skyflow id, you can register the customer’s card in the vault. The table below presents the required data, followed by an example call to the registerCustomerCard method:

Field NameDescription
customerTokenA token that uniquely identifies the customer. Used for authentication and access control.
data.skyflow_idAn identifier generated by Skyflow used to track or reference a customer in a secure and compliant way.
String customerToken = 'abc123XYZ789Token';

RegisterCustomerCardRequest data = RegisterCustomerCardRequest(
  skyflow_id: '01FGP5H38VZ4B9QPT4T9KJ8J22'
);

Future<RegisterCustomerCardResponse> registerCustomerCard(String customerToken, RegisterCustomerCardRequest data) async {
  RegisterCustomerCardResponse response = await sdkTonder.registerCustomerCard(customerToken, data);
  print(response);
}

Get customer cards

Use the getCustomerCards to retrieve all registered cards for the customer, allowing them to use a saved card to perform transactions. Below are the parameters to execute this call, followed by an example call to it:

FieldDescription
customerTokenA token that uniquely identifies and authenticates the customer making the request.
queryA query string used to specify and filter the details required, such as card type or status.
String customerToken = 'abc123XYZ789Token';
String query = 'status=active';

Future<GetCustomerCardsResponse> getCustomerCards(String customerToken, String query) async {
  GetCustomerCardsResponse response = await sdkTonder.getCustomerCards(customerToken, query);
  print(response);
}

Delete customer card

Use the deleteCustomerCard to delete any registered card for the customer, allowing them to removed a saved card from the system. Below are the parameters to execute this call, followed by an example call to it:

FieldDescription
customerTokenA token that uniquely identifies and authenticates the customer making the request.
skyflowIdAn optional identifier generated by Skyflow, used to specify which card should be deleted. If not provided, it defaults to an empty string.
String customerToken = 'abc123XYZ789Token';
String skyflowId = '01FGP5H38VZ4B9QPT4T9KJ8J22';

Future<GetCustomerCardsResponse> deleteCustomerCard({required String customerToken, String skyflowId = ''}) async {
  GetCustomerCardsResponse response = await sdkTonder.deleteCustomerCard(customerToken, skyflowId);
  print(response);
}

Get device session ID

Using the getOpenpayDeviceSessionID method, you can retrieve your device session id. This method requires you to add the following data to the parameter of the call:

Field NameDescription
merchant_idThe unique identifier for the merchant in the system.
public_keyThe public key associated with the merchant for transaction security.
production_modeOptional boolean indicating whether the system is in production mode or not. Defaults to null which might imply a test mode unless specified.
OpenpayKeys openpayKeys = OpenpayKeys(
  merchant_id: '1234567890abcdef',
  public_key: '9f24dk7a8s9d8f76b1a2c3d4e5f6g7h8as2',
  production_mode: true
)

Future<String?> getOpenpayDeviceSessionID(OpenpayKeys openpayKeys) async {
  String response = await sdkTonder.getOpenpayDeviceSessionID(openpayKeys);
  print(response);
}

The returned data will be your device’s session id.

3DS Verification

You can use the verify3dsTransaction() method to validate if a 3DS challenge was successful or not. Use the example below to call the method and handle the response as needed:

void verify3dsTransaction() async {
  try {
    final response = await inlineCheckout.verify3dsTransaction();
    print('Verify 3ds response: $response');

    if (response.transaction_status == 'Success') {
      _showAlert('3DS Transaction verified.');
      // Proceed with normal payment flow
    } else if (response.transaction_status == 'Failed') {
      _showAlert('3DS Transaction Failed');
    }
  } catch (error) {
    print('Error verifying 3DS transaction: $error');
    _showAlert('Error verifying 3DS transaction.');
  }
}