Passage.Js
Passage.js is a JavaScript library that allows merchants to securely collect sensitive payment information from users and send it directly to Valor. Merchants can integrate the library and fully customize the checkout form according to their requirements. Authentication is handled using a Client Token, which is generated via the GetClientToken API (explained in a later section).

Integrating Valor Payment Gateway with Passage.js
You can integrate Valor Payment Gateway using Passage.js by following these simple steps:
-
Generate Credentials
Obtain your APP ID, APP Key, and EPI, which are required for integration. -
Retrieve Client Token
Use the GetClientToken API to generate a secure client token for authentication. -
Include Passage.js Script
Add the Passage.js library to your frontend and pass the received token to thedata-clientTokenattribute in your checkout form. -
Create Checkout Form
Build a form with the required fields for payment collection. Set the form’sactionto the API endpoint that calls Valor’s Sale API. -
Handle Sale API Response
Process the response returned from the Sale API to confirm payment success or handle errors.
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 side menu

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

Generating Client Token
Merchants can generate a Client Token to handle authentication instead of using APP ID and APP Key. The generated token should be used in the Passage.js script via the data-clientToken attribute.
Example Client Token:
7b9e2a55-720d-4533-bb70-9376a378eae4
API Endpoints for Client Token
| Environment | URL |
|---|---|
| Demo | https://securelink-staging.valorpaytech.com:4430 |
| Live | https://securelink.valorpaytech.com:4430 |
Sample API Calls
<?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
Sample Response
{
"error_no": "S00",
"error_code": "00",
"clientToken": "7b9e2a55-720d-4533-bb70-9376a378eae4",
"validity": "2023-01-05 12:44:01"
}
Required Fields
| Field | Type | Length | Mandatory | Description |
|---|---|---|---|---|
appid | string | 32 | Yes | Contact Valor PayTech |
appkey | string | 32 | Yes | Contact Valor PayTech |
txn_type | string | 15 | Yes | Type of transaction (e.g., sale) |
epi | numeric | 10 | Yes | Merchant EPI number |
Integrating the Script
After retrieving the client token, include the Passage.js script on your checkout page.
Basic Integration
<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 automatically renders the default card fields: Card Number, Expiry Date, and CVV.
Optional Script Parameters
| Attribute Name | Example Value | Description |
|---|---|---|
data-clientToken | 7b9e2a55-720d-4533-bb70-9376a378eae4 | Client token required for authentication. |
data-epi | 2104704629 | Merchant EPI number. |
data-demo | true | Enables demo mode. Remove to process live transactions. |
data-variant | inline / lightbox | Display mode: inline (default) or lightbox popup. |
data-submitText | Pay $5 | Customize submit button text. |
data-submitBg | #000 | Submit button background color. |
data-submitColor | #fff | Submit button text color. |
data-valorLogo | false | Hide Valor logo (default: true). |
data-cardholderName | true | Display cardholder name field. |
data-defaultCardholderName | John Doe | Pre-fill cardholder name. |
data-email | true | Display email field. |
data-defaultEmail | [email protected] | Pre-fill email. |
data-phone | true | Display phone field. |
data-defaultPhone | (123) 123-1234 | Pre-fill phone. |
data-billingAddress | true | Display billing address fields. |
data-defaultAddress1 | 3636 | Pre-fill Address Line 1. |
data-defaultAddress2 | 33rd St | Pre-fill Address Line 2. |
data-defaultCity | New York City | Pre-fill City. |
data-defaultState | New York | Pre-fill State. |
data-url | https://securelink-staging.valorpaytech.com | Demo environment URL. |
data-name | valor_passage | Passage instance name. |
data-additionalInfo | true | Enable additional input fields like order number or invoice number. |
data-additionalType | order_number,invoice_number,ticket_number | Types of additional inputs to display. |
data-amount | Custom amount value | Set a custom payment amount. |
Integrating the Form
You can integrate the payment form using either inline or lightbox layouts:
- Inline: All fields render directly on the checkout page. Default mode.
- Lightbox: Opens card fields in a popup on submit. Use
data-variant="lightbox".
Example Form
<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>
Form Submit Event
document.addEventListener("passageHiddenFormAdded", function(event) {
const form = event.detail.form;
form.addEventListener("submit", function(event) {
event.preventDefault();
});
});
Vault API – Add Payment Profile Token
Add a card token to a Vault customer profile.
Endpoint:
POST https://demo.valorpaytech.com/api/valor-vault/addpaymentprofiletoken/{vault_id}
Request Payload
{
"token": "<TOKEN>"
}
Fields
| Field | Type | Required | Description |
|---|---|---|---|
| token | string | Yes | Secure token representing the card |
| cardholder_name | string | No | Optional cardholder name |
Integration Steps
- Generate Card Token: Frontend collects payment info and generates a token.
- Create Vault Customer Profile: Save the returned
vault_id. - Add Payment Profile Token: Call
/addpaymentprofiletoken/{vault_id}to associate the token.

Handling the Response
Once the form is submitted, it triggers the Sale API call to process the payment.
After the transaction is completed, the API will return a response object that can be used to display a confirmation or error message to the customer, for example, by redirecting them to a Thank You page or showing an error popup.
The response will contain information such as the transaction status, response code, and authorization details.
You can find detailed information about the Sale API request and response structure, including all parameters, in the official API documentation.
For a comprehensive list of error codes and their meanings, refer to the Valor API Documentation.
Test Card & AVS Information
| Field | Value |
|---|---|
| Address | 8320 |
| Zip Code | 85284 |

