API Reference

Documentation

Passage.Js

Passage.js is a JavaScript library for Merchants to collect sensitive payment data from the users and send directly to Valor. Merchants can integrate the script and customize the checkout form as per their requirements. The authentication is done by a Client Token generated by GetClientToken API, which is discussed in the later section.

You can integrate Valor Payment Gateway using Passage.js with these simple steps:

  • Generate APP ID, APP Key and EPI required for integration.
  • Retrieve the client token through GetClientToken API.
  • Integrate the required Passage.js script and pass the received token from the API to the “data-clientToken” attribute.
  • Create a form with required fields. Set action of the form to the API which calls Valor's Sale API.
  • Handle the response received from the Sale API.

Getting ID and Keys

In order to integrate and use Passage.js, the merchants will need to use their APP ID, APP Key and EPI to generate a Client Token.

You can take the following steps to generate or retrieve your keys:

Step 1: Login to the Valor portal


Step 2: Click on "Manage" option in "Virtual Terminal" in sidemenu

Step 3: Under "API KEYS" you can find your APP ID, APP Key and EPI

Generating Client Token

The merchant can now generate a Client Token to handle merchant authentication in place of APP ID, APP Key. The Token should then be used in Passage.js script with “data-clientToken” attribute.

Example Client Token: 7b9e2a55-720d-4533-bb70-9376a378eae4

Client Token can be generated by using the following GetClientToken API.

https://securelink-staging.valorpaytech.com:4430/?
https://securelink.valorpaytech.com:4430/?
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://securelink-staging.valorpaytech.com:4430/?appid=WaJeJErcv5xpqZa2UZz6LZod5MSyyfJw&appkey=53PWdki5U0PGSVhRnVoFsfVSbuDutsA8&epi=2203082193&txn_type=sale&token=26F9A99643197174FE11B29A4A76145773C0B93D&amount=5.00&surchargeIndicator=0&surchargeAmount=5.00&phone=5628398878&address1=2%20Jericho%20Plz&city=Jericho&state=NY&shipping_country=US&billing_country=US&zip=50001&saleAPI=', [
  'headers' => [
    'accept' => 'application/json',
  ],
]);

echo $response->getBody();
import requests

url = "https://securelink-staging.valorpaytech.com:4430/?appid=WaJeJErcv5xpqZa2UZz6LZod5MSyyfJw&appkey=53PWdki5U0PGSVhRnVoFsfVSbuDutsA8&epi=2203082193&txn_type=sale&token=26F9A99643197174FE11B29A4A76145773C0B93D&amount=5.00&surchargeIndicator=0&surchargeAmount=5.00&phone=5628398878&address1=2%20Jericho%20Plz&city=Jericho&state=NY&shipping_country=US&billing_country=US&zip=50001&saleAPI="

headers = {"accept": "application/json"}

response = requests.post(url, headers=headers)

print(response.text)
const sdk = require('api')('@valorapi/v1.0#2lhelnbcau0v');

sdk.saleApi({
  appid: 'WaJeJErcv5xpqZa2UZz6LZod5MSyyfJw',
  appkey: '53PWdki5U0PGSVhRnVoFsfVSbuDutsA8',
  epi: '2203082193',
  txn_type: 'sale',
  token: '26F9A99643197174FE11B29A4A76145773C0B93D',
  amount: '5.00',
  surchargeIndicator: '0',
  surchargeAmount: '5.00',
  phone: '5628398878',
  address1: '2%20Jericho%20Plz',
  city: 'Jericho',
  state: 'NY',
  shipping_country: 'US',
  billing_country: 'US',
  zip: '50001',
  saleAPI: ''
})
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));
CURL *hnd = curl_easy_init();

curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://securelink-staging.valorpaytech.com:4430/?appid=WaJeJErcv5xpqZa2UZz6LZod5MSyyfJw&appkey=53PWdki5U0PGSVhRnVoFsfVSbuDutsA8&epi=2203082193&txn_type=sale&token=26F9A99643197174FE11B29A4A76145773C0B93D&amount=5.00&surchargeIndicator=0&surchargeAmount=5.00&phone=5628398878&address1=2%20Jericho%20Plz&city=Jericho&state=NY&shipping_country=US&billing_country=US&zip=50001&saleAPI=");

struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "accept: application/json");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);

CURLcode ret = curl_easy_perform(hnd);
using RestSharp;


var options = new RestClientOptions("https://securelink-staging.valorpaytech.com:4430/?appid=WaJeJErcv5xpqZa2UZz6LZod5MSyyfJw&appkey=53PWdki5U0PGSVhRnVoFsfVSbuDutsA8&epi=2203082193&txn_type=sale&token=26F9A99643197174FE11B29A4A76145773C0B93D&amount=5.00&surchargeIndicator=0&surchargeAmount=5.00&phone=5628398878&address1=2%20Jericho%20Plz&city=Jericho&state=NY&shipping_country=US&billing_country=US&zip=50001&saleAPI=");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
var response = await client.PostAsync(request);

Console.WriteLine("{0}", response.Content);

package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://securelink-staging.valorpaytech.com:4430/?appid=WaJeJErcv5xpqZa2UZz6LZod5MSyyfJw&appkey=53PWdki5U0PGSVhRnVoFsfVSbuDutsA8&epi=2203082193&txn_type=sale&token=26F9A99643197174FE11B29A4A76145773C0B93D&amount=5.00&surchargeIndicator=0&surchargeAmount=5.00&phone=5628398878&address1=2%20Jericho%20Plz&city=Jericho&state=NY&shipping_country=US&billing_country=US&zip=50001&saleAPI="

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("accept", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(string(body))

}
require 'uri'
require 'net/http'

url = URI("https://securelink-staging.valorpaytech.com:4430/?appid=WaJeJErcv5xpqZa2UZz6LZod5MSyyfJw&appkey=53PWdki5U0PGSVhRnVoFsfVSbuDutsA8&epi=2203082193&txn_type=sale&token=26F9A99643197174FE11B29A4A76145773C0B93D&amount=5.00&surchargeIndicator=0&surchargeAmount=5.00&phone=5628398878&address1=2%20Jericho%20Plz&city=Jericho&state=NY&shipping_country=US&billing_country=US&zip=50001&saleAPI=")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'

response = http.request(request)
puts response.read_body
{"error_no":"S00","error_code":"00","clientToken":"7b9e2a55-720d-4533-bb70-9376a378eae4","validity":"2023-01-05 12:44:01"}
Field      Type           Length     Mandatory / Optional     Decription
appid      String         32         Mandatory                Contact valorpaytech
appkey     String         32         Mandatory                Contact valorpaytech
txn_type   String         15         Mandatory                clientToken
epi        Numeric        10         Mandatory                Epi number

Integrating The Script

After getting the token, integrate the Passage.js Script in your checkout page where you want to process the card details and payments. Pass the received token in the script with data-clientToken attribute.

You can integrate it using following script:

<script src="https://js.valorpaytech.com/V1/js/Passage.min.js" data-name="valor_passage" data-clientToken="YOUR TOKEN" data-epi="YOUR EPI"></script>

This script would call the card fields (card number, card expiry and cvv) by default when you integrate the form. But, we offer a list of other optional parameters that you can directly configure into the script itself for more flexibility and customizability over the form:

Name                            Example Value                                    Description
data-clientToken                7b9e2a55-720d-4533-bb70-9376a378eae4             Client Token required to pass for authentication.
data-epi                        2104704629                                       Client EPI
data-demo                       true                                             To process transaction in demo use this attribute or else remove this attribute to process with live.
data-variant                    inline/lightbox                                  Default value is inline, set it lightbox to display
                                                                                 card details as popup instead on page.
data-submitText                 Pay $5                                           Customize Submit Payment button text
data-submitBg                   #000                                             Color of the submit button background.
data-submitColor                #fff                                             Color of the submit button text.
data-valorLogo                  false                                            Default true. Pass false to hide the logo.
data-cardholderName             true                                             Calls for Valor's Name field if true
data-defaultCardholderName      John Doe                                         Default value is empty, can assign a value to autofill
data-email                      true                                             Calls for Valor's email field if true
data-defaultEmail               [email protected]                                      Default value is empty, can assign a value to autofill
data-phone                      true                                             Calls for Valor's phone field if true
data-defaultPhone               (123) 123-1234                                   Default value is empty, can assign a value to autofill
data-billingAddress             true                                             Calls for Valor's address fields (Address, City, State) if true
data-defaultAddress1            3636                                             Default value is empty, can assign a value to autofill
data-defaultAddress2            33rd st                                          Default value is empty, can assign a value to autofill
data-defaultCity                New York City                                    Default value is empty, can assign a value to autofill
data-defaultState               New York                                         Default value is empty, can assign a value to autofill
date-epi                        2104704629                                       Client EPI required to pass for authentication
data-demo                       https://securelink-staging.valorpaytech.com:4430 To use the demo URL
data-name                       valor_passage                                    Default value is empty, can assign a value to autofill

Integrating The Form

After you're done with selecting and finalizing your form style and fields, it's time to integrate it into a form and display it all on the page.

For the Form Layout you can choose one of the 2 approaches:

  • Inline: Which integrates all the fields including the card field into the checkout page. This is the default behavior while integrating Passage.js. You can pass the attribute "data-variant" as "inline" or not use the attribute at all to enable this option.
  • Lightbox: Which opens up the card fields as a popup on clicking the Submit button. To enable this layout, you will have to pass the attribute "data-variant" as "lightbox" in the Script in the previous step.

After that you can take following steps to integrate the form to capture card details:

  • Create a form element in the view with id "valor-checkout-form" and set the action of the form to call the Sale API from your backend.
  • You can first add any additional fields of your choice that you require in the form and then call a div with the id "valor-checkout-fields". This will call all the data input fields from Passage.js such as card details and the ones you may have enabled in the script tag.

Here's an Example:

<form action="https://path-to-your-api-call" method="post" id="valor-checkout-form">
    <input type="hidden" name="orderId" value="1"/>
    <div id="valor-fields"></div>
</form>

To capture the form submit event of passage.js use the below code snippet.

document.addEventListener("passageHiddenFormAdded", function(event) {

    const form = event.detail.form;

    form.addEventListener("submit", function(event) {

        event.preventDefault();

    });

});

Vault API – Add Payment Profile Token

This document outlines the integration details for adding a new endpoint to the Vault API that allows storing a card token in the process of adding a payment profile.

End Point: POST https://demo.valorpaytech.com/api/valor-vault/addpaymentprofiletoken/{vault_id}

  • {vault_id} – The unique Vault ID associated with the customer profile (received from the "Create Customer Profile" API).

Sample Request Payload

{
  "token": "<TOKEN>",
}
Field	            Type	   Required	  Description
token	            string	    Yes	        The secure token representing the card
cardholder_name	    string	    No	        Cardholder name is a optional

Integration Steps

Generate Card Token:

  • The frontend application collects the payment information.
  • Calls the Create Card Token API to securely generate a token.

Create Vault Customer Profile:

  • Call the Vault API to create a new customer profile.
  • Save the returned vault_id.

Add Payment Profile Token:

Use the new endpoint (/addpaymentprofiletoken/{vault_id}) to associate the token with the newly created Vault ID.

Inline Integration Example:

Lightbox Integration Example:

Handling The Response

The form submission will be calling the Sale API to complete the payment. After the the payment has completed it will return the response that you can integrate into a Thank You/Error page or a popup.

Details about the request/response structure, parameters for Sale API can be found here and information about Error codes can be found here

PassageJS v2.0 Documentation

A comprehensive payment form library supporting Credit Cards and ACH payments with secure tokenization and seamless integration.

Table of Contents

  1. Overview
  2. Features
  3. Installation
  4. Quick Start
  5. Configuration
  6. Payment Methods
  7. Events & Callbacks
  8. Custom Data
  9. API Reference
  10. Integration Examples
  11. Security
  12. Troubleshooting

Overview

PassageJS v2.0 is a vanilla JavaScript payment library that provides secure, PCI-compliant payment processing for both credit cards and ACH (bank account) payments. It features automatic card tokenization, real-time validation, and a comprehensive event system for seamless integration.

Key Benefits

🔒 Secure: Credit card tokenization ensures sensitive data never touches your servers

🎨 Customizable: Flexible UI with inline and lightbox modes

📱 Responsive: Mobile-optimized design that works on all devices

⚡ Fast: Vanilla JavaScript with no dependencies

🔧 Flexible: Comprehensive event system and custom data support

Features

Payment Processing

✅ Credit card tokenization via Valor PayTech API

✅ Direct ACH payment submission

✅ Real-time form validation

✅ Automatic field formatting

✅ Session management

UI/UX

✅ Inline and lightbox display modes

✅ Responsive design

✅ Custom styling options

✅ Card type detection with icons

✅ Loading states and error messages

Integration

✅ Comprehensive event system

✅ Custom data injection

✅ Parent form integration

✅ Multiple callback options

✅ Easy configuration updates

Installation

Option 1: Direct Script Include

<script src="path/to/passage-v2.js"></script>

Option 2: Module Import

import PassageJS from './passage-v2.js';

HTML Setup

Add a container element where the payment form will be rendered:

<div id="valor-fields"></div>

Quick Start

Basic Credit Card Setup

const passage = new PassageJS({
  clientToken: 'your_valor_client_token',
  epi: 'your_valor_epi',
  formAction: '/process-payment',
  
  onSuccess: (result) => {
    console.log('Payment successful:', result);
    // Redirect to success page
    window.location.href = '/success';
  },
  
  onError: (error) => {
    console.error('Payment failed:', error);
    alert('Payment failed. Please try again.');
  }
});

Lightbox Mode

const passage = new PassageJS({
  clientToken: 'your_valor_client_token',
  epi: 'your_valor_epi',
  formAction: '/process-payment',
  variant: 'lightbox',
  submitText: 'Pay Now'
});

Configuration

Required Settings

OptionTypeDescription
clientTokenstringYour Valor PayTech client token
epistringYour Valor PayTech EPI identifier
formActionstringURL where payment data will be submitted

Core Settings

const config = {
  // Required
  clientToken: 'your_client_token',
  epi: 'your_epi',
  formAction: '/process-payment',
  
  // Optional
  isDemo: false,                    // Use demo environment
  formMethod: 'POST',               // Form submission method
  customData: {},                   // Additional data to submit
  
  // UI Settings
  variant: 'inline',                // 'inline' | 'lightbox'
  theme: 'default',
  submitText: 'Pay Now',
  submitBg: '#005cb9',
  submitColor: '#fff',
  
  // Payment Methods
  enableCreditCard: true,
  enableACH: true,
  defaultPaymentMethod: 'credit-card',
  
  // Form Fields
  showLogo: false,
  showCardholderName: true,
  showEmail: false,
  showPhone: false,
  showBillingAddress: false,
  
  // Session
  sessionExpiryMinutes: 5
};

Default Values

const passage = new PassageJS({
  // ... other config
  defaults: {
    cardholderName: 'John Doe',
    email: '[email protected]',
    phone: '(555) 123-4567',
    address1: '123 Main St',
    city: 'New York',
    state: 'New York',
    zip: '10001'
  }
});

Payment Methods

Credit Card Processing

Credit cards are automatically tokenized for security:

  1. User enters card details → Real-time validation
  2. Form submission → Card data sent to Valor for tokenization
  3. Token received → Sensitive card data is replaced with secure token
  4. Form submitted → Only token and metadata sent to your server

Your server receives:

  • card_token - Secure payment token
  • payment_method - "credit-card"
  • cardholder_name - If enabled
  • Customer and custom data

ACH (Bank Account) Processing

ACH payments are submitted directly without tokenization:

Your server receives:

  • payment_method - "ach"
  • routing_number - Bank routing number
  • account_number - Bank account number
  • account_type - "checking" or "savings"
  • account_holder_name - Account holder name
  • Customer and custom data

Events & Callbacks

Event System

PassageJS provides a comprehensive event system for integration:

// Listen to events
passage.on('tokenReceived', (data) => {
  console.log('Card tokenized:', data.token);
});

passage.on('formSubmitting', (data) => {
  console.log('Submitting to:', data.action);
  console.log('Form data:', data.formData);
});

passage.on('validationChanged', (data) => {
  console.log('Form valid:', data.isValid);
  updateCheckoutButton(data.isValid);
});

Available Events

EventDescriptionData
initializedLibrary loaded and ready{version, config}
lightboxOpenedLightbox modal opened{}
lightboxClosedLightbox modal closed{}
paymentMethodChangedUser switched payment method{method}
fieldChangedForm field value changed{fieldType, value, isValid}
fieldBlurredForm field lost focus{fieldType, value, isValid}
validationChangedForm validation state changed{isValid, validation, paymentMethod}
beforeSubmitBefore payment processing starts{paymentMethod}
tokenReceivedCredit card token received{token, paymentMethod}
formSubmittingForm being submitted to server{formData, action, method}
afterSubmitAfter form submission{formData}
successPayment completed successfully{success, paymentMethod, token}
errorPayment processing failed{error}
sessionExpiredPayment session expired{}

Legacy Callbacks

For backward compatibility, you can also use callback functions:

const passage = new PassageJS({
  // ... config
  onSuccess: (result) => {
    console.log('Payment successful:', result);
  },
  
  onError: (error) => {
    console.error('Payment failed:', error);
  },
  
  onValidationChange: (isValid, validation) => {
    console.log('Form validation:', isValid);
  },
  
  onTokenReceived: (token, paymentMethod) => {
    console.log('Token received:', token);
  },
  
  onFormSubmit: (formData, action) => {
    console.log('Form submitting to:', action);
  }
});

Custom Data

Adding Order Information

Include order IDs, amounts, and other data with your payment submissions:

During Initialization

const passage = new PassageJS({
  clientToken: 'your_token',
  epi: 'your_epi',
  formAction: '/process-payment',
  
  customData: {
    order_id: 'ORDER-12345',
    amount: '99.99',
    currency: 'USD',
    customer_id: 'CUST-789'
  }
});

Dynamically

// Set custom data anytime
passage.setCustomData({
  order_id: generateOrderId(),
  promo_code: 'SUMMER20',
  discount_amount: '10.00'
});

// Add more data (merges with existing)
passage.setCustomData({
  shipping_method: 'express',
  gift_message: 'Happy Birthday!'
});

Using Parent Form

<form id="checkout-form">
  <input type="hidden" name="order_id" value="ORDER-12345">
  <input type="hidden" name="product_id" value="PROD-001">
  
  <!-- PassageJS renders here and automatically includes parent form data -->
  <div id="valor-fields"></div>
</form>

Event-Based Data

// Add data right before submission
passage.on('beforeSubmit', () => {
  passage.setCustomData({
    timestamp: new Date().toISOString(),
    session_id: getSessionId(),
    user_agent: navigator.userAgent
  });
});

API Reference

Constructor

new PassageJS(config)

Public Methods

setCustomData(data)

Add or update custom data to be included with form submission.

passage.setCustomData({
  order_id: 'ORDER-123',
  amount: '50.00'
});

getCustomData()`

Get current custom data.

const customData = passage.getCustomData();
console.log(customData);

updateConfig(newConfig)`

Update configuration after initialization.

passage.updateConfig({
  submitText: 'Pay $99.99',
  submitBg: '#28a745'
});

getValidationState()`

Get current form validation state.

const validation = passage.getValidationState();
console.log('Form is valid:', validation.isValid);

reset()`

Reset form to initial state.

passage.reset();

destroy()`

Clean up and remove PassageJS instance.

passage.destroy();

Event Methods

on(eventName, callback)`

Listen to events.

passage.on('success', (result) => {
  console.log('Payment successful:', result);
});

off(eventName, callback)`

Remove event listener.

const handler = (result) => console.log(result);
passage.on('success', handler);
passage.off('success', handler);

once(eventName, callback)`

Listen to event once.

passage.once('initialized', () => {
  console.log('PassageJS is ready!');
});

Integration Examples

E-commerce Checkout

// Complete e-commerce integration
function initializeCheckout(cart) {
  const passage = new PassageJS({
    clientToken: 'your_token',
    epi: 'your_epi',
    formAction: '/process-payment',
    variant: 'lightbox',
    
    customData: {
      order_id: generateOrderId(),
      subtotal: cart.subtotal,
      tax: cart.tax,
      shipping: cart.shipping,
      total: cart.total,
      items_count: cart.items.length
    }
  });
  
  // Update total when payment method changes
  passage.on('paymentMethodChanged', (data) => {
    const fee = data.method === 'ach' ? 0 : 2.99;
    updateOrderTotal(cart.total + fee);
  });
  
  // Track successful payments
  passage.on('success', (result) => {
    analytics.track('payment_completed', {
      order_id: passage.getCustomData().order_id,
      payment_method: result.paymentMethod,
      amount: cart.total
    });
    
    window.location.href = '/order-confirmation';
  });
}

Test Cards


Address - 8320
Zip - 85284