Skip to main content

Overview

To enable an instant payment (PULL/PUSH) with an external card-on-file, the following steps are required:
  1. Add card-on-file
  2. For PULL payments, enable 3-D Secure (3DS) authentication
  3. Initiate external card-on-file payment

Add card-on-file using the External Card Creation Widget

This step is requied if you are not PCI certified. The External Card Creation Widget allows your customers to securely enter payment card information directly in your application. Since the widget communicates directly between the client and Synctera, it removes the need for you to be PCI certified. The information is stored securely and can be retrieved via Synctera API.
The External Card Creation Widget provides a complete, secure payment form that includes:
  • Card Number (PAN) - Primary account number with automatic formatting
  • Cardholder Name - Name on the card
  • Expiration Date - Card expiry with MM/YY format
  • CVV/CVC - Security code (3-4 digits)
  • Billing Address - Optional billing address fields
All sensitive card data is handled in isolated iframes, ensuring PCI compliance while giving you full control over the user experience.

Getting Started

Prerequisites

Before integrating the widget, ensure you have:
  • Synctera API Keys - Working API keys for your business
  • Widget Token - A widget token for tokenizing cards (obtained from the API)
  • Environment Configuration - Know which environment you’re using (sandbox, or production)

API Keys

First, ensure you have your Synctera API Keys working for your business. You’ll need these to obtain widget tokens.

Mobile Applications

If you’re integrating the widgets in a mobile application, you may need to use one of the following web views:
  • WKWebView in an iOS application
  • WebView in an Android application
  • WebView in React Native

Basic Integration

Step 1: Load the Widget Script

Load the External Card Creation widget script into your page by adding the following script tag to the bottom of the body of your HTML:
    <script 
      type="module" 
      src="https://assets.synctera.com/widgets/external-card-creation/v1.0.0/index.js">
    </script>

Step 2: Get a Widget Token

Request a widget token for tokenizing cards from your backend using the Synctera API. The widget token is required for the widget to authenticate and submit card data.
curl -X POST "https://api-sandbox.synctera.com/v1/external_cards/widget_token?widget_type=TOKENIZE&customer_id={customerId}" \
  -H "Authorization: Bearer {apiKey}" \
  -H "Content-Type: application/json"
Widget tokens expire after a set period and are scoped to a specific customer. Generate a new token on each page load or when needed. Widget tokens are one use only, so if a user submits and gets an error that invalidates the token and the widget will be to be supplied a new token.

Step 3: Add the Widget Component

Add the <external-card-creation> web component to your page where you want the card form to appear:
<body>
  <external-card-creation
    token="your-widget-token"
    env="sandbox"
  ></external-card-creation>
</body>

Configuration Options

The <external-card-creation> component supports the following configuration options:
PropertyTypeRequiredDefaultDescription
tokenstringYes-Widget token obtained from the API
envstringYes-Environment: sandbox or production
themestringNo"default"Theme style: "default" or "night-shift"
include-addressbooleanNofalseShow/hide billing address fields section
custom-labelsstringNo{}JSON string of custom labels for form fields

Environment Configuration

The env property determines which API endpoint the widget uses:
  • sandbox - Sandbox/test environment (recommended for testing)
  • production - Production environment
Always use sandbox for testing and development. Only use production for live integrations.

Theme Options

The widget supports two themes:
<external-card-creation
  token="your-token"
  env="sandbox"
  theme="default"
></external-card-creation>

Custom Labels

Customize the labels and text displayed in the widget by passing a JSON string to the custom-labels attribute:
<external-card-creation
  token="your-token"
  env="sandbox"
  custom-labels='{
    "widgetTitle": "Payment Information",
    "cardNameLabel": "Full Name on Card",
    "cardNumberLabel": "Card Number",
    "expirationDateLabel": "Expiry",
    "securityCodeLabel": "CVV",
    "streetAddressLabel": "Street Address",
    "cityLabel": "City",
    "stateLabel": "State",
    "zipCodeLabel": "ZIP Code",
    "submitButtonText": "Add Payment Method",
    "submitLoadingText": "Processing...",
    "useAddressOnFileLabel": "Use my saved address"
  }'
></external-card-creation>
Available custom label keys:
  • widgetTitle - Widget header text
  • cardNameLabel - Name on card label
  • cardNumberLabel - Card number label
  • expirationDateLabel - Expiration date label
  • securityCodeLabel - CVV/CVC label
  • streetAddressLabel - Street address label
  • addressLine2Label - Address line 2 label
  • cityLabel - City label
  • stateLabel - State label
  • zipCodeLabel - ZIP code label
  • submitButtonText - Submit button text
  • submitLoadingText - Loading state text
  • useAddressOnFileLabel - Address checkbox label
  • billingAddressTitle - Billing address section title

Event Handling

The widget dispatches custom events for success and failure scenarios. You can listen to these events to handle the submission results.

Success Event

The widget dispatches a success event when card tokenization is successful:
<external-card-creation
  id="card-widget"
  token="your-token"
  env="sandbox"
></external-card-creation>

<script>
  document.getElementById('card-widget').addEventListener('success', (event) => {
    console.log('Card tokenized successfully:', event.detail);
    // Handle success - event.detail contains the tokenization result
  });
</script>

Failure Event

The widget dispatches a failure event when card tokenization fails:
widget.addEventListener('failure', (event) => {
  const { error } = event.detail;
  console.error('Tokenization failed:', error);
  // Display error message to user
});

Event Callback Properties

You can also provide callback functions directly as properties:
<external-card-creation
  token="your-token"
  env="sandbox"
  onSuccess="handleSuccess"
  onFailure="handleFailure"
></external-card-creation>

<script>
  function handleSuccess(event) {
    console.log('Success:', event.detail);
  }
  
  function handleFailure(event) {
    console.error('Error:', event.detail.error);
  }
</script>

Complete Example

Here’s a complete example showing a full integration with widget token fetching and error handling:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>External Card Creation Widget Example</title>
    <script 
      type="module" 
      src="https://assets.synctera.com/widgets/external-card-creation/v1.0.0/index.js">
    </script>
  </head>
  <body>
    <h1>Add Payment Card</h1>
    
    <div id="error-message" style="color: red; display: none;"></div>
    
    <external-card-creation
      id="card-widget"
      env="sandbox"
    ></external-card-creation>
    
    <script>
      async function initializeWidget() {
        try {
          // Fetch widget token from your backend
          const response = await fetch('/api/widget-token', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json'
            },
            body: JSON.stringify({
              customer_id: 'your-customer-id'
            })
          });
          
          const { widget_token } = await response.json();
          
          // Set token on widget
          const widget = document.getElementById('card-widget');
          widget.setAttribute('token', widget_token);
          
          // Set up event listeners
          widget.addEventListener('success', (event) => {
            console.log('Card tokenized:', event.detail);
            alert('Card added successfully!');
            // Redirect or update UI
          });
          
          widget.addEventListener('failure', (event) => {
            const errorDiv = document.getElementById('error-message');
            errorDiv.textContent = event.detail.error;
            errorDiv.style.display = 'block';
          });
          
        } catch (error) {
          console.error('Failed to initialize widget:', error);
          document.getElementById('error-message').textContent = 
            'Failed to load payment form. Please refresh the page.';
          document.getElementById('error-message').style.display = 'block';
        }
      }
      
      // Initialize when page loads
      window.addEventListener('DOMContentLoaded', initializeWidget);
    </script>
  </body>
</html>

Address Fields

The widget supports optional billing address collection. Enable address fields by setting include-address="true":
<external-card-creation
  token="your-token"
  env="sandbox"
  include-address="true"
></external-card-creation>
When address fields are enabled, the widget includes:
  • Street Address (Address Line 1)
  • Address Line 2 (optional)
  • City
  • State
  • ZIP Code
The widget also provides a checkbox option to “Use address on file” which will hide the address fields if checked.

Field Validation

The widget automatically validates all card fields in real-time:
  • Card Number (PAN): Validates card number format and runs Luhn algorithm check
  • Cardholder Name: Validates alphabetical characters and proper formatting
  • Expiration Date: Validates MM/YY format and ensures date is not expired
  • CVV/CVC: Validates 3-4 digit security code
  • Address Fields: Validates address format, state codes, and ZIP codes
The submit button is automatically disabled until all required fields are valid.

Card verifications

For security purposes, a number of verifications are performed when the card is added. For details, see the Verifications section.

Security & PCI Compliance

All sensitive card data is handled in isolated iframes, ensuring that your application never touches PCI-sensitive information.

Security Features

  • Iframe Isolation: Each field runs in its own sandboxed iframe
  • No Data Exposure: Sensitive data never touches the parent page
  • Token-based Authentication: Secure API communication using widget tokens
  • Origin Validation: All messages validated against expected origins
  • XSS Protection: All input is sanitized and validated

PCI Compliance

The widget is designed to help you maintain PCI compliance:
  • Sensitive card data is isolated in secure iframes
  • Your application never handles raw card data
  • All communication uses secure, tokenized endpoints
  • The widget handles PCI compliance requirements on your behalf

Troubleshooting

Widget Not Loading

If the widget doesn’t appear on your page:
  1. Check Script Loading: Ensure the widget script is loaded before the component is used
  2. Check Token: Verify the widget token is valid and not expired
  3. Check Environment: Ensure the env attribute matches your API environment
  4. Check Console: Look for JavaScript errors in the browser console

Tokenization Failing

If card submission fails:
  1. Verify Token: Ensure the widget token is valid and not expired
  2. Check Environment: Ensure the env matches your API endpoint
  3. Check Network: Inspect network requests in browser DevTools
  4. Review Error Events: Listen to the failure event for detailed error messages

Additional Information

Supported Browsers

The widget supports all modern browsers:
  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Responsive Design

The widget is fully responsive and adapts to mobile and desktop screens automatically.

Custom Styling

The widget comes with a theme option and labels can be passed in as attributes

Add card-on-file using API

If you are PCI certified, you have the option to create the External Card directly using the card credentials by calling POST /v1/external_cards. In addition to the card credentials (pan and expiration_month/expiration_year), you must provide the customer_id and cardholder name (business_id may optionally be provided if applicable). cvv is optional (for migration purposes), but should be provided for adding new cards as it provides an additional layer of security and reduces the risk of fraud. A billing_address can be added optionally, if it is different from the cardholder’s address-on-file on the Synctera platform. For more details on CVV and address verification, see the Verifications section.

Example request/response

Example request:
curl \
  $baseurl/v1/external_cards \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  -d '
  {
    "pan": "4005519200000004",
    "cvv": "123",
    "expiration_month": "04",
    "expiration_year": "26",
    "name": "Jane Taylor",
    "customer_id": "{CUSTOMER_ID}"
  }'
Example response:
{
  "created_time": "2023-01-18T12:03:46.892809-05:00",
  "currency": "USD",
  "customer_id": "{CUSTOMER_ID}",
  "expiration_month": "4",
  "expiration_year": "2026",
  "id": "{EXTERNAL_CARD_ID}",
  "last_four": "0004",
  "last_modified_time": "2023-01-18T12:03:46.892809-05:00",
  "name": "Jane Taylor",
  "verifications": {
    "address_verification_result": "VERIFIED",
    "cvv2_result": "VERIFIED",
    "pull_enabled": true,
    "push_enabled": true,
    "state": "SUCCEEDED"
  }
}

Verifications

When an External Card is created, the following verifications are performed:
  • CVV2 verification:
    • CVV2 provided in the widget or in the API is validated against the CVV2 on file with the issuer
  • Address verification:
    • Unless billing address is specified in the widget/API, the address stored on the customer’s record on Synctera is validated against the address-on-file with the issuer
    • Note that if business_id is provided, address verification is performed on the Business’s legal address, otherwise, it is performed on the Person’s legal address. However, cardholder name matching is performed on the Person’s name regardless.
  • Name verification:
    • Name provided in the widget is validated against the name on file with the issuer
The verification results are displayed in the verifications object. In addition to CVV2, address and name, the verifications object contains information about the card, as well as the type of transactions the card supports. If either pull_enabled or push_enabled are false, that type of transaction may not be performed using the card.

Enable 3DS and create payment

Once a card has been added on file, a PULL or a PUSH payment can be initiated with the card. For PULL payments, 3-D Secure (3DS) authentication is required. For details on how to enable 3DS, and how to iniate a payment with a card-on-file, see the Instant Payments - Card-On-File section.