Download OpenAPI specification:Download
The Versapay API offers operations in support of its flagship products:
Collaborative AR (formerly ARC) - accounts receivable platform with automated invoicing, effective collaboration, flexible payments and cash application to improve efficiency and customer relationships.
Importing & exporting customers, invoices, and payments.
Monitoring file based imports/batches.
Importing & exporting orders and processing order based payment transactions.
Ecommerce integrations.
PayPort - cloud based platform to electronically push and pull funds across the EFT / ACH network.
Moving funds using transactions and pre-authorized debit agreements.
A secure hosted checkout for accepting payments through your website or email.
Please contact us at support@versapay.com for support & setup of A/R invoicing integration, hosted checkout, and/or payment acceptance.
The current API version is Versapay API Reference (1.3.13)
.
Versapay commits to maintaining backward compatibility and existing API endpoints with each released version updating existing endpoints and/or introducing new endpoints.
Should Versapay require deprecation of a published API, Versapay will work with its API clients/users to confirm specific EOL/migration timelines with ample lead times, as well as endpoint migration strategies.
The UAT environment is a useful sandbox for integration testing where transaction settlements are simulated using test account numbers and test dollar amounts.
https://uat.versapay.com
Once integration testing is complete via the UAT environment, start sending your requests to the production URL to start moving money and/or integrating with Versapay.
https://secure.versapay.com
The standard rate limit is 120 requests per minute per IP address, but Versapay reserves the right to raise or lower that limit based on network conditions. When the rate limit is exceeded, APIs will return HTTP 403 Forbidden (Rate Limit Exceeded)
. Partner- or customer-specific rate limits can be established by special agreement.
Visit your account settings in UAT
(https://uat.versapay.com/account) or Production
(https://secure.versapay.com/account) to setup API credentials needed for authentication as well as webhooks to receive relevant callbacks from Versapay transaction processing.
You can generate/disable your API credentials as often as necessary for security reasons.
If you do not have an account, please contact Versapay Support for support & setup of AR invoicing integration, hosted checkout and/or payment acceptance for partner and/or API credential setup.
API requests are authenticated using API Token & Key
via HTTPS Basic Access Authentication.
Security Scheme Type | HTTPS |
---|---|
HTTPS Authorization Scheme | basic |
Simply provide the API Token & Key
values as the user
and password
parameters, using cURL for instance:
curl -u "Nvax...:UN0I..." -X POST https://secure.versapay.com/api/...
Alternatively, API requests can also be authenticated using JWT Token
via HTTPS Bearer Authentication.
Security Scheme Type | HTTPS |
---|---|
HTTP Authorization Scheme | bearer JWT |
JWT Tokens
, automatically generated alongside API Token & Key
, are displayed along with expiration in account settings as well as via authenticated /api/whoami
, see Authentication
Echo identity and account profile settings
Simply provide the JWT Token
in the authorization header, using cURL for instance:
curl -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbiI6Im54eDFaSjgzeXRNNmhtb3NGVExCIiwiZXhwIjoxNzEyOTU5NDA5fQ.adV6U1vW69Ypskt61uPL8hZ-4muvtM4FLM48QN6iCc4" -X POST https://secure.versapay.com/api/...
Visit your account settings in UAT
(https://uat.versapay.com/account) or Production
(https://secure.versapay.com/account) to setup API credentials needed for authentication as well as webhooks to receive relevant callbacks from Versapay transaction processing.
You can generate/disable your API credentials as often as necessary for security reasons.
If you do not have an account, please contact Versapay Support for support & setup of AR invoicing integration, hosted checkout and/or payment acceptance for partner and/or API credential setup.
API requests are authenticated using API Token & Key
via HTTPS Basic Access Authentication.
Security Scheme Type | HTTPS |
---|---|
HTTPS Authorization Scheme | basic |
Simply provide the API Token & Key
values as the user
and password
parameters, using cURL for instance:
curl -u "Nvax...:UN0I..." -X POST https://secure.versapay.com/api/...
Alternatively, API requests can also be authenticated using JWT Token
via HTTPS Bearer Authentication.
Security Scheme Type | HTTPS |
---|---|
HTTP Authorization Scheme | bearer JWT |
JWT Tokens
, automatically generated alongside API Token & Key
, are displayed along with expiration in account settings as well as via authenticated /api/whoami
, see Authentication
Echo identity and account profile settings
Simply provide the JWT Token
in the authorization header, using cURL for instance:
curl -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbiI6Im54eDFaSjgzeXRNNmhtb3NGVExCIiwiZXhwIjoxNzEyOTU5NDA5fQ.adV6U1vW69Ypskt61uPL8hZ-4muvtM4FLM48QN6iCc4" -X POST https://secure.versapay.com/api/...
Lists key account profile settings configured for the authenticated account
Successful Operation
Unauthorized
Production
UAT
{- "whoami": {
- "XbkkoXbkKOXbkKoXBkkOO": {
- "token": "2ABCDEFFF2ABC",
- "name": "CDS Client UAT",
- "sender_identifier": "cdscliuat",
- "jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbiI6Im54eDFaSjgzeXRNNmhtb3NGVExCIiwiZXhwIjoxNzEyOTU5NDA5fQ.adV6U1vW69Ypskt61uPL8hZ-4muvtM4FLM48QN6iCc4",
- "jwt_exp": 1712959409,
- "currency": "usd",
- "preferred_language": "en",
- "business_number": "333-222-3000",
- "address_1": "PO Box 2840",
- "address_2": "",
- "postal_code": "76902",
- "city": "San Angelo",
- "province": "TX",
- "country": "US",
- "branding_partner": null,
- "branding_partner_config": null,
- "merchant_accounts": [
- {
- "token": "MA28S4KCJLAJ",
- "acceptable_cards": [
- "master",
- "visa",
- "american_express",
- "discover"
], - "currency": "usd",
- "deposit_account_routing_number": "031201360",
- "nickname": "settlement",
- "gl_account": null,
- "mid": null,
- "tid": null,
- "deposit_account_masked_number": "XXX4567",
- "deposit_routing_account_hash_function": "sha-1",
- "deposit_routing_account_hash": "cb0f864628972ad90dc08ed44e1099c7005936ca"
}, - {
- "token": "MA7NLMGDG9F4",
- "acceptable_cards": [
- "master",
- "visa",
- "american_express",
- "discover"
], - "currency": "usd",
- "deposit_account_routing_number": "031201360",
- "nickname": "settlement-2",
- "gl_account": null,
- "mid": null,
- "tid": null,
- "deposit_account_masked_number": "XXX4568",
- "deposit_routing_account_hash_function": "sha-1",
- "deposit_routing_account_hash": "52dfefa6082a07eb1689b40b99686690d1995e58"
}, - {
- "token": "MA1F8B2E87AM",
- "acceptable_cards": [
- "master",
- "visa",
- "american_express",
- "discover"
], - "currency": "usd",
- "deposit_account_routing_number": null,
- "nickname": null,
- "gl_account": null,
- "mid": null,
- "tid": null,
- "deposit_account_masked_number": "",
- "deposit_routing_account_hash_function": "sha-1",
- "deposit_routing_account_hash": "da39a3ee5e6b4b0d3255bfef95601890afd80709"
}
], - "settlement_bank_accounts": [
- {
- "routing_number": "122105278",
- "token": "BA9DZBGGJGY1",
- "account_type": "checking",
- "currency": "usd",
- "nickname": null,
- "masked_account_number": "XXXXX6789",
- "routing_account_hash_function": "sha-1",
- "routing_account_hash": "95d63eb2e03b71d1971884ec9678bcf74623b2bf",
- "address": {
- "address_1": "",
- "address_2": "",
- "city": "",
- "province": null,
- "postal_code": "",
- "country": "US"
}
}, - {
- "routing_number": "122000247",
- "token": "BA7QBIQMUMQB",
- "account_type": "checking",
- "currency": "usd",
- "nickname": null,
- "masked_account_number": "XXXXXX1152",
- "routing_account_hash_function": "sha-1",
- "routing_account_hash": "384516d914a878c8280b132d22e567dc64e67676",
- "address": {
- "address_1": "",
- "address_2": "",
- "city": "",
- "province": null,
- "postal_code": "",
- "country": "US"
}
}, - {
- "routing_number": "999999999",
- "token": "BA9K62MMRTSS",
- "account_type": "checking",
- "currency": "usd",
- "nickname": null,
- "masked_account_number": "XXXXX9999",
- "routing_account_hash_function": "sha-1",
- "routing_account_hash": "6cbe786bc66848acf8a3e539e0899809059af8a5",
- "address": {
- "address_1": "501 S 8th St",
- "address_2": "",
- "city": "Minneapolis",
- "province": "MN",
- "postal_code": "55404",
- "country": "US"
}
}
], - "terminal_processors": [ ],
- "autopay_api_enabled": false
}
}
}
Versapay uses the Webhook pattern to POST updates to a HTTP (port 80) or HTTPS (port 443) URL you specify.
The specified URL must return a status code of 200 otherwise Versapay will continue attempting to deliver the POST up to a system defined number of attempts.
A webhook consumer must be idempotent in receiving replayed/duplicated webhook payload transmissions which may arise as a result of subscription configuration and event timing and/or retry scenarios.
You can view details for the latest notifications sent to your application by visiting /developers/webhook_responses
in uat or production.
Webhooks can receive updates for the following PayPort
entities:
State updates of any Transaction created by your account or going to your account. The request parameters will contain the same attributes as returned by viewing a transaction via GET /api/transactions/{token}
.
State updates of any Debit Agreement created by your account or sent to your account. The request parameters will contain the same attributes as returned by viewing a debit agreement via GET /api/debit_agreements/{token}
.
Webhooks can receive updates for the following Collaborative AR
entities:
Recent events for any Customer part of your supplier account. The request parameters will contain the same attributes as returned by viewing a customer via GET /api/exports/customer/{identifier}
.
Recent events for any Invoice part of your supplier account. The request parameters will contain the same attributes as returned by viewing an invoice via GET /api/exports/invoice/{number_or_id}
.
Recent events for any Payment part of your supplier account. The request parameters will contain the same attributes as returned by viewing a payment via GET /api/exports/payment/{reference_or_token}
.
Versapay will append a HMAC-SHA256 signature attribute to all webhook notifications. For instance:
POST http://your.domain.com/your/webhook/url
{
"to_account":"Example user",
"token":"5TH3ACC3AU21",
"transaction_reference":"",
"from_account":"First1 Last1",
"from_fund":"THE TORONTO-DOMINION BANK",
"transaction_type":"send_money",
"amount_in_cents":500,
"type":"transaction",
"created_by_user":"699cMPe6BAyqvVsZA5mo",
"message":"",
"state":"completed",
"link_url":"",
"email":"user@example.com",
"signature":"USYpBfZFQQHa2%2BT6UtDPUVFfUPP0aobWpXe5DE9hPOY%3D%0A"
}
To verify the authenticity of received webhook notifications:
Generate a single line request string concatenated with new line from:
Calculate the HMAC-SHA256 of the single line string along using your Versapay signing key (which is displayed on your webhook account settings) and Base64 the result.
URL Encode the HMAC and compare to the value of the signature
attribute for a match.
# Example of HMAC-SHA256 signature calculation - using Rails/Sinatra our POST payload is accessible via params
require 'openssl'
require 'base64'
require 'erb'
webhook_url = 'http://your.domain.com/your/webhook/url';
webhook_signing_key = 'v7aJHjbbxASKiwDW5wq6';
original_signature = params.delete(:signature)
sorted_key_values = params.keys.sort.map{ |key| "#{key}#{params[key]}" }.join
request_string = "POST\n#{webhook_url}\n#{sorted_key_values}"
expected_signature = ERB::Util.url_encode( Base64.encode64( OpenSSL::HMAC.digest(
OpenSSL::Digest::SHA256.new, webhook_signing_key, request_string
) ) )
puts "\nexpected signature: #{expected_signature}"
puts "\noriginal signature: #{original_signature}"
puts "\nauthentic? #{expected_signature == original_signature}"
Versapay will send a HMAC-SHA256 signature attribute to all webhook notification request headers under the key X-Versapay-Signature
To verify the authenticity of received webhook notifications:
/* Example of HMAC-SHA256 signature calculation - using JavaScript/Express our POST payload is accessible via req.body */
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const app = express(