All pages
Powered by GitBook
1 of 3

Loading...

Loading...

Loading...

Simple HTML Example

For convenience, here's an example of how to interact with our APIs to verify Legitimate's NFC tags in your own application

The following code snippet is an example of a synchronous, blocking javascript function to verify the digital signatures emitted by Legitimate's NFC tags.

This code is provided as an example for your own implementation. For more information on how to implement this exact code into your own website, please see Getting Started.

The code of the javascript is expanded below for reference.

Getting Started

Use our provided javascript function in your own HTML website to easily verify the digital signatures emitted by Legitimate's NFC tags

For convenience, Legitimate provides a simple javascript implementation of the API verification mechanism required to validate the digital signatures emitted by NFC tags. You can see a full HTML example .

Add the JS snippet

To get started, simply add our minified javascript function to the top of your HTML <head> block. Make sure this is at the top of the <head> block as it is required to load first.

This script contains sensible defaults that will hide the entirety of your page's contents until after the digital signature verification is complete. You can see the un-minified implementation of this script

.

What this script does

This script calls the exact same API endpoint as described in Verify by passing through the verification parameters present in the URL query parameters. If the verification is successful, the contents of your HTML <body> will be displayed as normal.

Adding Custom Error States

By default, the snippet will display an error message if the digital signature verification fails. You may add custom error messages by adding the following HTML elements to your page.

Reused Digital Signature Parameters Error Message

The inner contents of an HTML element with the following id legitimate-expired-cmac-message will be used as the error state content if the verification fails due to the verification parameters being reused.

Our API is designed in such a way that each tag verification can only occur once with a given set of parameters. This is to prevent customers from sharing or replicating any URLs or links emitted by the NFC tag.

Default Error State Message

The inner contents of an HTML element with the following id legitimate-custom-error-message will be used as the default error state content if the verification fails.

here
here
<head>
    <script type="text/javascript">
        (function(){var a=document.createElement('style');a.innerHTML=`
    body { display: none !important; }
  `;document.head.appendChild(a);var b='https://api.legitimate.tech/external/v1/tags/verify';document.addEventListener('DOMContentLoaded',()=>{console.log('DOM loaded, making API request');fetch(b,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(Object.fromEntries(new URLSearchParams(window.location.search)))}).then(async A=>{var _=await A.json();if(!A.ok){A.status===422&&_.errors.cmac.indexOf('has expired')!==-1?c('expired_cmac'):c();return}!_.errors?a.innerHTML=`
          body { display: block !important; }
          #legitimate-custom-error-message { display: none !important; }
          #legitimate-expired-cmac-message { display: none !important; }
        `:c()}).catch(()=>c())});function c(B='default'){let C=document.getElementById('legitimate-error-message-container');!C&&(console.log('Creating error message container'),C=document.createElement('div'),C.id='legitimate-error-message-container',document.body.appendChild(C));let _c=`
      <div style="font-family: sans-serif; color: red; padding: 2rem; text-align: center;">
        An error occurred. Please try again later.
      </div>
    `;if(B==='expired_cmac'){var d=document.getElementById('legitimate-expired-cmac-message');d&&(console.log('Using expired cmac error message'),_c=d.innerHTML)}else{var e=document.getElementById('legitimate-custom-error-message');e&&(console.log('Using custom error message'),_c=e.innerHTML)}C.innerHTML=_c;a.innerHTML=`
      body { display: block !important; }
      body > *:not(#legitimate-error-message-container) { display: none !important; }
    `}})();
    </script>
    <!-- other code that may need to go into the head element -->
</head>
<div id="legitimate-expired-cmac-message" class="hidden">
    <!-- Expired CMAC Error Message -->
</div>
<div id="legitimate-custom-error-message" class="hidden">
    <!-- Your content here -->
</div>

Web/HTML Implementation

Legitimate allows agencies and developers to create entirely custom digital experiences on the Legitimate platform for a given set of tags.

Legitimate's API can be used to redirect to custom web applications or even native app experiences via two different approaches. This page covers the simple flow when redirecting to another web-based application. For information on native app integration, please refer to Native App Implementation

Technical Architecture

The Legitimate Tags are pre-programmed to link to the Tap by Legitimate web app that then be configured to redirect to your own website.

Tag URL Redirect

To see a simple example of the tag URL Redirect and tag verification in action, please refer to the document and .

Legitimate's NFC Tags can be configured to redirect to a different domain or URL with the verification parameters from the tag to create an entirely new user flow and digital experience. This is extremely useful to redirect users to a custom web experience, or redirect to a native mobile app experience.

By default, Legitimate's NFC Tags are pre-programmed to open Legitimate's web URL first and then redirect to another desired URL. Legitimate will collect analytics data before redirecting.

The URL parameters can then be used to call the tag related APIs.

Each time an NFC tag is scanned, a new set of verification parameters will be generated. Therefore, if you are intending to use the Tag URL Redirect features, it is extremely important to note that . This is meant to protect the connected products from counterfeit and ensure that each scan is unique.

To configure the redirect URL, please login to the , open the configuration page for the desired SKU, and set the Redirect URL field.

(Tag URL Redirect) High Level User Interface Overview

  • User taps the tag with their phone and opens the link popup

  • The browser opens

  • The uid, ctr, and cmac is used to verify the tag's authenticity and get information about the content for the tag.

The browser is then redirected to your own page with the same parameters https://www.yourdomain.com/page/name?uid=XXXXXXXXXXXXXX&ctr=YYYYYY&cmac=ZZZZZZZZZZZZ

  • Your own page must now call our APIs to verify the digital signature payload that is present in the query parameters.

    • Please reference our Getting Started guide to see how to implement this verification via a simple JS snippet

    • Alternatively, you can implement this verification yourself using our API Resources to create a more robust user-experience.

  • Getting Started
    Simple HTML Example
    you must verify the parameters every time a scan occurs
    Legitimate Dashboard
    https://verify.legitimate.tech/?uid=XXXXXXXXXXXXXX&ctr=YYYYYY&cmac=ZZZZZZZZZZZZ
    https://verify.legitimate.tech/?uid=XXXXXXXXXXXXXXX&ctr=YYYYYY&cmac=ZZZZZZZZZZZZZZZZ
    https://www.yourdomain.com/experience/?uid=XXXXXXXXXXXXXX&ctr=YYYYYY&cmac=ZZZZZZZZZZZZZ
    https://github.com/LegitimateTech/lgt-verify-example/blob/main/html/index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Script Test</title>
      <script src="verify-sdk-v1.js"></script>
      <script src="https://cdn.tailwindcss.com"></script>
    </head>
    
    <body class="min-h-screen bg-gray-50">
      <main class="container mx-auto px-4 py-8">
        <h1 class="text-4xl font-bold text-gray-900 mb-4">Main Page Content</h1>
        <p class="text-lg text-gray-600">If the API is valid, you'll see this content.</p>
      </main>
    
      <!-- Custom Error Message -->
      <div id="legitimate-custom-error-message" class="hidden">
        <div class="min-h-screen flex items-center justify-center bg-gray-50">
          <div class="max-w-md w-full p-6 bg-white rounded-lg shadow-lg">
            <h1 class="text-3xl font-bold text-red-600 mb-4">Custom Error!</h1>
            <p class="text-gray-600">This content failed to load. Please contact support.</p>
          </div>
        </div>
      </div>
    
      <!-- Expired CMAC Error Message -->
      <div id="legitimate-expired-cmac-message" class="hidden">
        <div class="min-h-screen flex items-center justify-center bg-gray-50">
          <div class="max-w-md w-full p-6 bg-white rounded-lg shadow-lg">
            <h1 class="text-3xl font-bold text-red-600 mb-4">Please Scan the Tag Again</h1>
            <p class="text-gray-600">The tag verification has expired. Please scan the tag again.</p>
          </div>
        </div>
      </div>
    
    </body>
    </html>
    https://github.com/LegitimateTech/lgt-verify-example/blob/main/html/verify-sdk-v1.js
    (function() {
      // Inject CSS to hide body and error container
      const style = document.createElement('style');
      style.innerHTML = `
        body { display: none !important; }
      `;
      document.head.appendChild(style);
    
      const API_URL = 'https://api.legitimate.tech/external/v1/tags/verify';
    
      document.addEventListener('DOMContentLoaded', () => {
        console.log('DOM loaded, making API request');
        fetch(API_URL, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(Object.fromEntries(new URLSearchParams(window.location.search)))
        }).then(async res => {
          const data = await res.json();
          if (!res.ok) {
            if (res.status === 422 && data.errors.cmac.indexOf('has expired') !== -1) {
              renderErrorMessage('expired_cmac');
            } else {
              renderErrorMessage();
            }
            return;
          }
          if (!data.errors) {
            style.innerHTML = `
              body { display: block !important; }
              #legitimate-custom-error-message { display: none !important; }
              #legitimate-expired-cmac-message { display: none !important; }
            `;
          } else {
            renderErrorMessage();
          }
        })
        .catch(() => {
          renderErrorMessage();
        });
      });
    
      function renderErrorMessage(errorType = 'default') {
        let errorContainer = document.getElementById('legitimate-error-message-container');
        if (!errorContainer) {
          console.log('Creating error message container');
          errorContainer = document.createElement('div');
          errorContainer.id = 'legitimate-error-message-container';
          document.body.appendChild(errorContainer);
        }
    
        let errorContent = `
          <div style="font-family: sans-serif; color: red; padding: 2rem; text-align: center;">
            An error occurred. Please try again later.
          </div>
        `;
    
        if (errorType === 'expired_cmac') {
          const expiredCmacErrorEl = document.getElementById('legitimate-expired-cmac-message');
          if (expiredCmacErrorEl) {
            console.log('Using expired cmac error message');
            errorContent = expiredCmacErrorEl.innerHTML;
          }
        } else {
          const customErrorEl = document.getElementById('legitimate-custom-error-message');
          if (customErrorEl) {
            console.log('Using custom error message');
            errorContent = customErrorEl.innerHTML;
          }
        }
    
        errorContainer.innerHTML = errorContent;
        style.innerHTML = `
          body { display: block !important; }
          body > *:not(#legitimate-error-message-container) { display: none !important; }
        `;
      }
    })();