This document describes how to integrate your website with the SALT Credit Card API. This document provides a step-by-step guide to completing the integration process as well as information on test and configuration tools available to you.
The following is a list of abbreviations, acronyms, and terms that are used throughout this document:
Term | Definition |
---|---|
API | Application Programming Interface |
Approval (or Authorization) Code | Code obtained from the credit card processing network that is required to complete any credit card transaction. Note that the Approval/Authorization code is not a guarantee of acceptance or payment of a transaction. Receipt of an approval/authorization code does not mean that the merchant will not receive a chargeback for that transaction. |
CVV2 (a.k.a. CVD) | Card Verification Value. A three or four digit code which is printed on a credit card, but which is not a part of the card number. |
Elavon | Company providing access to the credit card payment processing network, c/o SALT. |
HTML | Hyper Text Markup Language |
HTTPS | Secure Hyper Text Transfer Protocol |
Issuer | A Bank/Financial Institution issuing credit cards |
SSL | Secure Sockets Layer |
To get a better understanding of what is involved in the integration process, you should first understand the workflow of the SALT Credit Card API.
The SALT Credit Card API Solution workflow consists of four phases, as illustrated in the following diagram:
At-a-glance, the process of integrating with the Credit Card API consists of the following steps:
Step | Description | |
---|---|---|
1) | SALT Sandbox Environment | Accessing/familiarizing yourself with the SALT Sandbox environment. |
2) | Working with the SALT API | Writing the HTML POST that will allow you to send transactions to the SALT Payment Handler. |
3) | Working with Receipts | Writing HTML/web scripting code to display the receipt from transaction data returned by the API. |
4) | Certification | Working with SALT to ensure that your completed web application meets the requirements set out by Elavon for any merchant using credit card payment processing. |
5) | Going into Production | Moving from the Sandbox environment to the production environment. |
The SALT Sandbox Environment is a environment mirroring the production environment that allows you to perform testing and integration before going into production.
If you don't yet have a Sandbox account, you can create one by following the link below!
URL | Description | |
---|---|---|
SALT Merchant Management Website | https://test.saltpayments.com/merchantmanagement/ | Allows you to perform administrative tasks such as viewing transaction activity and configuring your services. |
SALT Payment Gateway | https://gateway-uat.saltpayments.com/gateway/creditcard/processor.do | Receives Credit Card API requests |
The SALT Merchant Management Console requires a login, which consists of a Username and Password set by you when creating your Sandbox account. You can change your password at any time.
In order to process payments through your Sandbox account, you will need to retrieve your Sandbox Merchant Credentials - merchantId
and apiToken
. To find your credentials:
merchantId
and apiToken
.You will need to use the SALT Credit Card API to perform credit card transactions.
Before working with the SALT Core API, ensure that you have downloaded the client library file to your computer. The Core API consists of a single package package com.salt.payment.client.creditcard.api
with two main classes:
HttpsCreditCardService
- Calls the SALT Payment Gateway to process credit card transactions, such as purchases, voids, and refunds.
CreditCardReceipt
- A container class for the HttpsCreditCardService
method response.
These classes and their methods will be described in full in the following sections.
To process a credit card transaction, you will need to construct an instance of the HttpsCreditCardService
class as follows:
HttpsCreditCardService(merchant, url)
|
||
Name | Type | Description |
---|---|---|
merchant | Merchant | Contains your merchant credentials. See Table 3.2. |
url | String(255) | URL to the SALT Core API handler. In the environment this ishttps://gateway-uat.saltpayments.com/gateway/creditcard/processor.do |
HttpsCreditCardService
from API versions 1.3.1 or older, the old constructors are still supported but are now considered deprecated.
Merchant(merchantId, apiToken [, storeId])
|
||
Name | Type | Description |
---|---|---|
merchantId | Integer | Merchant ID as assigned to you by SALT (can check this in the Merchant Management Website). |
apiToken | String(20) | API Token as assigned to you by SALT (can check this in the Merchant Management Website) |
storeId OPTIONAL |
String(50) | Store ID field that can be used to identify/group transactions. Optional field. |
After you have created a new instance of HttpsCreditCardService
, you can use it to process transactions.
To perform a credit card purchase you will invoke the singlePurchase()
method:
HttpsCreditCardService.singlePurchase(orderId, creditCard, amount, verificationRequest)
|
||
Name | Type | Description |
---|---|---|
orderId |
String(32) |
Merchant assigned orderId. Must be unique. |
creditCard |
CreditCard |
Credit Card information (see Table 3.4) |
amount |
Long |
Amount of the purchase in cents. Do NOT include a $ or any decimal place. (e.g. if your purchase is $10.00, then send 1000 as the total). |
verificationRequest |
VerificationRequest |
Credit Card Verification request information, null if not used. See Section 5 for details on how to use this field. |
Returns: | ||
CreditCardReceipt |
The results of the purchase request |
The customer credit card information is submitted using the data object CreditCard. The basic constructor is shown below.
CreditCard Constructor Parameters | ||
Name | Type | Description |
---|---|---|
creditCardNumber |
Long |
Credit Card Number |
expiryDate |
Short |
Credit Card Expiry Date in MMYY format |
To use advanced features such as Address Verification System and CVV, you will have to use the full constructor that provides additional fields. See Section 5.1 for details.
The CreditCardReceipt object contains the results of the Purchase:
CreditCardReceipt | ||
Field | Type | Description |
---|---|---|
getApprovalInfo() |
ApprovalInfo |
Transaction approval information |
getAvsResponse() |
AvsResponse |
The AVS response from processing the purchase, or null if AVS was not enabled or no response. See Section 5 |
getCardBrand() |
Integer |
Returns the brand of the credit card, as a number: 1=Visa, 2=MasterCard, 3=AMEX, 4=Discover, 5=Diners, 6=JCB, 7=Other |
getCvv2Response() |
Cvv2Response |
The CVV2 response from processing the purchase, or null if CVV2 was not enabled or no response. See Section 5 |
getDebugMessage() |
String(255) |
Debug message, if applicable |
getErrorCode() |
String(128) |
Error code, if applicable |
getErrorMessage() |
String(255) |
Error message, if applicable |
getOrderId() |
String(32) |
Merchant-assigned orderId |
getPeriodicPurchaseInfo() |
PeriodicPurchaseInfo |
Information about the periodic purchase, if this was a periodic purchase transaction |
getProcessedDateTime() |
Date |
Date/time when the transaction was processed |
getSanitizedCardNumber() |
String(20) |
Storage/display-safe version of the credit card number. E.g. 424242****4242 |
getTransactionId() |
Long |
SALT TransactionId for this transaction |
isApproved() |
Boolean |
Returns true if the request was approved, otherwise the request was declined due to some error. |
The ApprovalInfo object contains the transaction approval information of the Transaction:
ApprovalInfo | ||
Field | Type | Description |
---|---|---|
getApprovalCode() |
String |
Credit Card Approval Code |
getAuthorizedAmount() |
Long |
Amount authorized on approval, in cents |
getReferenceNumber() |
Integer |
Credit Card approval Reference Number |
getTraceNumber() |
Integer |
Credit Card approval Trace Number |
You may need to void or refund a purchase made by a customer from time to time. You can do this programmatically through the Core API (see below) but if you don't need/want to, you can perform refunds manually through the Merchant Management Website.
What is a Void? What is a Refund?
HttpsCreditCardService.voidTransaction(transactionId, transactionOrderId)
|
||
Name | Type | Description |
---|---|---|
transactionId |
Long |
The SALT transactionId of the transaction to void |
transactionOrderId |
String(32) |
The orderId previously assigned to the transaction that is to be voided. This is an extra check to prevent inadvertent voiding of a transaction. Not null. |
Returns: | ||
CreditCardReceipt |
The results of the void request |
HttpsCreditCardService.refund(purchaseId, purchaseOrderId, refundOrderId, amount) |
||
Name | Type | Description |
---|---|---|
purchaseId |
Long |
The SALT transactionId of the purchase to void |
purchaseOrderId |
String(32) |
The order id previously assigned to the purchase that is to be refunded. This is an extra check to prevent inadvertent refunding of a purchase. Not null. |
refundOrderId |
String(32) |
The merchant assigned orderId to be attached to this refund request. Will be generated if null. |
amount |
Long |
Amount to refund in cents. Do NOT include a $ or any decimal place. (e.g. if your purchase is $10.00, then send 1000 as the total). This value does NOT have to match the original purchase amount. |
Returns: | ||
CreditCardReceipt |
The results of the Refund Request |
The CreditCardReceipt object is the same as is described in Section 3.3.
Credit Card Void and Refund operations are subject to the following restrictions/conditions:
If you do not need/want to perform Void/Refund operations programmatically, you can always perform them manually using the Merchant Management Website:
You can use SALT Periodic Purchase features when the customer is billed periodically, or when splitting payment into a number of separate payments.
In the API version 1.4 and below, calling recurringPurchase() will automatically create, verify and process the transaction. However, starting in 2.0,
recurringPurchase()
will only create and verify the transaction. The funds are not immediately captured from the
customer credit card until executeRecurringPurchase()
is explicitly called.
You can set up a customer for recurring billing by using the recurringPurchase() method:
HttpsCreditCardService.recurringPurchase(periodicPurchaseInfo, creditCard, storageTokenId, verificationRequest) |
||
Name | Type | Description |
---|---|---|
periodicPurchaseInfo |
PeriodicPurchaseInfo |
Defines periodic-specific information, such as schedule, dates, and customer ID. See Table 3.10. |
creditCard |
CreditCard |
Credit Card information (see Table 3.4). If storageTokenId is provided, this will be ignored |
storageTokenId |
String |
Storage Token ID specifying the stored credit card to use for this purchase. Takes precedence over the creditCard field. |
verificationRequest |
Verification Request |
Credit Card Verification request information, null if not used. Note that CVV2 will not be stored/used in recurring purchases. See Section 5 for details on how to use this field. |
Returns: | ||
CreditCardReceipt |
The results of the purchase request. |
The periodicPurchaseInfo
object is constructed as follows:
PeriodicPurchaseInfo Constructor Parameters
|
||
Name | Type | Description |
---|---|---|
periodicTransactionId |
Long |
SALT recurring purchase ID returned when the purchase was originally created. Not applicable to new recurring purchases |
state |
State |
One of IN_PROGRESS, ON_HOLD, CANCELLED. Note a cancelled payment will not be run again and cannot be further modified. Not applicable to new recurring purchases. |
schedule |
Schedule |
The schedule on which to issue payments. See Table 3.11. If null, will default to monthly payments. |
perPaymentAmount |
Long |
Per-payment amount of the in cents. Do NOT include a $ or any decimal place. (e.g. if your purchase is $10.00, then send 1000 as the total). |
orderId |
String(32) |
Merchant assigned orderId. Must be unique. Cannot be modified after the first payment has been issued. |
customerId |
String(32) |
Optional meta field that can be used to describe a customer |
startDate |
Date |
The date of when to issue the first payment. If this date is null or in the past, then the first payment will be issued immediately. Cannot be modified after the first payment has been issued. |
endDate |
Date |
The date of when to end the payments. A payment will not be issued if it falls on this date. |
nextPaymentDate |
Date |
Change when the next payment will occur. Must be set between the start and end date (as currently defined or as modified by their respective parameters). Not used in a new recurring payment (startDate defines first payment date). |
Parameters Outside of the full constructor | ||
ExecutionType |
enum |
Has a value of either
If not provided, will default to |
setExecutionType(ExecutionType executionType) |
Sets the execution type to either manual or auto | |
getExecutionType() |
ExecutionType |
Returns the value of the execution type |
installmentNumber |
Integer |
The value of the instalment the periodic purchase transaction is on. (e.g. if there are 4 instalments, and the card is charged for the second time, the installmentNumber = 2) |
setInstallmentNumber(Integer installmentNumber) |
||
getInstallmentNumber() |
Integer |
Returns the installmentNumber |
You can define a custom schedule for when to issue recurring payments:
Schedule Constructor Parameters |
||
Name | Type | Description |
---|---|---|
scheduleType |
ScheduleType |
Schedule based on days, weeks, or months (See Table 3.12 ScheduleType Enumeration) |
intervalLength |
Short |
Payments will be issued every number of days/weeks/months |
ScheduleType |
|
Value | Description |
---|---|
MONTH | Schedule based on months |
WEEK | Schedule based on weeks |
DAY | Schedule based on days |
So for example, if you create a Schedule using scheduleType = WEEK and intervalLength = 2, then payments will be issued every two weeks.
Once a recurring purchase has been successfully created (with recurringPurchase() ), it can be executed by calling the executeRecurringPurchase()
method.
HttpsCreditCardService.executeRecurringPurchase(recurringPurchaseId, cvv2) |
||
Name | Type | Description |
---|---|---|
recurringPurchaseId |
Long |
SALT recurring purchase ID returned when the purchase was originally created. |
cvv2 |
String |
Card Verification Value/Card Verification Digits. This parameter provides optional verification when performing this transaction |
Returns: | ||
CreditCardReceipt |
The results of the transaction |
There are additional operations available that you can use to manage your recurring payments.
Putting a hold on a recurring payment means that further payments will be suspended until the recurring payment is resumed. You can resume payments by
calling the resumeRecurringPurchase()
method.
HttpsCreditCardService.holdRecurringPurchase(recurringPurchaseId) |
||
Name | Type | Description |
---|---|---|
recurringPurchaseId |
Long |
SALT recurring purchase ID returned when the purchase was originally created. |
Returns: | ||
CreditCardReceipt |
The results of the hold |
HttpsCreditCardService.resumeRecurringPurchase(recurringPurchaseId) |
||
Name | Type | Description |
---|---|---|
recurringPurchaseId |
Long |
SALT recurring purchase ID returned when the purchase was originally created. |
Returns: | ||
CreditCardReceipt |
The results of the hold |
You can cancel a payment entirely by calling the cancelRecurringPurchase()
method. This means that no further payments will be made regardless of whether
the payment has reached its endDate
. Note that you cannot resume or otherwise update a cancelled payment.
HttpsCreditCardService.cancelRecurringPurchase(recurringPurchaseId) |
||
Name | Type | Description |
---|---|---|
recurringPurchaseId |
Long |
SALT recurring purchase ID returned when the purchase was originally created. |
Returns: | ||
CreditCardReceipt |
The results of the cancellation |
To update the payment details of a recurring purchase such as when a customer credit card expires/is changed, you can use the updateRecurringPurchase()
method. Note that you cannot update a recurring purchase that has been cancelled or that has completed.
If any parameters provided are null, the existing corresponding fields will not be updated.
HttpsCreditCardService.updateRecurringPurchase(periodicPurchaseInfo, creditCard, storageTokenId, verificationRequest) |
||
Name | Type | Description |
---|---|---|
periodicPurchaseInfo |
PeriodicPurchaseInfo |
Defines periodic-specific information, such as schedule, dates, and customer ID. See Table 3.10. |
creditCard |
CreditCard |
Credit Card information (see Table 3.4). If storageTokenId is provided, this will be ignored |
storageTokenId |
String(32) |
Storage Token ID specifying the stored credit card to use for this purchase. Takes precedence over the creditCard field. |
verificationRequest |
VerificationRequest |
Credit Card Verification request information, null if not used. Note that CVV2 will not be stored/used in recurring purchases. See Section 5 for details on how to use this field. |
Returns: | ||
CreditCardReceipt |
The results of the update request |
The queryRecurringPurchase()
method is a convenience method that you can use to check the current status of a recurring purchase, including the last
successful payment made.
HttpsCreditCardService.queryRecurringPurchase(recurringPurchaseId) |
||
Name | Type | Description |
---|---|---|
recurringPurchaseId |
Long |
SALT recurring purchase ID returned when the purchase was originally created. |
Returns: | ||
CreditCardReceipt |
The results of the query retrieve the PeriodicPurchaseInfo field for periodic purchase fields. |
The PeriodicPurchaseInfo
object contains a subset of the fields from the class:
periodicTransactionId
the ID when the periodic purchase was originally created
state
current state of the periodic purchase
nextPaymentDate
next date the payment will be run
lastPaymentId
the transaction ID of the last successful payment run. You can use this ID to run a verifyTransaction()
to retrieve the transaction
information.
If you do not need/want to manage Periodic Payments programmatically, you can always perform them manually using the Merchant Management Website:
In certain cases when you are unsure of the results of the transaction, such as when a transaction times out, you may need to double-check its status. You
can run the verifyTransaction()
method to perform this check. This method returns a receipt containing the results of the transaction.
HttpsCreditCardService.verifyTransaction(transactionId, transactionOrderId) |
||
Name | Type | Description |
---|---|---|
transactionId |
Long |
The SALT transactionId of the transaction to verify |
transactionOrderId |
String(32) |
The orderId assigned to the transaction. |
Returns: | ||
CreditCardReceipt |
The results of the transaction verification request |
You must specify at least one of the transactionId
or transactionOrderId
arguments.
Note that if the specified transaction cannot be found, you will receive a not-found C111_TRANSACTION_DOES_NOT_EXIST
error in the receipt, as opposed to
the results of the transaction.
Use the verifyCreditCard()
method to check the validity of a credit card without charging the customer (i.e. a $0.00 transaction). A CreditCardReceipt
object is returned, containing information about the card
validity, Secure Storage information if the card uses Secure Storage and Fraud information if the card uses the Advanced Fraud Suite.
singlePurchase()
($1.00 is sufficient) instead.
HttpsCreditCardService.verifyCreditCard(creditCard, verificationRequest) |
||
Name | Type | Description |
---|---|---|
creditCard |
CreditCard |
Credit Card information (see Table 3.4) |
verificationRequest |
Verification Request |
Credit Card Verification request information, null if not used. See Section 5 for details on how to use this field. |
Returns: | ||
CreditCardReceipt |
The results of the verifyCreditCard request. (See Table 3.21) |
All batches are closed automatically every night at 12:00 am EST. If for some reason you want to close a batch manually during the day, this may be done by
invoking the closeBatch()
method. Note that this will NOT prevent the automatic daily batch closure.
HttpsCreditCardService.closeBatch() |
|
Returns: | |
CreditCardReceipt |
The results of the batch close |
Applies only when using the Advanced Fraud Sute. This function allows you to update fraud service with the appropriate credit card authorization status if you are using a non-SALT payment processing service.
HttpsCreditCardService.updateFraud(Long transactionId, String fraudSessionId, String auth) |
||
Name | Type | Description |
---|---|---|
transactionId |
Long |
Transaction ID number of the transaction whose fraud authentication is being updated. Cannot be null. |
fraudSessionId |
String |
Fraud Session ID string. Cannot be null. Used to track which merchant is preforming the fraud update. |
auth |
String |
Auth string. If null, will decline the update request. |
Returns: | ||
CreditCardReceipt |
The results of the fraud update |
When a transaction has been completed, you must display a receipt to your customer. The following section describes the requirements of a receipt.
The required receipt fields listed below include the corresponding CreditCardReceipt field name as returned by SALT (where applicable). Note that there are different fields to be displayed depending on if the transaction was successful or unsuccessful.
In the case of a Successful Transaction, you must display:
isApproved() == true
)
getOrderId()
)getApprovalInfo()
.getAuthorizedAmount()
field, be sure to convert back to dollars/cents
and also to include currency)
getProcessedDateTime()
)getApprovalInfo().getApprovalCode()
)In the case of an Unsuccessful Transaction, you must display:
isApproved() == false
)getProcessedDateTime()
)getOrderId()
)Do NOT display the Approval Code or Card Number to the customer on an Unsuccessful Transaction.
An example of an appropriate receipt for a successful transaction is shown below:
An Example Receipt Screen:
This receipt shows all required information, a print page link, and a return link. You can use this as a reference for the generation of your own receipt.
Below are two examples of an appropriate error page for an unsuccessful transaction:
Example Error Screen With Payment Retry:
Example Error Screen With No Payment Retry (Order Cancellation):
To use the Client API Credit Card security features, you will need to use the full constructor for the CreditCard
class, which includes additional data fields.
CreditCard Constructor Parameters |
||
Name | Type | Description |
---|---|---|
creditCardNumber |
Long |
Credit Card Number |
expiryDate |
Short |
Credit Card Expiry Date |
cvv2 |
String |
Card Verification Value/Card Verification Digits |
street |
String |
Cardholder street address |
zip |
String |
Cardholder zip/postal code |
secureCode |
String |
Verified by Visa/MasterCard SecureCode value |
cardHolderName |
String |
Credit Card Holder Name |
The Card Verification Value (sometimes known as CVV2 or CVN is a security feature for credit card transactions, giving increased protection against credit card fraud. It is a series of digits (3 or 4) that can be usually found on the back of a credit card.
Many card issuers will decline a transaction if the CVV2 is not provided. If the value provided by the customer does not match the value on file with the card issuer, the issuer may decline the transaction (although this is not always the case).
To use CVV2, you must
CreditCard
objectVerificationRequest
with the Cvv2Request
parameter set to CVV2_PRESENT
.singlePurchase()
method with the VerificationRequest
.Cvv2Request |
||
Value | Description | Indicator* |
---|---|---|
CVV2_NOT_SUBMITTED |
CVV2 value is deliberately bypassed or is not provided by the merchant. | 0 |
CVV2_PRESENT |
Cardholder states that the CVV2 value is present on the card and can be verified. | 1 |
CVV2_PRESENT_BUT_ILLEGIBLE |
Cardholder states that the CVV2 value is present on the card but it is illegible. | 2 |
CARD_HAS_NO_CVV2 |
Cardholder states that the card has no value imprint. | 9 |
* Denotes the indicator digit typically associated with CVV2 verification. Is not needed when using this API, but may be referred to in other documentation.
An example of a singlePurchase()
with CVV2 checking is shown below:
import com.salt.payment.client.creditcard.api.*; : : int merchantId=12345; // as assigned by SALT String apiToken="DNZHRC6dNgppYYzR"; // as assigned by SALT long pan=4242424242424242L; short expiry=1212; String invoice="order-12345"; // merchant invoice/orderId String cvv2="888"; // CVV2 digits long amount=3420; // in cents HttpsCreditCardService ccService = new HttpsCreditCardService( new Merchant(merchantId, apiToken), "https://gateway-uat.saltpayments.com/gateway/creditcard/processor.do"); // specify additional credit card parameters CreditCard creditCard = new CreditCard(pan, expiry, cvv2, null, null); // specify the VerificationRequest contains an AvsRequest and/or Cvv2Request VerificationRequest verify = new VerificationRequest( null, Cvv2Request.CVV2_PRESENT, ); CreditCardReceipt receipt = ccService.singlePurchase(invoice, creditCard, amount, verify); : : // Extract Results from CreditCardReceipt... : : // Verification results from CreditCardReceipt... Cvv2Response cvv2Response = receipt.getCvv2Response(); : :
The results of the CVV2 check are returned as a Cvv2Response
object as part of the CreditCardReceipt.
Cvv2Response |
||
Field (Accessor) | Type | Description |
---|---|---|
getCode() |
String |
CVV2 Response Code |
getMessage() |
String |
CVV2 Response Message |
The CVV2 response code will denote a match/mismatch:
Code | Description | Match |
---|---|---|
M | CVV2 Match | Match |
N | CVV2 No Match |
Mismatch |
P | Not Processed | Unknown |
S | Issuer indicates that CVV2 data should be present on the card, but the merchant has indicated data is not present on the card | Unknown |
U | Issuer has not certified for CVV2 or Issuer has not provided Visa with the CVV2 encryption keys | Unknown |
<blank> | CVV2 was not performed, occurs if you did not provide a cvv2 or an invalid cvv2 value | Unknown |
Note that if a CVV2 check results in a mismatch or is not supported by the cardholder financial institution, this does NOT necessarily mean that a transaction will be declined. Some financial institutions may decline but others will not. CVV2 gives you additional information on which you can base your decision whether or not to accept the transaction as legitimate . If the financial institution does not decline the transaction, and you choose not to accept the transaction, you must issue a void against it. (See Section 3.4 on how to perform a void)
Address Verification System (AVS) provides additional security by comparing a given billing address against the address on file at the cardholder financial institution. If an AVS check indicates that the address does not fully match, you may have cause to suspect a possibly fraudulent transaction.
The result of an AVS check is a letter code indicating the degree of match, which can be full, partial, or a mismatch. Some financial institutions, in particular those outside the US, Canada, and UK, may not support AVS checking which can result in a corresponding not supportedmresponse code being returned.
Note that if an AVS check results in a mismatch or is not supported by the cardholder financial institution, this does NOT necessarily mean that a transaction will be rejected. AVS only gives you additional information on which you can base your decision whether or not to accept the transaction as legitimate. If you choose not to accept the transaction, you must issue a void against it
To use AVS, you must
CreditCard
objectVerificationRequest
with the AvsRequest
parameter set.singlePurchase()
method with the VerificationRequest
.AvsRequest |
||
Value | Description | |
---|---|---|
VERIFY_STREET_AND_ZIP | Verify that both specified street number & name (combined) and zip/postal code of the cardholder matches the values in the cardholder issuer file. | |
VERIFY_ZIP_ONLY | Verify that specified zip/postal code of the cardholder matches the value in the cardholder issuer file. If this is specified, address will not be verified |
An example of a singlePurchase()
with AVS checking is shown below:
import com.salt.payment.client.creditcard.api.*; : : int merchantId=12345; // as assigned by SALT String apiToken="DNZHRC6dNgppYYzR"; // as assigned by SALT long pan=4242424242424242L; short expiry=1212; String invoice="order-12345"; // merchant invoice/orderId String avsStreet="123 Easy Street"; // AVS Street number and name String avsZip="A1B2C3"; // AVS ZIP/Postal code long amount=3420; // in cents HttpsCreditCardService ccService = new HttpsCreditCardService( new Merchant(merchantId, apiToken), "https://gateway-uat.saltpayments.com/gateway/creditcard/processor.do"); // specify additional credit card parameters CreditCard creditCard = new CreditCard(pan, expiry, null, avsStreet, avsZip); // specify the VerificationRequest contains an AvsRequest and/or Cvv2Request VerificationRequest verify = new VerificationRequest( AvsRequest.VERIFY_STREET_AND_ZIP, null ); CreditCardReceipt receipt = ccService.singlePurchase(invoice, creditCard, amount, verify); : : // Extract Results from CreditCardReceipt... : : // Verification results from CreditCardReceipt... AvsResponse avsResponse = receipt.getAvsResponse(); : :
The results of the AVS request are returned as an AvsResponse
object as part of the CreditCardReceipt
.
AvsResponse |
||
Field (Accessor) | Type | Description |
---|---|---|
getAvsErrorCode() |
String |
The code of the error that prevented AVS from being performed, or null if no error |
getAvsErrorMessage() |
String |
The message of the error that prevented AVS from being performed, or null if no error |
getAvsResponseCode() |
String |
The standard alphabetic AVS response code (see Table 5.7) |
getZipType() |
String |
The type of the zip (either zip or postal code) or null if there was an AVS error |
isAvsPerformed() |
Boolean |
true if AVS was performed, false if it wasn't |
isStreetFormatValid() |
Boolean |
true if the street format is valid, false otherwise |
isStreetFormatValidAndMatched() |
Boolean | true if the street format is valid and matches |
isZipFormatValid() |
Boolean |
true if the zip/postal code format is valid, false otherwise |
isZipFormatValidAndMatched() |
Boolean | true if the zip/postal code format is valid and matches |
The getResponseCode()
field indicates: a full match (both address and zip/postal match), a partial match (one field matches), a mismatch (both do not
match), or unknown (AVS may be unavailable/unsupported by this cardholder bank).
Code | Description | Match |
---|---|---|
A | Street address matches, but zip/postal does not (Domestic) | Partial |
B | Street address matches, but postal code not verified (International) | Partial |
C | Street address and postal code do not match (International) |
Mismatch |
D, M | Street address and postal code match (International) | Full Match |
E | AVS data invalid or not allowed for this card type | Unknown |
G | Non-US bank does not support AVS | Unknown |
I | Address not verified | Unknown |
N | Street address and postal code do not match (Domestic) |
Mismatch |
P | Postal code matches, but street address not verified (International) | Partial |
R | System unavailable (Domestic) | Unknown |
S | Bank Does not support AVS (Domestic) | Unknown |
U | Address information unavailable. Returned if the US bank does not support non-US AVS or if the AVS in a US bank is not functioning properly. | Unknown |
W, Z | Street address does not match, but zip code matches (Domestic) | Partial |
X, Y | Street address and zip code match (Domestic) | Full Match |
<blank> | AVS was not performed, occurs if you did not provide a billing address | Unknown |
AVS is not a foolproof security feature, so even if a full match is obtained, there is no guarantee that a transaction is not fraudulent. However, a partial, or better yet, full match makes it more likely that whoever is submitting the transaction is the real cardholder (since they have access to the correct address information, which typically only appears the cardholder statement).
Below are some suggestions for the interpretation/handling of AVS responses. Please note that these are just suggestions and the ultimate decision of whether or not to accept a transaction is still up to you. Also remember that if you do not want to accept a transaction, you must void it yourself.
With the Secure Storage API, merchants can remotely store credit card and other sensitive customer data with SALT to increase security and reduce the scope of PCI Compliance.
When information is stored with SALT, a Storage Token (which identifies the information in secure storage) is returned in response. This Storage Token can be used for all subsequent transactions including purchases and credit card verification.
HttpsCreditCardService.addToStorage(paymentProfile, storageTokenId)
|
||
Name | Type | Description |
---|---|---|
storageTokenId |
String(32) |
Optional. Specifies the identifier (storage token) for the stored information. Must be unique. If not provided, SALT will auto-generate one for you. |
paymentProfile |
PaymentProfile |
Contains the customer information to be stored. See Table 5.9 for details |
Returns: | ||
StorageReceipt |
The results of the storage request |
The PaymentProfile class contains a CreditCard data object as well as a CustomerProfile data object. The basic constructor is shown below.
PaymentProfile Constructor Parameters
|
||
Name | Type | Description |
---|---|---|
creditCard |
CreditCard |
Contains Credit Card information, optional. However, if you intend to run transactions with this PaymentProfile you must provide this field. |
customerProfile |
CustomerProfile |
Contains Customer information, optional. See Table 5.10 for details |
The CreditCard
class is described in Table 5.1. Note that CVV2 will not be stored, even if specified.
The CustomerProfile
class allows you to store various customer details such as name and address. All fields are completely optional you can choose to
store any or all of the following fields:
CustomerProfile
|
||
Field | Type | Description |
---|---|---|
setFirstName() |
String |
Customer first name |
setLastName() |
String |
Customer last name |
setAddress1() |
String |
Address 1 (first line of address) |
setAddress2() |
String |
Address 2 (second line of address) |
setCity() |
String |
City |
setProvince() |
String |
Province/State |
setPostal() |
String |
Postal/ZIP Code |
setCountry() |
String |
Country |
setPhoneNumber() |
String |
Customer Phone Number |
setFaxNumber() |
String |
Customer Fax Number |
setWebsite() |
String |
Customer website |
setLegalName() |
String |
Customer Company Legal Name |
setTradeName() |
String |
Customer Company Trade Name |
An example of storing customer data (credit card and customer profile) is shown below:
import com.salt.payment.client.creditcard.api.*; : : int merchantId=12345; // as assigned by SALT String apiToken="DNZHRC6dNgppYYzR"; // as assigned by SALT String storageTokenId="myToken-001"; // will be used to identify the storage record long ccNumber=4242424242424242L; // Credit Card Number short ccExpiry=1212; // Credit Card Expiry String firstName="John"; // Customer first name String lastName="Smith"; // Customer last name String address1="123 Easy Street"; // Customer address1 String postal="A1B2C3"; // Customer Postal code String phone="4165551234"; // Customer phone number HttpsCreditCardService ccService = new HttpsCreditCardService( new Merchant(merchantId, apiToken), "https://gateway-uat.saltpayments.com/gateway/creditcard/processor.do"); // credit card to store CreditCard creditCard = new CreditCard(ccNumber, ccExpiry); // customer profile details to store CustomerProfile customerProfile = new CustomerProfile(); customerProfile.setFirstName(firstName); customerProfile.setLastName(lastName); customerProfile.setAddress1(address1); customerProfile.setPostal(postal); customerProfile.setPhoneNumber(phone); // put together data into a payment profile PaymentProfile paymentProfile = new PaymentProfile(creditCard, customerProfile); // Store the data under the specified storageTokenId StorageReceipt receipt = ccService.addToStorage(storageTokenId, paymentProfile); : : // Use Results from StorageReceipt... if (receipt.isApproved()) { : : }
The results of the storage request are returned as a StorageReceipt
object. This is a data class similar to the CreditCardReceipt
, and contains the following fields:
StorageReceipt
|
||
Field | Type | Description |
---|---|---|
getDebugMessage() |
String |
Debug message, if applicable |
getErrorCode() |
String |
Error code, if applicable |
getErrorMessage() |
String |
Error message, if applicable |
getProcessedDateTime() |
Date |
Date/time when the transaction was processed |
getPaymentProfile() |
PaymentProfile |
Payment profile retrieved or updates (via the storage query or update methods). For creation/deletion, this field is null |
getStorageTokenId() |
String(32) |
The storageTokenId used. For storage record creation where no storageTokenId was specified, this will contain the value of the SALT-generated storageTokenId. |
isApproved() |
Boolean |
Returns true if the request was approved, otherwise the request was declined due to some error. |
Once you have created a Storage Token, you can use it in place of a CreditCard
object in any transaction that requires a credit card. The SALT Gateway will
use the storageTokenId
to look up the stored credit card information, which in turn will be used in the transaction.
To use the storageTokenId
, all you need to do is call the appropriate Storage Token transaction methods (which are the same as the credit card methods,
just replacing the credit card with the token). The Storage Token singlePurchase()
is shown below:
HttpsCreditCardService.singlePurchase(orderId, storageTokenId, amount, verificationRequest)
|
||
Name | Type | Description |
---|---|---|
orderId |
String(32) |
Merchant assigned orderId. Must be unique. |
storageTokenId |
String(32) |
Storage Token ID as returned to you/specified by you when the storage record was created, will specify the stored credit card to use for this purchase. |
amount |
Long |
Amount of the purchase in cents. Do NOT include a $ or any decimal place. (e.g. if your purchase is $10.00, then send 1000 as the total). |
verificationRequest |
Verification Request |
Credit Card Verification request information, null if not used. See Section 5.1 for details on how to use this field. Note that because CVV2 is not stored, you cannot specify a CVV2 check. |
Returns: | ||
CreditCardReceipt
|
The results of the purchase request |
There is a method that can provide the merchant a combined transaction for both purchase and secure storage creation.
HttpsCreditCardService.singlePurchase(orderId, storageTokenId, amount, verificationRequest)
|
||
Name | Type | Description |
---|---|---|
orderId |
String(32) |
Merchant assigned orderId. Must be unique. |
creditCard |
CreditCard |
Credit Card information (see Table 3.4) |
amount |
Long |
Amount of the purchase in cents. Do NOT include a $ or any decimal place. (e.g. if your purchase is $10.00, then send 1000 as the total). |
verificationRequest |
Verification Request |
Credit Card Verification request information, null if not used. See Section 5.1 for details on how to use this field. Note that because CVV2 is not stored, you cannot specify a CVV2 check. |
storageTokenId |
String(32) |
The secure storage token id that will be used to create storage record for this credit card. |
Returns: | ||
CreditCardReceipt
|
The results of the purchase request |
The other methods that can use the storageTokenId
are:
You can query and retrieve the contents of any previously stored customer information.
HttpsCreditCardService.queryStorage(storageTokenId)
|
||
Name | Type | Description |
---|---|---|
storageTokenId |
String(32) |
The Storage Token ID of the stored information to retrieve. |
Returns: | ||
StorageReceipt
|
The results of the query request |
You can access the data through StorageReceipt.getPaymentProfile()
and then retrieving the contained creditCard
and/or customerProfile
.
If you need to update/modify a stored record:
HttpsCreditCardService.updateStorage(storageTokenId, paymentProfile)
|
||
Name | Type | Description |
---|---|---|
storageTokenId |
String(32) |
The Storage Token ID of the stored information to update. |
paymentProfile |
PaymentProfile |
Customer information to be stored. Will overwrite any existing customer information. |
Returns: | ||
StorageReceipt |
The results of the update request |
The provided PaymentProfile
will overwrite any existing data. If a null value is provided for the PaymentProfile
creditCard
or customerProfile
parameters, then the corresponding stored data will be deleted. Note that even if you delete all of the data, the record itself will still exist (but be
blank).
If you need to delete a stored record altogether:
HttpsCreditCardService.deleteFromStorage(storageTokenId)
|
||
Name | Type | Description |
---|---|---|
storageTokenId |
String(32) |
The Storage Token ID of the stored information to delete. |
Returns: | ||
StorageReceipt |
The results of the delete request |
Deleting a record will free up the associated storageTokenId for re-use.
The customer must have a means to receive notification of the results of a transaction through a separate channel in addition to display on screen. This is to ensure that even in the case of an accident such as the customer closing their browser, the customer will still be able to determine if the transaction succeeded or failed.
Suggested means of implementing such a feature:
If you do not already have such a feature it is recommended that the Email Notification method be used for ease of implementation.
Your store must make a Privacy Statement/Policy clearly available to the customer. A Privacy Statement should tell the customer:
You must adhere to the following security and privacy requirements:
Credit card associations, including Visa and Mastercard, require that all merchants offering online credit card payment follow a set of standard guidelines for implementation. The process of verifying that your website meets the card association requirements is known as Certification.
Approval for processing may be contingent on meeting these guidelines, depending on your credit card processor.
A full Approval requires a fully-functional, secure and complete e-commerce website to be created by the merchant. Since you will want to obtain some kind of approval before actually starting integration, you will typically go for a Conditional Approval first if supported by your processor (see below).
A Conditional Approval can be granted to a merchant who has not yet integrated their site with the SALT Payment Gateway. A Conditional Approval means that you are guaranteed a full Approval so long as the payment portion of your site is completed.
As long as the informational parts of your website are complete (product, return/refund policy, delivery policy, and privacy policy), you can be conditionally approved.
Important notes about Conditional Approval:
Each merchant implementation must undergo a brief certification process to obtain approval. To complete certification, you will need to supply SALT with:
SALT and the processor will conduct a review of your site, and once this is complete you will receive the appropriate approval(s). Please ensure that you have met all website requirements before submitting your request.
The following self-assessment checklist summarizes the requirements that need to be met:
✔ | Requirement | Description |
---|---|---|
Correlation between business and product/service | There should be a correlation between the registered merchant name and the product/service offered. | |
Customer service contact provided | There must be a clear posting of a Customer Service Telephone # or Email Address. | |
Return/Refund policy | Return/refund policy is clearly stated on the merchant website. | |
Delivery policy | The merchant's delivery methods and timing are clearly described | |
*Display correct receipt |
The receipt presented to the customer after a successful or unsuccessful transaction must contain certain fields. Make sure to follow the guidelines presented in the Receipts section. |
|
*Display timeout warning (if applicable) |
Display a warning message to the customer if the customer has < 30 minutes to complete payment (e.g. their session times out). If there is no such restriction, no message needs to be displayed |
|
Product/service description | The product/service offered for sale is clearly described | |
*Display correct currency | Must indicate the currency of payment (e.g. USD, CAD). Explicitly indicate the currency type on the payment total | |
English language option | There must be an English translation option for foreign language websites | |
*Customer Notification | You must have some way for a customer to be notified/determine the status of a transaction. Follow the requirements presented in the Non-page-specific requirements section. | |
Age Verification | The website includes an age Verification process for products sold that require age verification (alcohol, tobacco etc.). | |
Customer Ready? | The website must be ready to accept real orders from customers at the website URL specified in your application the site should NOT use language/pages that imply that it is coming soon or under construction or use a testing URL (e.g. www.yourdomain.com/test) | |
Privacy Policy | Make sure a privacy policy/statement is clearly stated on your website. | |
*Secure Payment Page |
Ensure that you have an SSL Certificate protecting your payment information entry page. Follow the requirements presented in the Non-page-specific requirements section. |
* Required for full approval, but not required for conditional approval
Once certification is complete, you will be ready to move to the SALT Production environment. Moving to the Production environment involves changing the API handler URL to the production URL, and verifying your configuration settings in the production Merchant Management Website.
Production Site | URL |
---|---|
SALT Merchant Management Website | https://manage.saltpayments.com/merchantmanagement/ |
Payment API Handler | https://gateway-prod.saltpayments.com/gateway/creditcard/processor.do |
When you want to move to production:
The INTERAC Online and Credit Card Client API integrations are similar, with a few minor differences listed below:
Area | INTERAC Online | Credit Card |
---|---|---|
Client API URL | Ends with iop/merchantprocessor.do | Ends with cc/processor.do |
Purchase Transaction | Is created through an HTTP POST to the SALT Payment Handler | Is performed directly through the SALT Client API |
Entry of Payment Information | Banking information is entered at the customer online banking website, it is not seen by the merchant | Credit card information is entered into your website (but must not be retained) |
Transaction Types | Purchase, Refund (there is no Void or Periodic Purchase in IOP) | Purchase, Refund, Void, Periodic Purchase, Secure Storage |
Secure Payment Page | Not required because no banking information is entered on your website. | Page where credit card information is entered on your website must be protected by a valid SSL certificate |
The SALT Client API is available for Microsoft .NET (for both .NET Framework versions 1.1 and 2.0). Below is a sample code fragment of a single purchase with the .NET Client API (in C#):
using com.salt.payment.client.creditcard.api; : : int merchantId=12345; // your SALT merchantId string apiToken="a3fer6321asdf1HY"; // your SALT API token long pan = 4242424242424242; // Credit Card Number short expiry = 1212; // Credit Card Expiry string invoice="unique invoice"; // assign a unique invoice number long amount = 10000; // amount of txn HttpsCreditCardService ccService = new HttpsCreditCardService(new Merchant(merchantId, apiToken), "https://gateway-uat.saltpayments.com/gateway/creditcard/processor.do"); CreditCard creditCard = new CreditCard(pan, expiry); CreditCardReceipt resp = null; resp = ccService.singlePurchase(invoice, creditCard, amount, null); if(resp.isApproved()){ Console.WriteLine("TransactionId: {0}",resp.getTransactionId()); Console.WriteLine("ApprovalInfo: {0}", resp.getApprovalInfo().ToString()); } else { // display error for debugging: it is recommended not to display full error // message to external user Console.WriteLine("Error Code: {0} Message: {1}", resp.getErrorCode(),resp.getErrorMessage()); }
The SALT Credit Card Client API for Microsoft .NET package will contain the following:
Copy the admeriscc*.dll to your web bin folder. The Test executable files are provided so that you can quickly test some of the gateway functions from the command line. Run the executable(s) with no arguments for usage instructions.
The SALT Client API is available for PHP 4.3 (or greater). Below is a sample code fragment of a single purchase with the PHP Client API.
<?php include "HttpsCreditCardService.php"; : : $merchantId=12345; // your SALT merchantId $apiToken="a3fer6321asdf1HY"; // your SALT API token $pan = 4242424242424242; // Credit Card Number $expiry = 1212; // Credit Card Expiry $invoice="unique invoice"; // assign a unique invoice number $amount = 10000; // amount of txn $ccService = new HttpsCreditCardService($merchantId, $apiToken, "https://gateway-uat.saltpayments.com/gateway/creditcard/processor.do"); $creditCard = new CreditCard($pan, $expiry); $resp = $ccService->singlePurchase($invoice, $creditCard, $amount, null); if($resp->isApproved()){ print_r($resp->params); } else { // display error for debugging: it not recommended to display full error // message to external users echo "Error Code: " . $resp->getErrorCode() . "Message: " . $resp->getErrorMessage(); } ?>
Below is an example of a Single Purchase with Secure Storage in PHP:
<?php include "HttpsCreditCardService.php"; : : $merchantId=12345; // your SALT merchantId $apiToken="a3fer6321asdf1HY"; // your SALT API token $pan = 4242424242424242; // Credit Card Number $expiry = 1212; // Credit Card Expiry $invoice="unique invoice"; // assign a unique invoice number $amount = 10000; // amount of txn $storage="token123" // Credit Card Storage Token Id $ccService = new HttpsCreditCardService($merchantId, $apiToken, "https://gateway-uat.saltpayments.com/gateway/creditcard/processor.do"); $creditCard = new CreditCard($pan, $expiry); $resp = $ccService->singlePurchase($invoice, $creditCard, $amount, null, $storageTokenId); if($resp->isApproved()){ print_r($resp->params); } else { // display error for debugging: it is recommended not to display full error // message to external user echo "Error Code: " . $resp->getErrorCode() . "Message: " . $resp->getErrorMessage(); } ?>