Tokenization Forms

Learn how to use Tokenization Forms to securely accept payment details of your buyers.


Token Forms

Use Tokenization Forms to collect and tokenize the payment details of buyers. Our Tokenization Form offers a low-code solution to easily take in credit card and bank data and tokenize in a PCI compliant way.

Finix's Tokenization Forms, includes functionality to:

  • Show and hide specific fields
  • Customize labels and placeholders
  • Modify error messages to match your writing style
  • Control input styling within and outside of the Tokenization Form
  • Accept both and ACH in the same form

Examples

React Example

The example below uses our CardTokenForm with minimal styling and Finix's submit button. You can update the CSS and which fields you want to show.

HTML Example

The example below uses our TokenForm that allows you to tokenize card or bank accounts. In this example, we include a number of different styling options you can use in HTML, React, vanilla javascript, and more.

Library

There are three Tokenization Forms available:

  • A TokenForm to accept both card numbers and bank accounts.
  • A CardTokenForm to only accept credit or debit cards.
  • A BankTokenForm to only accept a routing and account number.
Every Tokenization Form uses a versioned finix.js JavaScript library to secure sensitive card and bank account data. Having buyers input their data into a Tokenization Form prevents third parties from accessing the submitted information.

Once initialized, the library communicates the state of the form through a JavaScript callback. The state object includes logic that validates the payment details submitted by the buyer.

See the following for examples of how to use our Tokenization Forms to tokenize payment details. You can build your own form by editing the various elements:

Tokenization Form ExamplesLibrary NameDescription
Tokenization FormTokenFormAccept bank account details, a debit card, or a credit card.
Debit and Credit CardsCardTokenFormAccept credit or debit cards.
Bank AccountsBankTokenFormAccept bank account details, including account number and routing number.
Minimal Versions

For your convience, here are minimal versions of the Tokenization Forms without any comments:

Tokenization Form ExamplesLibrary NameDescription
Tokenization Form - MinimalTokenFormAccept bank account details, a debit card, or a credit card.
Debit and Credit Card - MinimalCardTokenFormAccept credit or debit cards.
Bank Accounts - MinimalBankTokenFormAccept bank account details, including account number and routing number.

Step 1: Add finix.js Library

First, we'll need to add the finix.js library to the webpage hosting the form that collects payment details.

To add the library, include the following the script:

Copy
Copied
 <script type="text/javascript" src="https://js.finix.com/v/1/finix.js"></script>
Using this URL will automatically update the finix.js library to the latest V1 version.

Versioning

You can set a specific version of the finix.js library for your form to lock to.To specify a finix.js library version to use, update the url to your desired version. This example uses V1.0.5 of the finix.js library:
Copy
Copied
 <script type="text/javascript" src="https://js.finix.com/v/1/0/5/finix.js"></script>

Step 2: Initialize the Tokenization Form

Initialize the form with:

TokenFormCardTokenFormBankTokenForm
Copy
Copied
const form = window.Finix.TokenForm("form-elements", options);
Copy
Copied
const form = window.Finix.CardTokenForm("form-elements", options);
Copy
Copied
const form = window.Finix.BankTokenForm("form-elements", options);

Step 3: Define Input Fields

Next, define and customize what exact fields will be included and required in the Tokenization Form.

attention

Requesting an address in your Tokenization Form can lower interchange on credit card transactions.

Aspects of the input fields you can change include:

FieldTypeDescription
showAddressbooleanShow address fields in the form (default is false).
showLabelsbooleanShow labels in the form (default is true).
labelsobjectSet custom labels for each field.
showPlaceholdersbooleanTurn on or off placeholder text in the fields (default is true).
placeholdersobjectSet custom placeholders for each field.
hidefieldsarray<string>Specify which fields to hide.
requiredFieldsarray<string>Require any specific fields that are not required by default.
hideErrorMessagesbooleanIf you want to require a field, but not hide input error messages (default is false).
errorMessagesobjectSet custom error messages for each field if you are showing error messages.
Copy
Copied
const options = {
  showAddress: true,   // show address fields in the form (default is false)
  showLabels: true,  //show labels in the form (default is true)
  labels: {   // set custom labels for each field
    name: "Cardholder Name", // Supported Fields: "name", "number", "expiration_date", "security_code", "address_line1", "address_line2", "address_city", "address_state", "address_region", "address_country", "address_postal_code"
  },
  showPlaceholders: true,   // turn on or off placeholder text in the fields (default is true)
  placeholders: {   // set custom placeholders for each field, you can specify them here
    // Supported Fields: "name", "number", "expiration_date", "security_code", "address_line1", "address_line2", "address_city", "address_state", "address_region", "address_country", "address_postal_code"
    name: "Cardholder Name",
  },
  hideFields: [   // set custom placeholders for each field, you can specify them here
  ], // Fields avaiblae to hide: "name", "security_code", "address_line1", "address_line2", "address_city", "address_state", "address_region", "address_country", "address_postal_code", "address_country"
  requiredFields: [   // require any specific fields that are not required by default, you can specify them here
    "name",
    "address_line1",
    "address_city",
    "address_state",
    "address_region",
    "address_country",
    "address_postal_code",
  ], // Supported Fields: "name", "address_line1", "address_line2", "address_city", "address_state", "address_region", "address_country", "address_postal_code"
  hideErrorMessages: false,   // if you want to require a field, but not hide input error messages (default is false)
  errorMessages: {   // set custom error messages for each field if you are showing error messages
    name: "Please enter a valid name", // Supported Fields: "name", "number", "expiration_date", "security_code", "address_line1", "address_line2", "address_city", "address_state", "address_region", "address_country", "address_postal_code"
    address_city: "Please enter a valid city",
  },

Step 4: Style Tokenization Form

Style the Tokenization Form with your brand identity and colors.

Styling you can change includes:

FieldDescription
colorColor of the fields.
borderBorder of the fields.
borderRadiusRounding of the fields' border.
paddingSpacing inside the field.
fontSizeSize of the font used by the fields.
boxShadowShadow of the fields.
successStyling if the value entered is valid.
errorStyling if the value entered is invalid and can't be accepted.
Copy
Copied
  styles: {    // default styling for all fields
    default: {
      color: "#000",
      border: "1px solid #CCCDCF",
      borderRadius: "8px",
      padding: "8px 16px",
      fontFamily: "Helvetica",
      fontSize: "16px",
      boxShadow: "0px 1px 1px rgba(0, 0, 0, 0.03), 0px 2px 4px rgba(0, 0, 0, 0.03)",
    },
    success: {     // specific styling if the field is valid
      color: "#5cb85c",
    },
    error: {
      color: "#d9534f",    // specific styling if the field has errors
      border: "1px solid rgba(255,0,0, 0.3)",
    },
  },

Step 5: Submit Payload and Handle Response

We'll also need to configure what happens when the buyer submits the form. Specifically, the form needs to:

  • Register a click event that fires when the buyer submits their information.
  • Define a callback for handling the response.
Create a function that submits the form and handles the response. Include your Application ID so the library submits the field values under your account during the executed POST request.
Copy
Copied
const onSubmit = () => {
  form.submit("sandbox", "APgPDQrLD52TYvqazjHJJchM", function (err, res) {  // call the form submit function and supply the environment and application ID to submit under
    const tokenData = res.data || {};
    const token = tokenData.id;
  });  
}
This onSubmit function can either be:
  • Passed to the Form options object to automatically create a submit button.
  • Added to a custom submit button. You can do this by adding a click event handler to your custom button that calls this onSubmit function.

Arguments

FieldTypeDescription
environmentstring, requiredsandbox for testing and live for live environments
applicationIdstring, requiredApplication id that the payment card will be scoped to
callbackfunction, requiredCallback that will be executed when the HTTPRequest is finished.
Once you've handled the response, store the ID to utilize the token in the future. To do this, send the token ID from your front-end client to your back-end server.
Copy
Copied
    const tokenData = res.data || {};     // get token ID from response
    const token = tokenData.id;

    alert("Your token ID is: " + token);
    console.log(tokenData);
  });
}

Fraud Detection

We recommend also collecting a fraud_session_id to detect and block potentially fraudulent payments.

For more information, see Fraud Detection.

Step 6: Create an Identity for the Buyer

Before you can use the newly tokenized card or bank account, you'll need to:

  • Create an Identity for the buyer.
  • Create a Payment Instrument with the created Identity.
You can create an Identity with minimal or no information.
  • To avoid asking for the same info multiple times, you don't need to request additional information from the buyer when creating an Identity.
  • You don't need to create an additional Identity for the buyer if one already exists.
To create an Identity, make a POST request with whatever details you've gathered (e.g. name, email, phone, etc.) or create an empty Identity by leaving the entity empty.
Copy
Copied
curl https://finix.sandbox-payments-api.com/identities \
    -H "Content-Type: application/json" \
    -H 'Finix-Version: 2022-02-01' \
    -u  USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \
    -d '
        {
          "entity": {
          }
        }'

HTTP Request

POST https://finix.sandbox-payments-api.com/identities

Request Arguments

FieldTypeDescription
citystring, optionalCity (max 20 characters)
countrystring, optional3-Letter Country code
emailstring, optionalEmail address
first_namestring, optionalFirst name
last_namestring, optionalLast name
line1string, optionalFirst line of the address (max 35 characters)
line2string, optionalSecond line of the address (max 35 characters)
phonestring, optionalPhone number
postal_codestring, optionalZip or Postal code (max 7 characters)
regionstring, optional2-letter State code
tagsobject, optionalKey value pair for annotating custom metadata (e.g. order numbers)

Example Response

Copy
Copied
{
  "id" : "ID4KUMjzTggPzmCbvRUryQpE",
  "created_at" : "2023-01-03T18:56:30.40Z",
  "updated_at" : "2023-01-03T18:56:30.40Z",
  "application" : "APgPDQrLD52TYvqazjHJJchM",
  "entity" : {
    "amex_mid" : null,
    "annual_card_volume" : 0,
    "business_address" : null,
    "business_name" : null,
    "business_phone" : null,
    "business_tax_id_provided" : false,
    "business_type" : null,
    "default_statement_descriptor" : null,
    "discover_mid" : null,
    "dob" : null,
    "doing_business_as" : null,
    "email" : null,
    "first_name" : null,
    "has_accepted_credit_cards_previously" : false,
    "incorporation_date" : null,
    "last_name" : null,
    "max_transaction_amount" : 0,
    "mcc" : null,
    "ownership_type" : null,
    "personal_address" : {
      "line1" : null,
      "line2" : null,
      "city" : null,
      "region" : null,
      "postal_code" : null,
      "country" : null
    },
    "phone" : null,
    "principal_percentage_ownership" : null,
    "short_business_name" : null,
    "tax_authority" : null,
    "tax_id_provided" : false,
    "title" : null,
    "url" : null
  },
  "tags" : { },
  "_links" : {
    "self" : {
      "href" : "https://finix.sandbox-payments-api.com/identities/ID4KUMjzTggPzmCbvRUryQpE"
    },
    "verifications" : {
      "href" : "https://finix.sandbox-payments-api.com/identities/ID4KUMjzTggPzmCbvRUryQpE/verifications"
    },
    "merchants" : {
      "href" : "https://finix.sandbox-payments-api.com/identities/ID4KUMjzTggPzmCbvRUryQpE/merchants"
    },
    "settlements" : {
      "href" : "https://finix.sandbox-payments-api.com/identities/ID4KUMjzTggPzmCbvRUryQpE/settlements"
    },
    "authorizations" : {
      "href" : "https://finix.sandbox-payments-api.com/identities/ID4KUMjzTggPzmCbvRUryQpE/authorizations"
    },
    "transfers" : {
      "href" : "https://finix.sandbox-payments-api.com/identities/ID4KUMjzTggPzmCbvRUryQpE/transfers"
    },
    "payment_instruments" : {
      "href" : "https://finix.sandbox-payments-api.com/identities/ID4KUMjzTggPzmCbvRUryQpE/payment_instruments"
    },
    "associated_identities" : {
      "href" : "https://finix.sandbox-payments-api.com/identities/ID4KUMjzTggPzmCbvRUryQpE/associated_identities"
    },
    "disputes" : {
      "href" : "https://finix.sandbox-payments-api.com/identities/ID4KUMjzTggPzmCbvRUryQpE/disputes"
    },
    "application" : {
      "href" : "https://finix.sandbox-payments-api.com/applications/APgPDQrLD52TYvqazjHJJchM"
    }
  }
}
You can update this Identity at a later time with a PUT request that uses the information in the Payment Instrument you create with the token.

Step 7: Create a Payment Instrument

Create a Payment Instrument by making a POST request to /payment_instrument with the relevant token and the Identity#id created for the buyer.
warning
Tokens should be used to create a Payment Instrument right away. Tokens that don't get connected within 30 mins of creation expire and can't be used.
Copy
Copied
curl https://finix.sandbox-payments-api.com/payment_instruments \
    -H "Content-Type: application/json" \
    -H 'Finix-Version: 2022-02-01' \
    -u  USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \
    -d '
        {
            "token": "TKghUufLdh4QQ96CBi928HP3",
            "type": "TOKEN",
            "identity": "ID4KUMjzTggPzmCbvRUryQpE"
        }'

HTTP Request

POST https://finix.sandbox-payments-api.com/payment_instruments

Request Arguments

FieldTypeDescription
addressobject, requiredBilling address (Full description of child attributes below)
Note: Including a postal or zip code when creating a Payment Instrument can lower the interchange on credit card transactions
identitystring, requiredID for the Identity resource which the account is to be associated
namestring, requiredFull name of the registered card holder
tokenstring, requiredID for the Token that was returned via the tokenization client
typestring, requiredMust pass TOKEN as the value

Address-object Request Arguments

FieldTypeDescription
citystring, optionalCity (max 20 characters)
countrystring, optional3-Letter Country code
line1string, optionalFirst line of the address (max 35 characters)
line2string, optionalSecond line of the address (max 35 characters)
postal_codestring, requiredZip or Postal code (max 7 characters)
regionstring, optional2-letter State code

Example Response:

Copy
Copied
{
  "id" : "PImmCg3Po7oNi7jaZcXhfkEu",
  "created_at" : "2022-10-10T05:32:17.78Z",
  "updated_at" : "2022-10-10T05:35:04.55Z",
  "application" : "APgPDQrLD52TYvqazjHJJchM",
  "created_via" : "API",
  "currency" : "USD",
  "enabled" : true,
  "fingerprint" : "FPRiCenDk2SoRng7WjQTr7RJY",
  "identity" : "ID4KUMjzTggPzmCbvRUryQpE",
  "instrument_type" : "PAYMENT_CARD",
  "address" : {
    "line1" : "900 Metro Center Blv",
    "line2" : null,
    "city" : "San Francisco",
    "region" : "CA",
    "postal_code" : "94404",
    "country" : "USA"
  },
  "address_verification" : "POSTAL_CODE_AND_STREET_MATCH",
  "bin" : "520082",
  "brand" : "MASTERCARD",
  "card_type" : "DEBIT",
  "expiration_month" : 12,
  "expiration_year" : 2029,
  "issuer_country" : "NON_USA",
  "last_four" : "8210",
  "name" : "Amy White",
  "security_code_verification" : "MATCHED",
  "tags" : {
    "card_name" : "Business Card"
  },
  "type" : "PAYMENT_CARD",
  "_links" : {
    "self" : {
      "href" : "https://finix.sandbox-payments-api.com/payment_instruments/PImmCg3Po7oNi7jaZcXhfkEu"
    },
    "authorizations" : {
      "href" : "https://finix.sandbox-payments-api.com/payment_instruments/PImmCg3Po7oNi7jaZcXhfkEu/authorizations"
    },
    "transfers" : {
      "href" : "https://finix.sandbox-payments-api.com/payment_instruments/PImmCg3Po7oNi7jaZcXhfkEu/transfers"
    },
    "verifications" : {
      "href" : "https://finix.sandbox-payments-api.com/payment_instruments/PImmCg3Po7oNi7jaZcXhfkEu/verifications"
    },
    "application" : {
      "href" : "https://finix.sandbox-payments-api.com/applications/APgPDQrLD52TYvqazjHJJchM"
    },
    "identity" : {
      "href" : "https://finix.sandbox-payments-api.com/identities/IDgWxBhfGYLLdkhxx2ddYf9K"
    },
    "updates" : {
      "href" : "https://finix.sandbox-payments-api.com/payment_instruments/PImmCg3Po7oNi7jaZcXhfkEu/updates"
    }
  }
}
The type of card that gets saved is detailed in card_type. Available values for Payment Instruments with type PAYMENT_CARD include:
  • CREDIT
  • DEBIT
  • HSA_FSA
  • NON_RELOADABLE_PREPAID
  • RELOADABLE_PREPAID
  • UNKNOWN
You can also update the buyer Identity with a PUT request using the information saved in the Payment Instrument.

Next Steps

With the Payment Instrument created, you can proceed with creating and capturing an Authorization or creating a Transfer.