Home > Java Client > Using the SDK


Using the SDK

This section explains how to request CyberSource services by using the Java SDK.

Requesting CyberSource Services

To request CyberSource services, you must:

nCreate a system that collects the information required for the CyberSource services

nCreate the ASP pages that do the following:

lAssemble the order information into requests

lSend the requests to the CyberSource server

lProcess the reply information

The CyberSource services use the SCMP API, which consists of name-value pair API fields. The name-value pair API fields you use for credit card orders are described in the Credit Card Services Using the SCMP API (PDF | HTML). The code in the examples in this section is incomplete. For complete sample programs, see the test programs in the test/ directory of the SDK.

Constructing and Sending Requests

To access CyberSource services, you must create and send a request that holds the required information. You need instances of these methods:

nICSClient — sends the request

nICSClientRequest — holds the information about your company and the customer

nICSClientOffer — holds the information about the item being purchased

This example shows basic code for requesting CyberSource services. In this example, Jane Smith is buying an item for $29.95.

Importing Classes

Add the following import statements:

import com.cybersource.ics.base.message.*;

import com.cybersource.ics.base.exception.*;

import com.cybersource.ics.client.message.*;

import com.cybersource.ics.client.*;

Creating the Client, Request, and Offer

You next create instances of the client, the request, and the offer, while handling a possible exception:

try {

ICSClient client = new ICSClient("../properties/ICSClient.props");

ICSClientRequest request = new ICSClientRequest();

ICSClientOffer offer = new ICSClientOffer();

} catch (ICSException e) {

System.out.println("Could not create client and/or message. ") +

    e.getMessage());

}

For more details about these classes and constructors, see API for the Java SDK. You can use a single instance of a client to send multiple requests that use different merchant IDs. For more information, see Using Multiple Merchant IDs.

Adding Services to the Request

You next indicate the service that you want to use by using the setField(String fieldname, String value) method:

request.setField("ics_applications", "ics_auth");

You can request multiple services by using commas to separate the service names. For example, you can request both credit card authorization and capture together (referred to as a “sale”) by using the following code:

request.setField("ics_applications", "ics_auth,ics_bill");

Adding Request-Level Fields

You next add request-level fields using the setField(String fieldname, String value) method. This includes basic information about the customer and your company. Some of the fields that you set in a request correspond to properties in the ICSClient.props file. Setting the values in the request overrides the values in the properties file.

If you request multiple services that share common fields, you must add the field only once.

request.setField("customer_firstname", "Jane");

request.setField("customer_lastname", "Smith");

request.setField("customer_cc_number", "4111111111111111");

The example above shows only a partial list of the fields required for the request. For a full list of the request fields for the CyberSource credit card services, see the Credit Card Services Using the SCMP API (PDF | HTML).

Adding an Offer to the Request

After you specify the request information, add the offer information about the individual items being purchased. You can include multiple offers in one request.

offer.setField("amount", "29.95");

request.addOffer(offer);

For a full list of the offer fields for the CyberSource credit card services, see the Credit Card Services Using the SCMP API (PDF | HTML).

Sending the Request

You next send the request to CyberSource while handling a possible exception:

try {

ICSReply reply = client.send(request);

} catch (ICSException e) {

System.out.println("Error while sending request: ") +

    e.getMessage());

}

For more details about the ICSReply class and the send(ICSClientRequest) method, see API for the Java SDK.

Handling the Reply Flags and Error Messages

After the CyberSource server processes your request, the server returns a reply consisting of name-value pairs. The fields vary, depending on which services you requested and the results of the request.

To use the reply information, you must integrate it into your system and any other system that uses that data. This includes storing the data and passing it to any other services that need the information.

You must write an error handler to handle the reply flags and error messages that you receive from CyberSource. Do not show the flags or error messages directly to customers. Instead, present an appropriate response that tells customers the result.

 

Because CyberSource may add reply fields and reason codes at any time, you should parse the reply data according to the names of the fields instead of their order in the reply.

Each CyberSource service has its own list of reply flags and error responses that you must handle. For the credit card services, see the Credit Card Services Using the SCMP API (PDF | HTML) for a list of the fields. The main reply fields to evaluate for the request are as follows:

nics_rcode — a one-digit code that indicates whether the entire request was successful:

l1 indicates the request was successful

l0 indicates the request was declined

l-1 indicates an error occurred

nics_rflag — a one-word description of the result of the entire request:

lSOK indicates the request was successful

lA flag starting with the letter D indicates the request was declined

lA flag starting with the letter E indicates there was an error

nics_rmsg — a message that explains the reply flag. Do not show this message to customers or use it to write the error handler.

You also receive similar fields for each service you request, indicating the result of the service. The names of the fields are <service>_rcode, <service>_rflag, and <service>_rmsg. For example, the service for credit card authorization (ics_auth) returns auth_rcode, auth_rflag, and auth_rmsg.

 

CyberSource reserves the right to add new reply flags at any time. Write your error handler so that it can process these new reply flags without problems.

Receiving the Reply

Receive the reply (in the same statement you use to send the request) and get the request’s ics_rcode and ics_rflag values:

try {

ICSReply reply = client.send(request);

} catch (ICSException e) {

System.out.println("Error while sending request: ") +

    e.getMessage());

}

int rcode = reply.getReplyCode();

String rflag = reply.getField("ics_rflag");

Handling the Reply

Next evaluate the request’s reply code and reply flag:

if (rcode < 0) {

  // Error occurred;

  // Notify customer that an error occurred,

  // and ask customer to try again.

}

else if (rcode == 0) {

  // Request declined

  // Evaluate reply flag for reason why request was declined

  if ("DINVALIDDATA".equals(rflag)) {

    // Notify customer that request included invalid data;

    // Ask to correct error and resubmit request.

  }

  else if ("DCARDREFUSED".equals(rflag)) {

    // For cards declined by the bank.

    // Notify customer unable to process order.

  }

  else {

    // Handle remaining possible declined reply flags here.

    // Write error handler to process

    // new reply flags created by CyberSource.

  }

}

else {

  // Successful transaction;

  // perform any local processing, and

  // notify customer of success.

}

Handling Exceptions

You must handle several exceptions when constructing and sending requests. For a full list of the exceptions, see the Javadoc in the doc/ directory of the SDK. At a minimum, you should catch ICSException, the base class for all of the exceptions.

Creating the Client and Request

The constructors for ICSClient and ICSClientRequest throw ICSException, the base class for all CyberSource exceptions. The following example gives sample code for catching ICSException.

try {

ICSClient client = new ICSClient();

ICSClientRequest request = new ICSClientRequest();

} catch (ICSException e) {

System.out.println("Could not create client and/or request. ") +

    e.getMessage());

}

 

ICSClient constructors also throw ICSConfigException, a subclass of ICSException, which indicates that a problem occurred with the property values.

Sending the Request

The common exceptions thrown when you send a request indicate either a network or an SDK configuration problem. The exceptions fall into two categories: those thrown before the server receives the request, and those thrown after.

Exceptions Thrown Before the Server Receives the Request

These two exceptions indicate that the CyberSource server did not receive the request:

nICSConfigException — indicates a problem occurs with any of the property values

nRequestMessageException — indicates an error occurs when creating or sending the request

In these cases, you can send the same request again without risk of duplicating the transaction.

Exceptions Thrown After the Server Receives the Request

The next two exceptions indicate that the CyberSource server received the request, but a subsequent error occurred:

nICSMessageParseException — indicates an error occurs when parsing the reply data

nReplyMessageException — indicates an error occurs when decrypting or reading the reply

In these cases, you should not resend the request to avoid duplicating the transaction. Use Transaction Search in the Business Center to search for the transaction.

Typically you only must handle the four exceptions listed above. The following examples provide sample code.

try {

// send the request and receive the reply

ICSReply reply = client.send(request);

} catch (ICSConfigException e) {

System.out.println("Problem with CyberSource client configuration: ") +

    e.getMessage());

}

catch (RequestMessageException e) {

System.out.println("Could not send request to server: ") +

    e.getMessage());

}

catch (ICSMessageParseException e) {

System.out.println("Reply received, but could not parse it: ") +

    e.getMessage());

}

catch (ReplyMessageException e) {

System.out.println("Request sent; problem with reply: ") +

    e.getMessage());

}

Three of the four exceptions have subclasses that provide greater detail to help troubleshoot where in the code the error occurs. See the Javadoc in the doc/ directory of the SDK for more information.

Requesting Multiple Services

When you request multiple services in one request, CyberSource processes the services in a specific order. If a service fails, CyberSource does not process the subsequent services in the request.

For example, in the case of a sale (a credit card authorization and a capture requested together), if the authorization service fails, CyberSource does not process the capture service. The reply you receive only includes reply fields for the authorization.

Many CyberSource services include “ignore” fields that tell CyberSource to ignore the result from the first service when deciding whether to run the subsequent services. In the case of the sale, even though the issuing bank gives you an authorization code, CyberSource might decline the authorization based on the AVS or card verification results. Depending on your business needs, you might choose to capture these types of declined authorizations anyway. You can set the ignore_avs field to “yes” in your combined authorization and capture request:

request.setField(“ignore_avs”, “yes”);

This tells CyberSource to continue processing the capture even if the AVS result causes CyberSource to decline the authorization. In this case you would then get reply fields for both the authorization and the capture in your reply.

 

You are charged only for the services that CyberSource performs.

Specifying the Proxy Settings in the Request

You can specify the proxy settings in the request, overriding the settings in the system properties. You might do this if you use the Java SDK in an application server environment with many applications that have unique socket connection requirements.

You can set the proxy host and port in the request message using the following code:

request.setField("http_proxy_host", "host");

request.setField("http_proxy_port", "port");

If you include the proxy settings in the request, the SDK uses the proxy for the connection. If you do not include the proxy settings in the request, the SDK uses the settings specified with the system properties http.proxyHost and http.proxyPort.

 

If the value you specify in the request for either the host or port is invalid, the proxy settings are silently ignored, and the SDK attempts a direct connection. If the firewall blocks the attempt and requires a proxy, the direct connection fails with an exception. If, however, the firewall does not block the attempt, the direct connection succeeds.

Timeouts and Automatic Retries

If you find that you are not receiving replies to some of your requests, you can troubleshoot the problem by adjusting how your code handles retries and timeouts.

Retries and timeouts control how long the client waits for a reply from the CyberSource server after it sends a request, and whether and when the client automatically resends the request (called a retry).

 

When the client retries, the retry request has the same request ID as the original request.

Three parameters allow you to control how retry requests and timeouts work:

nretry_enabled — indicates whether you want to send a retry request if you do not initially get a reply. Retry request is disabled by default.

nretry_start — controls how long (in seconds) you want to wait for the initial request to be sent and replied to by CyberSource. A retry request is sent if a reply is not received by the time this expires. The default value is 30.

ntimeout — controls the total amount of time (in seconds) you want to wait for a response before a timeout error is returned (whether retry was attempted or not). The default value is 110.

 

Retry is not attempted if the difference between the timeout and retry_start values is less than 3 seconds.

How a Transaction without Retry Works

When retry is disabled, the SDK for Java functions as follows:

1Encrypt and send the initial request. The timeout clock starts counting at 0 seconds.

2Wait for and receive a response from the CyberSource server in the allotted time (set by the timeout parameter).

If the response does not come back from the CyberSource server in the allotted time, a timeout error is returned.

How a Transaction with Retry Works

When retry is enabled, the SDK for Java functions as follows:

1Encrypt and send the initial request. The timeout clock and the retry_start clock both start counting at 0 seconds.

2Wait until retry_start has expired or return the response if one was received, whichever comes first.

3If retry_start has expired and no response has been received, the client encrypts and sends the request again, using the same request ID as the initial request. The timeout clock continues counting.

The request (and the response, if one is received) automatically includes an additional field to indicate that this request is a retry.

4The client returns a response if one is received, or waits until the full timeout has expired. (The timeout clock started counting at the time that the initial request was sent.)

5If no response was received before the timeout expired, a timeout error is returned.

For example, if retry_start is set at 30 seconds, and no response has been received in that 30 seconds, then the client sends a retry request.

The client then waits for the duration of the remaining timeout time (timeout minus retry_start). For example, if timeout is set at 110 seconds, the client then waits for a length of time equal to 110 seconds minus 30 seconds. If no response is received in that 80-second interval, then a timeout error is returned.

Evaluating the Retry Reply Fields

You evaluate the success of the retry request using the ics_retry field. The field returns one of the following values:

n1 — The retry request was successful using the original data; no reprocessing was necessary.

The CyberSource server has a record of the response in its database. CyberSource does not reprocess the request and sends the original response to you.

n0 — The retry request was successful using data from reprocessing the request.

The CyberSource server has no record of the request. CyberSource reprocesses the request and sends you the response.

n-1 — The retry request was unsuccessful due to a processing error.

The CyberSource server has a record of the request, but the response is not in its database. CyberSource does not reprocess the request. Do not resend the request, because you might duplicate the transaction. Use Transaction Search in the Business Center to search for the transaction.

Setting Retry and Timeout Parameters

You can set the parameters’ values using the setField(String fieldname, String value) method. You can also set the parameters directly in the ICSClient.props file.

Enabling Retry

The retry_enabled value controls whether the client sends a retry request if no initial response is received. Retry is disabled by default. You enable retry_enabled with the following code (“yes” is case-insensitive):

request.setField("retry_enabled", "yes");

You can also set the value in the ICSClient.props properties file:

retryEnabled=true

Setting the retry_start Value

The retry_start value controls how long the client waits before sending a retry request. The default value is 30 seconds. The minimum value is 3 seconds, which is acceptable for testing, but not for running live transactions. Start with the default value of 30 seconds and lower the value to 15 seconds if appropriate.

You can set the retry_start value with the following code:

request.setField("retry_start", "15");

Or, you can set the value in the ICSClient.props properties file:

retryStart=15

Setting the timeout Value

The timeout value controls the maximum time you want to wait to send the request and receive the response. This time begins when the client sends the initial request. The default value is 110 seconds and must not be less than the minimum value of 6 seconds when retry is enabled.

You can set the timeout value with the following code:

request.setField("timeout", "90");

Or, you can set the value in the ICSClient.props properties file:

timeout=90

 

The timeout value must not be set at less than 6 seconds when retry is enabled. The timeout value must also be greater than the retry_start value by at least 3 seconds. You receive an error and the system sends no retry request if the timeout or retry_start values are too low or invalid.

System Errors and Retries

The client’s automatic retry capability described above in Timeouts and Automatic Retries does not automatically retry in the case of system errors, only timeouts. You must design your transaction management system to include a way to correctly handle CyberSource system errors. System errors occur when you successfully receive a reply and the reply’s ics_rflag=ESYSTEM. For more information about the ics_rflag, see Handling the Reply Flags and Error Messages. Depending on which payment processor is handling the transaction, the ESYSTEM error may indicate a valid CyberSource system error or a processor rejection due to invalid data. In either case, CyberSource recommends that you do not design your system to retry sending a transaction many times when an ESYSTEM error occurs.

Instead, CyberSource recommends that you retry sending the request only two or three times with successively longer periods of time between each retry. For example, after the first system error response, wait 30 seconds and then retry sending the request. If you receive the same error a second time, wait one minute before you send the request again. Depending on the situation, you may decide you can retry sending the request after a longer time period. Determine what is most appropriate for your business situation.

If after several retry attempts you are still receiving a system error, it is possible that the error is actually being caused by a processor rejection and not a CyberSource system error. In that case, CyberSource recommends that you use one of these options:

nSearch for the transaction in the Business Center, look at the description of the error on the Transaction Detail page, and call your processor to determine if and why they are rejecting the transaction.

nContact CyberSource Customer Support to confirm whether your error is truly caused by a CyberSource system issue.

If TSYS Acquiring Solutions is your processor, you may want to follow the first suggestion because there are several common TSYS Acquiring Solutions processor responses that are returned to you as system errors and that only TSYS Acquiring Solutions can address.

Enterprise JavaBeans™ (EJB)

The SDK includes an Enterprise JavaBeans™ (EJB) component to build server applications that access CyberSource services.

See the README_EJB.txt file in the SDK for details on creating the CdkApp application, packaging and deploying the CdkJAR bean, and testing your EJB implementation.