Set Up a REST API Integration
Quick, efficient integration
Overview
Integrating with CSG Forte's REST API takes only a few simple steps. Once you're connected, you will have access to a robust payment processing solution that provides efficient access to your business' data.
Step 1: Creating a Sandbox Account
Your Sandbox account gives you the ability to create testing credentials, which you will need for authenticating test calls. The process of creating a Sandbox account differs between merchants and partners.
Merchant Process
If you are a merchant, navigate to the Forte Developer's Test Account sign-up page and enter your First Name, Last Name, Company Name, and Email address in the applicable fields. Forte uses this email address for verification purposes and as your Username for registering and signing into Dex, Forte's newest payment processing portal where you will create your credentials for this testing account.
Partner Process
If you are a partner, contact Forte's Sales Team and request a partner Sandbox account. Partner accounts in Dex have different permissions and different menu options.
Step 2: Generate Credentials
Verification and Registration
After requesting a Sandbox account, you will receive three emails: one from Forte Sales and two more from Dex. In the Dex email, "Verify Email," click the Verify Email Address button. Emails must be verified within 24 hours. After verifying your email address, open the Dex email, "You are invited to join Dex." Click the Accept Invitation button. A browser window opens where you can register for your Dex account. Dex registration requires a mobile phone number that can receive SMS messages for account verification.
Once you complete registration, Dex logs you into your new Dex organization as an Admin. A organization represents a legal entity that can own multiple sub-organizations (for partners) or multiple locations (for merchants) as well as the customers, payment methods, and transactions that belong to those locations (see location description below). Every request call made to the CSG Forte REST API must contain the organization_id
within the URI.
In addition to an organization, every Dex Sandbox account also comes with at least one location. Locations are processing endpoints that merchant organizations use to initiate transactions (in Forte legacy applications like Virtual Terminal, locations were known as MIDs). Locations own all the transaction data including sensitive payment method data and tokens. Tokens are random, alpha-numeric strings that represent stored, encrypted data. Tokenization is a common practice in the payment industry to protect sensitive data.
NOTE: For questions or help with Dex registration or setup, contact Forte Technical Support at 888-235-4635 option 5.
Creating Credentials
Before creating your first API request, you first have to create your API authentication credentials. These include an API Access ID, which acts as your username, and an API Secure Key, which acts as a password. You will create and maintain these credentials exclusively in Dex.
To generate your API Access ID and API Secure Key, complete the following steps:
-
From a Google Chrome browser, log into your Dex Account.
-
Select Developer > API Credentials from the Dex Main Menu.
-
Click the CREATE button. The Create API Credentials screen displays.
-
Enter a name for this set of API credentials in the Name field.
-
Click the CREATE NEW API KEY button. The API Access ID and API Secure Key values display in their corresponding fields.
-
Click the COPY button next to the API Access ID and API Secure Key fields to record both of these newly generated values in a secure location to use in authenticating your REST API requests.
NOTE: Once you save your API Secure Key, you will not be able to see the value again. If you forget your API Secure Key or it becomes compromised, you will have to regenerate the value in Dex.
Step 3: Integrating
To help you become familiar with the objects and methods of CSG Forte's REST API, we've created a Postman collection that you can download from our REST docs. Simply click the button that displays at the top of the screen. To help you become familiar with all the features of our REST API, this section will guide you through your first call creating a transaction.
Supported Actions
To begin crafting your call, you must choose an action and add its corresponding HTTP verb to the call. CSG Forte's REST API supports the following actions:
Action | HTTP Method | Description |
---|---|---|
Create | POST | Creates the resource that corresponds to the data type defined in the endpoint. For example, making a POST call to the transactions URI creates a new transaction.
|
Find | GET | Returns summary information for all the resources that match the provided query parameters. For example, performing a GET call to the customers URI returns all the customers associated with that specific merchant location. To return comprehensive/detailed information on a specific resource, provide the resource’s ID to the defined URI. For example, to find a specific customer associated with a merchant location, perform a GET call to the customers endpoint and include the customer_token filter parameter in the URI |
Update | PUT | Modifies the existing resource for the provided URI. All PUT calls require the resource’s ID. |
Delete | DELETE | Deletes the existing resource for the provided URI. All DELETE calls require the resource’s ID. |
Since we want to create a transaction in our call, we'll use the POST verb.
curl --location -g --request POST
Defining the Resource Path
Resource paths define where you want the action to occur. All resource paths contain two components, the base URI, that identifies Forte's server and environment, and an endpoint that identifies the merchant, location, and resource where the action should occur.
Base URI
When constructing a call, you will append the endpoint to one of the following base URIs for the specified environments:
URI | Environment | |
---|---|---|
https://sandbox.forte.net/api/v3 | Sandbox | |
https://api.forte.net/v3 | Production |
Endpoint
Forte's API has 14 resources where records can be created, searched for, updated, or deleted. All endpoints must begin by identifying the specific organization resource (your Organization ID). Most endpoints also require specifying a location resource (your Location ID or MID).
curl --location -g --request POST '{{baseURI}/organizations/org_300005/locations/loc_115161/
These values identify the merchant and location where an action will be performed.
Note how each numerical ID is preceded by three characters. This is called object prefixing. Rather than resource paths containing nothing but ID numbers and tokens, an object prefix identifies the resource to which the ID number or token belongs. This helps with troubleshooting in the event of an error response.
All resources must be prefixed for the call to be successful, particularly if the request is for specific records (like in GET, PUT, and DELETE calls). The following table displays the prefixing standards used by Forte for each resource:
Object | Prefix | Example |
---|---|---|
Addresses | add_ + Token | add_jUYRwbRjKUWgswNrFpSdKg
|
applications | app_ + ID | app_258741
|
bankaccounts | bac_ + Token | bac_48BdhGkl6UOtnrO4BmoeWg
|
customers | cst_ + Token | cst_SoGUG6mcLUS1nVzYBIbk3g
|
disputes | dsp_ + ID | dsp_2365435-e4ae-4ff4-a91e-abd8kjjfjffffc
|
documents | doc_ + ID | doc_3131dddgwef0gpV2eYlo5
|
funding | fnd_ + ID | fnd_ACH-0226-173C5 |
locations | loc_ + ID | loc_100000 |
organizations | org_ + ID | org_200000 |
paymethods | mth_ + Token | mth_ymC20TMkHE-YmYxMt0UvMA |
scheduleitems | sci_ + GUID | sci_4690fbfb-0b77-4477-a066-2c07ca2e5a3c |
schedules | sch_ + GUID | sch_2e5770ae-c120-414f-ae8c-d065753567e7 |
settlements | stl_ + GUID | stl_51cf4633-1767-484f-8784-be76a4076791 |
transactions | trn_ + GUID | trn_55c98c85-d3e8-4230-85e9-21d7d522eec0 |
Forte's REST API Endpoint reference includes a listing of all available resource endpoints for POST, GET, PUT, and DELETE actions.
Example
Going back to our Create Transaction call, we can now add the complete resource path, or URI, to the call. Fill in the IDs with your own organization and location IDs.
curl --location -g --request POST 'https://sandbox.forte.net/api/v3/organizations/org_{organizationID}/locations/loc_{locationID}/transactions' \
Create Headers
To ensure our call is secure and readable, we now need to add headers. Requests to Forte's REST API must be authenticated using the Authorization
header field and the custom header property, X-Forte-Auth-Organization-Id
.
Authorization Header
Forte's REST web services rely on Basic access authentication over HTTPS using the API Access ID and API Secure Key (i.e., the credentials you created in Step 2 above) as the username and password values, respectively. These unique values are combined with a colon and then encoded using the RFC2045-MIME variant of Base64. The encoded string is then added to the HTTP Authorization
header. For example, if you created the following API credentials:
-
API Access ID =
315c7649520edde96c5cbad59a5b265f
-
API Secure Key =
c233f2958bd855d09d98397e74950640
The value of the Authorization
header field would look like the following:
Authorization=Basic MzE1Yzc2NDk1MjBlZGRlOTZjNWNiYWQ1OWE1YjI2NWY6YzIzM2YyOTU4YmQ4NTVkMDlkOTgzOTdlNzQ5NTA2NDA=
Several different online tools can help you create your Authorization
header, such as Postman. You can also add Base64 encoding to HMAC requests to automatically convert the API Access ID and API Secure Key values into the encoded ASCII string. To do so, use the following code:
Convert.ToBase64String(Encoding.Default.GetBytes(APIAccessID + ":" + APISecureKey)).Trim()
X-Forte-Auth-Organization-Id Header
The custom header property X-Forte-Auth-Organization-Id
specifies at which organization Forte should authenticate the request. A partner can authenticate his or her Organization ID in the X-Forte-Auth-Organization-Id
header property and then can access merchant sub-organizations by specifying the merchant Organization ID in the URI of the request.
Accept Header
Forte’s REST service supports Content Negotiation through the Accept
header sent in the request call.
The default value for Accept
headers is application/json which returns JSON responses. However, you can also use application/xml which returns XML responses.
The Content-Type Header
The Content-Type
header is only required for POST and PUT calls. Like the Accept
header, the Content-Type
header supports both application/json and application/xml. The default value for Content-Type
headers is application/json.
Example
For our example request, we'll add our headers for authentication:
curl --location -g --request POST 'https://sandbox.forte.net/api/v3/organizations/org_{organizationID}/locations/loc_{locationID}/transactions' \
--header 'Authorization: {{Authorization}}' \
--header 'Accept: application/json' \
--header 'X-Forte-Auth-Organization-Id: org_{{AuthOrganizationID}}' \
--header 'Content-Type: application/json' \
Adding Parameters
Only POST and PUT requests include parameters since these actions are adding resources or updating existing resources. GET or DELETE requests require only the action, the resource path, and the headers. The CSG Forte REST docs list the available parameters for each object in a resource. At a minimum, you must include the required parameters of each object for every request. For our Create Transaction example, we'll use the minimum required parameters to create a credit card transaction:
curl --location -g --request POST 'https://api.forte.net/v3/organizations/org_{{organizationID}}/locations/loc_{{locationID}}/transactions' \
--header 'Authorization: {{Authorization}}' \
--header 'Accept: application/json' \
--header 'X-Forte-Auth-Organization-Id: org_{{AuthOrganizationID}}' \
--header 'Content-Type: application/json' \
--data-raw '{
"action":"sale",
"authorization_amount": 102.45,
"subtotal_amount": 99.95,
"billing_address":{
"first_name": "Jennifer",
"last_name": "McFly"
},
"card":{
"card_type": "visa",
"name_on_card": "Jennifer McFly",
"account_number": "4111111111111111",
"expire_month": "12",
"expire_year": "2017",
"card_verification_value":"123"
}
}'
If formatted and authenticated correctly, this call will produce the following 201 - Created
success response.
{
"transaction_id": "trn_9eab1d30-5326-4d15-b500-5d04c1e74839",
"location_id": "loc_192642",
"action": "sale",
"authorization_amount": 102.45,
"entered_by": "4fefaf5f77d944ce10bdd3d88f7a2da9",
"billing_address": {
"first_name": "Jennifer",
"last_name": "McFly"
},
"card": {
"name_on_card": "Jennifer McFly",
"last_4_account_number": "1111",
"masked_account_number": "****1111",
"expire_month": 12,
"expire_year": 2017,
"card_type": "visa"
},
"response": {
"environment": "live",
"response_type": "A",
"response_code": "A01",
"response_desc": "TEST APPROVAL",
"authorization_code": "123456",
"avs_result": "Y",
"cvv_result": "M"
}
}
Responses echo back all the parameters included in the body of the request. NOTE: Optional request parameters whose values are null do not echo back in responses.
Forte includes all the applicable parameters of the response object in responses returned to the client. The following table displays the response object and the string parameters returned for each resource request.
Parameter | Description |
---|---|
response_desc
|
A short description of the action's response. All resources use this parameter. |
environment
|
The environment in which the user made the request. The value for this field can be either live or sandbox . All resources use this parameter. |
authorization_code
|
The code indicating whether or not the transaction was authorized. This field is not used for voiding transactions. |
response_type
|
The type of response this action generated:
|
response_code
|
The response code of the action. |
preauth_result
|
Pre-authorization check result from Forte Verify with the following possible values:
|
preauth_desc
|
Pre-authorization check description from Forte Verify. |
preauth_neg_report
|
Negative database response information (unformatted) when pg_preauth_result=NEG . |
avs_result
|
Forte only returns this field if the merchant passes any combination of billing address parameters from the
|
cvv_result
|
The card verification value response. Supported values for this field include the following:
|
available_card_balance |
The available balance on the credit card if a credit card is used for the transaction. |
requested_amount
|
The transaction amount |
Monitoring Transactions
After creating a transaction, you can track its progress via two different methods: webhook subscriptions and smart querying. Both webhook subscriptions and smart querying can provide accurate real-time or near real-time updates.
Webhook Subscriptions
NOTE: At this time, only CSG Forte's Technical Support Team (866-290-5400 option 5) can configure webhooks.
Webhooks are postback messages that Forte sends to unique, server-side URL endpoints, which you provide. These messages can be used to verify information so that you can perform tasks in your own system, such as
-
Shipping merchandise
-
Updating invoice and accounting applications
-
Maintaining current customer and payment method data for marketing collateral
-
Tracking transactions that customers dispute
Webhook messages are triggered by transaction events. An event is an action that occurs during the progression of the transaction from capture to processing. For example, for the Create Transaction call you just created, three events occur: transaction.sale
, customer.create
, and paymethod.create
. You can configure your webhooks to capture all the events of a transaction under a common event ID (e.g., evt_xxxxxx) or configure different webhooks to capture different combinations of events. This is referred to as a webhook subscription.
You can configure up to 25 webhook subscriptions for your organization. To configure a webhook, contact Technical Support and provide them with the following information:
Field | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Name | The name of the webhook. The value of this field should be concise and capture what events this webhook will record (see below). | ||||||||||||
Status | The status of the webhook. Use the dropdown to select the supported options: Active or Pending. | ||||||||||||
URL | The secure URL endpoint where Forte will post this webhook. At a minimum, this URL should be an SSL-encrypted, dedicated page on your own server. | ||||||||||||
Events |
The action(s) that will be captured by this webhook.
|
Technical Support will configure the webhook and provide you with a webhook_key
value. Use the webhook_key
to compute the value of the signature parameter and then compare it to the value of the webhook's X-Forte-Signature
HTTP header. If these values match, then the webhook is authenticated. A signature
comparison ensures the webhook came from Forte and that no one tampered with the webhook's payload.
The signature
parameter is computed with a hash-based message authentication code (HMAC) using a secret key (i.e., webhook_key
) and a SHA256 digest algorithm:
HMACSHA256(webhook_url|payload|utc_time, webhook_key)
Where
Parameter | Description | Example |
---|---|---|
webhook_url
|
The all-lowercase webhook URL. Requires the HTTPS URI scheme to protect privacy and data integrity. | https://www.mycompany.com/webhook/pay.aspx |
payload
|
The JSON contents of the webhook. |
|
utc_time
|
UTC time in ticks (since 01/01/0001 00:00:00) sent in the x-forte-utc-time header parameter. |
634094514514687490
|
webhook_key
|
The webhook key. This value is unique for each webhook endpoint that you define. | AD6cNaWFoDla5VXqN2clfJjkGnCo6TNc
|
The following signature
formula example uses values that come from the examples displayed in the parameter table above.
HMACSHA256(https://www.mycompany.com/webhook/pay.aspx|{ "location_id":"loc_115161", "event_id":"evt_o5bgfKnXbEKmPyp06-dZ3Q",
"paymethod":{ "paymethod_token":"mth_jKxUPnIYTMq8iMqjp4CcsQ", "organization_id":"act_300005", "location_id":"loc_115161",
"customer_token":"cst_9s7_JzBUT9eCnuW6Wkwcug", "label":"Visa Credit Card - 1111", "notes":"", "card":{ "name_on_card":"John Smith",
"masked_account_number":"************1111", "expire_month":11, "expire_year":2025, "procurement_card":false, "card_type":"visa" },
"links":{ "self":"https://sandbox.forte.net/API/v3/paymethods/mth_jKxUPnIYTMq8iMqjp4CcsQ" } }, "source":"RESTAPI/3",
"type":"payment.create", "environment":"live" }|634094514514687490, AD6cNaWFoDla5VXqN2clfJjkGnCo6TNc)
When put through the HMACSHA256 algorithm with the webhook secret key value of AD6cNaWFoDla5VXqN2clfJjkGnCo6TNc
, the formula renders the following value:
30eaf51928aea79e67de3396578862254eeb4a8b0ae85550bdd7ae87c5708fb9
If the webhook payload is secure and the webhook can be authenticated from Forte, this signature
value will match the value that is returned in the webhook's X-Forte-Signature
HTTP header field:
Accept: application/json
Content-Type: application/json
X-Request-Id: 7066f5f3-33a0-47a8-9f03-a0e94b4b2a5f
X-Forte-Utc-Tim: 634094514514687490
X-Forte-Signature: 30eaf51928aea79e67de3396578862254eeb4a8b0ae85550bdd7ae87c5708fb9
Using the Create Transaction call we configured above, lets assume our organization is subscribed to transaction.sale
webhook events. The webhook generated for this call would look similar to the following.
Headers
Accept: application/json
Content-Type: application/json
X-Request-Id: 7066f5f3-33a0-47a8-9f03-a0e94b4b2a5f
X-Forte-Utc-Time: 634094514514687490
X-Forte-Signature:d718baf56c64ee53a0eb2702744b7043bc6e246c31fd72688b406c38486b48b7
Raw Body
{
"location_id":192642,
"event_id":"evt_IO-4Mw9PYEyipIgkNty2vw",
"transaction_id": "trn_9eab1d30-5326-4d15-b500-5d04c1e74839",
"location_id": "loc_192642",
"action": "sale",
"authorization_amount": 102.45,
"entered_by": "4fefaf5f77d944ce10bdd3d88f7a2da9",
"billing_address": {
"first_name": "Jennifer",
"last_name": "McFly"
},
"card": {
"name_on_card": "Jennifer McFly",
"last_4_account_number": "1111",
"masked_account_number": "****1111",
"expire_month": 12,
"expire_year": 2017,
"card_type": "visa"
},
"response": {
"environment": "live",
"response_type": "A",
"response_code": "A01",
"response_desc": "TEST APPROVAL",
"authorization_code": "123456",
"avs_result": "Y",
"cvv_result": "M"
}
},
"source":"ForteCO",
"type":"transaction.sale",
"environment":"sandbox"
Smart Querying
Another method for monitoring transactions is via smart querying, where you make strategic GET calls to the settlements
endpoint to gather pertinent transaction information. While querying individual transactions can tell you whether a transaction has settled, you don’t want to bog down the transactions
endpoint with unnecessary requests for updates—especially when you’re tracking thousands of transactions. This can significantly slow down your payment processing ability as Forte throttles API requests to 10 per second.
Since settlement times can vary depending on transaction parameters and your merchant location setup, you’ll want to create strategically timed queries using the settle_date
filter of the settlements
object. Use these date and timestamp queries to poll daily or intermittently throughout the day to synchronize and reconcile your data.
Querying Settlements
Transaction settlements can come in throughout the day. Rather than constantly polling the settlements object for new data, we recommend using date and timestamp queries using the settle_date
filter parameter in the URI to keep systems synchronized. This can include a daily query for the prior day’s activity or multiple, intra-day queries. When setting up these GET calls, allow for a short period of time (i.e., 15 minutes) for the data to propagate (e.g., run the 1AM–4AM query at 4:15AM). Use additional filter parameters like method
or settle_response_code
to narrow your results further. Using the timestamp filter ensures the response contains only settlements that Forte received since the previous query.
The following sections include common use cases for smart querying the settlements
object.
Single Query for Prior Day Activity
The following query captures all the settlement activity between midnight, October 1, 2019 and midnight, October 2, 2019. We would run this query at 12:15AM on October 2, 2019 to include data propagation time.
curl --location --request GET "https://api.forte.net/v3/organizations/org_{{organizationID}}/locations/loc_{{locationID}}/settlements/?filter=start_settle_date+eq+2019-10-01T00:00:00+AND+end_settle_date+eq+2019-10-2T00:00:00" \
--header "Authorization: {{Authorization}}" \
--header "Accept: application/json" \
--header "X-Forte-Auth-Organization-Id: org_{{AuthOrganizationID}}" \
--data ""
Hourly Queries
For near-real-time results, use hourly queries to capture transaction updates.
1:15AM Query
curl --location --request GET "https://api.forte.net/v3/organizations/org_{{organizationID}}/locations/loc_{{locationID}}/settlements/?filter=start_settle_date+eq+2019-10-01T00:00:00+AND+end_settle_date+eq+2019-10-1T01:00:00" \
--header "Authorization: {{Authorization}}" \
--header "Accept: application/json" \
--header "X-Forte-Auth-Organization-Id: org_{{AuthOrganizationID}}" \
--data ""
2:15AM Query
curl --location --request GET "https://api.forte.net/v3/organizations/org_{{organizationID}}/locations/loc_{{locationID}}/settlements/?filter=start_settle_date+eq+2019-10-01T01:00:00+AND+end_settle_date+eq+2019-10-1T2:00:00" \
--header "Authorization: {{Authorization}}" \
--header "Accept: application/json" \
--header "X-Forte-Auth-Organization-Id: org_{{AuthOrganizationID}}" \
--data ""
3:15AM Query
curl --location --request GET "https://api.forte.net/v3/organizations/org_{{organizationID}}/locations/loc_{{locationID}}/settlements/?filter=start_settle_date+eq+2019-10-01T02:00:00+AND+end_settle_date+eq+2019-10-1T3:00:00" \
--header "Authorization: {{Authorization}}" \
--header "Accept: application/json" \
--header "X-Forte-Auth-Organization-Id: org_{{AuthOrganizationID}}" \
--data ""
4:15AM Query
curl --location --request GET "https://api.forte.net/v3/organizations/org_{{organizationID}}/locations/loc_{{locationID}}/settlements/?filter=start_settle_date+eq+2019-10-01T03:00:00+AND+end_settle_date+eq+2019-10-1T4:00:00" \
--header "Authorization: {{Authorization}}" \
--header "Accept: application/json" \
--header "X-Forte-Auth-Organization-Id: org_{{AuthOrganizationID}}" \
--data ""
Continue these queries for the remaining 20 calls. While this method can provide accurate and near-real-time results, it's not the most efficient method. Forte recommends using webhook subscriptions for the most accurate and efficient method of tracking transaction events. Single transaction queries should be used on a very limited basis for user-initiated, real-time status updates instead of for general synchronization. NOTE: Most transactions only have one settlement entry, but due to disputes and returns, some transactions may have multiple settlement entries.
Going Further
Now that you've created your first call, you can test additional calls for different resources. Create a customer profile or two and then search for a specific customer. Create a credit card or echeck payment profile for each customer and test different types of transactions. For a full list of potential test calls, see CSG Forte's REST API docs.
Step 4: Go Live
Once you've completed your testing in Sandbox and established your merchant account with Forte, you're ready to go Live in production.
When Forte enrolls you as a new merchant, you'll receive your production Organization ID and, if applicable, Location ID. These values may be different than the Organization ID and Location ID for the Sandbox account you created on the Forte Developer's Test Account sign-up page or the test account provided to you by the Sales Team. If so, ensure you change these values in your integration.
Additionally, you will need to change the Base URI of the resource path to https://api.forte.net/v3
, to point to the Live environment.
Finally, Sandbox credentials do not carry over to Live, so you'll need to create and implement new API credentials into your integration. Fortunately, the process to create new credentials in Live is the same process in Sandbox. After creating new Live credentials remember to update/recreate your authentication headers before sending your first Live request.
Once you've changed these values in your integration, you can craft your first Live call.