Secure Fields (Payment)

Below, we outline the step-by-step process to enable the Secure Fields checkout functionalities in your system:

Step 1: Include the library in your project.

The first step is to make sure to include the Yuno SDK file in your webpage before closing the <body> tag. See the example below:

<script src="https://sdk-web.y.uno/v1/static/js/main.min.js"></script>

Step 2: Initialize secure fields with the public key

In your JavaScript application, create an instance of the Yuno class by providing a valid PUBLIC_API_KEY. Check the Get your API credentials guide.

Like the example below, use the initialized class that is attributed to the yunoconstant.

const yuno = Yuno.initialize(PUBLIC_API_KEY)

Step 3: Start the checkout process

You will start the checkout process. To do it, use the secureFields function and provide the necessary configuration parameters.

The essential parameters are the countryCode, which determines the country for which the payment process is configured, and checkoutSession, which refers to the current payment's checkout session. The next code block presents an example of the parameter configuration.

The following table lists all required parameters and their descriptions.

ParameterDescription
countryCodeThis parameter determines the country for which the payment process is being configured. It should be set to one of the following country codes: CO, BR, CL, PE, EC, UR, or MX.
checkoutSessionRefers to the current payment's checkout session.
Example: '438413b7-4921-41e4-b8f3-28a5a0141638'
installmentsEnableThis parameter is optional and is set false by default. If set True, the installments set for the account will be shown as a secure field.
  const secureFields = yuno.secureFields({
    /**
     * country can be one of CO, BR, CL, PE, EC, UR, MX
     */
    countryCode: country,
     /**
     * Should be added her or in the token generation
     * @optional
     */
    checkoutSession,
    installmentEnable: false,
  })

Step 4: Mount the Secure Fields

After defining the parameters, you will define, configure, and mount the Secure Fields. For each Secure Field, you need to define the name and options when creating it with the secureFields.create function.

The table below presents all configurations available:

ParametersDescription
nameThe available names for field names are cvv, pan, or expiration.
options.placeholderDefault placeholder for the field.
options.stylesAdditional CSS styles for the current field.
options.labelField visible label.
options.showErrorDefines if errors will be shown. Available options are true and false.
options.onChangeAn auxiliary function that can be configured and will run when the field content changes. Indicates if the fields have errors or additional data.
options.onBlurAn auxiliary function that can be configured and will run when blurring from the input.
options.onFocusAn auxiliary function that can be configured and will run when focussing on the input.
options.errorMessageThis allows for the definition of the field's error message.

Once you have set the parameter, you will render the created Secure Field with the render function by selecting an HTML element using a valid CSS selector (#, ., [data-*]).

The next code block presents an example of the parameter configuration for three Secure Fields, and as they are mounted, the fields are presented to the user.

/**
   * interface SecureField {
   *  render(elementSelector: string): void
   * 
   *  clearValue(): void
   * 
   *  setError(errorMessage: string): void
   * 
   *  updateProps(args: Record<string, unknown>): void
   * 
   *  focus(): void
   * 
   *  validate(): void
   * 
   *  unmountSync(): Promise<void>
   * }
   */  
const secureNumber = secureFields.create({
    name: 'pan',
    options: {
      placeholder: '0000 0000 0000 0000',
      /**
       * you can edit card form styles
       * only you should write css then it will be injected into the iframe
       * example 
       * `@import url('https://fonts.googleapis.com/css2?family=Luckiest+Guy&display=swap');
       *  .Yuno-text-field__content.focus label.Yuno-text-field__label {
       *    color: red;
       *    font-family: 'Luckiest Guy' !important;
       *   }`
       */
      styles: ``,
      label: 'Card Number',
      showError: true,
      errorMessage: "Custom Error",
      onChange: ({ error,data }) => {
      /**
       * in data.installments you could receive an installments plan list information 
       regarding the installments plan set for your account and chosen by the customer
    		[{
            installmentId: string;
            installment: number;
            amount: {
                currency: string;
                value: string;
                total_value: string;
            } | undefined;
        }]
       */
        /**
       * in data.cardIIN you can receive card_data
    		[{
            "id": "436c457c-1234-4e5e-b51d-1814e67d696a",
            "iin": "411111",
            "scheme": "VISA",
            "issuer_name": "JPMORGAN CHASE BANK N A",
            "issuer_code": null,
            "brand": "VISA",
            "type": "CREDIT",
            "category": "CREDIT",
            "country_code": "US",
            "country_name": "United States of America",
            "website": "https://www.chase.com",
            "phone": {
                "country_code": null,
                "number": "+ (1) 212-270-6000"
            },
            "address": {
                "address_line_1": null,
                "address_line_2": null,
                "city": null,
                "country": null,
                "state": null,
                "zip_code": null
            }
        }]
       */
       /**
       * in data.isCardIINLoading you can receive a true or false indicating if the card iin search is being excecuted.
       */
       /**
       * in data.isInstallmentLoading you can receive a true or false indicating if the installments search is being excecuted.
       */
        if (error) {
          console.log('error_pan')
        } else {
          console.log('not_error_pan')
        }
      },
      onBlur() {
        console.log('blur_pan')
      },
      onFocus: () => {
        console.log('focus_pan')
      }
    },
  })

  secureNumber.render('#pan')

  const secureExpiration = secureFields.create({
    /**
     * Fields name, can be 'cvv' | 'pan' | 'expiration'
     */
    name: 'expiration',
    // All options are optional
    options: {
      placeholder: 'MM / YY',
      /**
       * you can edit card form styles
       * only you should write css then it will be injected into the iframe
       * example 
       * `@import url('https://fonts.googleapis.com/css2?family=Luckiest+Guy&display=swap');
       *  .Yuno-text-field__content.focus label.Yuno-text-field__label {
       *    color: red;
       *    font-family: 'Luckiest Guy' !important;
       *   }`
       */
      styles: ``,
      label: 'Card Expiration',
      showError: true,
      // Indicates if the fields has error
      onChange: ({ error }) => {
        if (error) {
          console.log('error_expiration')
        } else {
          console.log('not_error_expiration')
        }
      },
      // Trigger when blurring from input
      onBlur() {
        console.log('blur_expiration')
      },
      // Trigger when focussing on input
      onFocus: () => {
        console.log('focus_expiration')
      }
    },
  })

  secureExpiration.render('#expiration')


  const secureCvv = secureFields.create({
    name: 'cvv',
    options: {
      placeholder: 'CVV',
      /**
       * you can edit card form styles
       * only you should write css then it will be injected into the iframe
       * example 
       * `@import url('https://fonts.googleapis.com/css2?family=Luckiest+Guy&display=swap');
       *  .Yuno-text-field__content.focus label.Yuno-text-field__label {
       *    color: red;
       *    font-family: 'Luckiest Guy' !important;
       *   }`
       */
      styles: ``,
      label: 'CVV',
      showError: true,
      onChange: ({ error }) => {
        if (error) {
          console.log('error_cvv')
        } else {
          console.log('not_error_cvv')
        }
      },
      onBlur() {
        console.log('blur_cvv')
      },
      onFocus: () => {
        console.log('focus_cvv')
      }
    },
  })

  secureCvv.render('#cvv')
  • Below you find a GIF showing how you can configure the Secure Fields:

Step 5: Generate an OTT (one-time token)

With all user information in hand, you can start the payment. First, you need to create a One-Time Token using the function secureFields.generateToken. As it is an asynchronous function, you can use try/catch to ensure you will correctly handle triggered errors. Below, you will find an example of creating a One-Time Token:

// Create One Time Token
// This will trigger an error if there are missing data
// You can catch it using a try/catch
const oneTimeToken = await secureFields.generateToken({
  // Optional: This parameter is used to indicate that a different checkout session is desired, 
  //rather than the one initially generated.
  //A use case is for the persistence of card data after a payment error.
  checkoutSession: '{{the checkout session id}}',
  // Required: You can create an input to get this formation
  cardHolderName: 'John Deer',
  // Optional: You can create an input to get this formation
  saveCard: true,
  /**
   * @optional
   */
  // Optional: only neccessary if an installments plan is created for the account
  installment: {
            id: string,
            value: number,
            amount: {
                currency: string,
                value: string,
                total_value: string,
            },
        },
  // Check your card processor to know if you need to send 
  // customer information
  // full object here https://docs.y.uno/reference/the-customer-object
  customer: {
    document: {
      document_number: '1090209924',
      document_type: 'CC',
    },
  },
  // This is useful for dual cards where the same card can be either used as credit or debit
  cardType: 'DEBIT' or 'CREDIT'
})

You can also use secureFields.generateTokenWithInformation to receive any additional info given by the customer in the checkout such as installments or document type/number.

// Create One Time Token
// This will trigger an error if there are missing data
// You can catch it using a try/catch
const oneTimeTokenWithInformation = await secureFields.generateTokenWithInformation({ 
  // Optional: This parameter is used to indicate that a different checkout session is desired, 
  //rather than the one initially generated.
  //A use case is for the persistence of card data after a payment error.
  checkoutSession: '{{the checkout session id}}',
  // Required: You can create an input to get this formation
  cardHolderName: 'John Deer',
  // Optional: You can create an input to get this formation
  saveCard: true,
  // Optional: only neccessary if an installments plan is created for the account
  installment: {
            id: string,
            value: number,
            amount: {
                currency: string,
                value: string,
                total_value: string,
            },
        },
  // Check your card processor to know if you need to send 
  // customer information
  // full object here https://docs.y.uno/reference/the-customer-object
  customer: {
    document: {
      document_number: '1090209924',
      document_type: 'CC',
    },
  },
  // This is useful for dual cards where the same card can be either used as credit or debit
  cardType: 'DEBIT' or 'CREDIT'
})

Step 6: Create the Payment

After receiving the One Time Token, you can create the payment using the createPayment function, providing the oneTimeToken and the checkoutSession. The back-to-back payment creation must be carried out using the Create Payment endpoint.

  • Status Payment: As the process may raise errors, we recommend using a try/catch function here. Then, you can check the payment status with the yuno.mountStatusPaymentfunction, as shown in the next code example:
// Create your payment, you should implement this function
await createPayment({ oneTimeToken, checkoutSession })

// Check payment status
yuno.mountStatusPayment({
  checkoutSession: checkoutSession,
  /**
   * Country can be one of CO, BR, CL, PE, EC, UR, MX
   */
  /**
     * Should be added her or in the token generation
     * @optional
     */
  countryCode: 'CO',
  /**
   * Language can be one of es, en, pt
   */
  language: 'en',
  /**
   * @param {'READY_TO_PAY' | 'CREATED' | 'SUCCEEDED' | 'REJECTED' | 'CANCELLED' | 'ERROR' | 'DECLINED' | 'PENDING' | 'EXPIRED' | 'VERIFIED' | 'REFUNDED'} data
   */
  yunoPaymentResult(data) {
    console.log('yunoPaymentResult', data)
  },
})

Complementary Features

In addition to the code examples provided, you can access the Demo App for a complete implementation of Yuno SDKs or go directly to the HTML and JavaScript Secure Fields checkout demos available on GitHub.

Yuno Secure Fields provides additional services and configurations you can use to improve customers' experience:

1- Persist credit card information to retry payments

In case a transaction is rejected, you can persist the credit card data to retry a payment after the customer has entered the credit card details. In order to do that, you will need to:

  1. Add the following parameter during the creation of the One Time Token (OTT):
const oneTimeTokenWithInformation = await secureFields.generateTokenWithInformation({ 
  checkoutSession: '{{the checkout session id}}',
})

To receive any additional info given by the customer in the checkout such as installments, document type or document number

const oneTimeTokenWithInformation = await secureFields.generateTokenWithInformation({ 
  checkoutSession: '{{the checkout session id}}',
})
  1. In case the transaction is rejected, you will need to:
    i. Create a new checkout session.
    ii. Generate a new One Time Token (OTT). In the OTT generation, send the new checkout session in the checkoutSession parameter.
  2. Continue with the new checkout and One Time Token with the regular payment flow.

2- Clear the values entered in the card fields

Related to the previous functionality, the merchant can configure to clear the information entered in any of the card fields. To accomplish this, it is necessary to execute the method secureFieldInstance.clearValue(), for each field that you wish to clear or delete. Below is an example:

const secureFieldInstance = secureFields.create({...})
secureFieldInstance.clearValue()

3- Input focus

The merchant can set focus on a particular input. To accomplish this, it is necessary to execute the method secureFieldInstance.focus(), for each field that you wish to focus. Below is an example:

const secureFieldInstance = secureFields.create({...})
secureFieldInstance.focus()

4- Force validation

The merchant can force the validation for a particular input. To accomplish this, it is necessary to execute the method secureFieldInstance.validate(), for each field that you wish to validate. Below is an example:

const secureFieldInstance = secureFields.create({...})
secureFieldInstance.validate()

5- Set custom error message

The merchant can define a custom error message after an input validation. To accomplish this, it is necessary to execute the method secureFieldInstance.setError(), for each field that you wish to set a custom error message for. Below is an example:

const secureFieldInstance = secureFields.create({...})
secureFieldInstance.setError('Custom error')

6- Set card type

The merchant can define the card type the customer is using for the payment. To accomplish this, it is necessary to execute the method secureFieldInstance.setCardType() and send either ´DEBIT´ or ´CREDIT´ for each scenario. This is useful for dual cards where the same card can be either used as credit or debit. In Brazil for example. Below is an example:

const secureFieldInstance = secureFields.create({...})
secureFieldInstance.setCardType('CREDIT')