Have your own great idea for a new API feature?

or maybe a suggested improvement to an existing one? Share it and become a god of the developer world.

New Idea

Subscription Transactions?

Status: Accepted
by dnsBuffaloNY on ‎04-12-2017 01:15 PM

Currently, there is no easy way to get a list of transactions for a given subscription id.  To get a list of transactions for a subscription id. I load the subscription to get the customerProfileId and payentProfileId, call getTransactionListForCustomerRequest(customerProfileId, paymentProfileId), loop over the transactions returned in the response, and evaluate if transaction.subscription.id is equal to the subsciptionId I am looking for.  Furthermore, getTransactionListForCustomerRequest() uses paging, so I may need to call that API multiple times to get the collection of transactions for a subscription.

 

I am requesting there be a new API to get a list of transactions for a subscription id.  The new method would implement the standard paging and sorting.

 

See this Community Forum Discussion

 

Thank you for your consideration.

 

Status: Accepted

Include ACH in Accept.Js

Status: Accepted
by dnsBuffaloNY on ‎10-01-2016 12:26 PM

Accept.Js works great!  It allows my website to capture Credit Card information without that data ever posting back to my servers.  I don't any PCI Compliance headaches.

 

My suggestion would be to enhance Accept.JS to also allow for ACH payments.  That is, have accept.JS allow for the capture of a Routing and Account Number.  It could look like this:

 

var secureData = {}, authData = {}, bankData = {};
	
	bankData.routingNumber = document.getElementById('ROUTINGNUMBER_ID').value;
	bankData.accountNumber = document.getElementById('ACCOUNTNUMBER_ID').value;

	secureData.bankData = bankData;

	authData.clientKey = '6WrfHGS76gHW3v7btBCE3HuuBukej96Ztfn5R32G5ep42vne7MCWZtAucY';
	authData.apiLoginID = 'my_api_login_id';
	secureData.authData = authData;
	
	Accept.dispatchData(secureData, 'responseHandler');

Here's a related communit post.

 

https://community.developer.authorize.net/t5/Integration-and-Testing/Accept-JS-and-ACH/m-p/55887#M30...

 

Thank you for your consideration!

Status: Accepted

There should be a way to retrieve transaction details by their invoice number. If there is a network failure the only identifying information we have is the invoice number (not the Authorize.net generated transaction id).

 

Using the getUnsettledTransactionListRequest call is a bad choose since it only returns the last 1000 records.

Status: Accepted

Changing to Accepted, also it is now possible to return more than 1000 rows using paging.

Soft Descriptor and Contact Information

Status: Accepted
by jbracken1973 on ‎11-18-2014 08:38 AM - last edited on ‎01-15-2015 11:23 AM by Administrator Administrator

The ability to set the soft descriptors for a transaction. 

 

These are the fields that a customer sees on their statements, it allows for the customer to quickly ID the transactions reducing disputes and customer service.  For obvious reasons I hope.

 

Dynamic Descriptors include:

Business Name

Phone (Best Practices says this should be a Customer service number)

City and/or State

Status: Accepted

We plan to support Soft Descriptors when supported by the processors we connect to, and have plans to add support for TSYS and Global Payments.

Level 3 Support Feature request

Status: Accepted
by thill on ‎02-05-2016 09:50 AM

I have just recently wrapped up an integration with Auth.net to our website and erp system using CIM and the Payment Transaction API.  Our system is passing the Level 3 data to Auth.net, but Auth.net doesn't pass this information to the processor.  I was curious about the decision for Auth to hold onto the data and not deliver it to the processors and if this feature is on the roadmap?  I would love to have the L3 data passed around, we could realize an incredible amount of savings from this (fees can be cut by up to half with this information, That's huge!). 

 

If this isn't on the roadmap, please consider adding support for this.

 

Status: Accepted

Created from previous thread: https://community.developer.authorize.net/t5/Integration-and-Testing/How-to-set-billing-info-in-CIM-...

 

Add ability to pre-load billing information into CIM hosted form.   Our customer's billing information is already stored in our system, and we do not want to force them to enter it a second time when adding a payment profile.  We would prefer instead to show the current billing information as the default values and allow them to modify the displayed information if the billing infomration is different for the credit card than what is already on file.

 

================================

 

 

In our system the user complete billing information, and when we show the form of the CIM hosted API, we need such data are loaded in the form, as we do that?

 

First we call to createCustomerProfileRequest,  with merchantCustomerId and email.

 

Then I call createCustomerShippingAddressRequest with customer billing address

 

and then, I call getHostedProfilePageRequest.

Status: Accepted

Idea: A read-only key that can be generated specifically for the Transaction Details API.

 

Background:

We are developing an app that only uses the Transaction Details API.

Which means we are only reading information.

 

From a liability standpoint, we want to avoid saving a write-capable transaction key.

 

Ideally a separate "read-only" transaction key could be created when a user turns on the Transaction Details API.

Status: Accepted

As we build out our integration we noticed it would nice to have some additonal search types added to the getCustomerPaymentProfileListRequest endpoint. The most useful for us would be to search by customerProfileID.  Also an expiration date range would be nice along with a paymentType (credit card or bank account)

 

A future request i could see is having the ability to have multiple searchTypes like customerProfileID and and an expiration month/year or range, or customerProfileID and paymentType.

 

Thanks,

-Nick

Status: Accepted

Despite using best security practices to protect passwords, we consider the single form authentication to the Authorize.net portal to be a critical security concern.

 

The concern is especially high with regard to CIM. When CIM is enabled, anybody breaking into the Authorize.net account can do a lot of damage (like creating transactions).

 

We are in 2015 and two form factor authentication is widespread and easy to implement. It does not have to be a full blown 2-factor with MFA devices. A simple solution - for example using a mobile phone access code - would already be a huge improvement over the current system.

 

 

Status: Accepted

Created from previous thread: https://community.developer.authorize.net/t5/Integration-and-Testing/refundTransaction-requires-expi...

 

Currently, to refund a transaction, you must provide both the masked credit card number and expiration date.   Yet this information adds nothing to the request -- in fact, if you no longer have this information, you must issue a separate getTransactionDetail transaction to fetch this information.   Rather than requiring two separate transactions to perform a single task, only require the original transaction id.

 

Status: Accepted

ARB subscription details

Status: Accepted
by mandah0520 on ‎01-26-2015 02:02 PM

There needs to be a feature that allows you to get subscription information like when was the last valid payment, all attempt of card processing and whether it failed or went through, etc etc etc. ARB really is tiny with no usefull functions other than create and cancel subscriptions. Even the update is useless with the amount of things u can update about a transaction. So please add some features that gives users some idea of what is going on with their subscription. Is there a better payment processor than authorize.net that does this?

Status: Accepted

Hi,

It's great that now we finally can retrieve card expiration dates via API call. Nevertheless, on https://test.authorize.net/profile/editPayment form expiration date is still displayed as masked. Our clients find this inconvenient. The idea is to show unmasked date on hosted form.

Status: Accepted

The current minimum 7 day interval for ARB makes testing impossible.

Developers need a shorter interval, for example 1 minute, to be able to test their applications.

Status: Accepted

Updating ARB status to Suspended

Status: Accepted
by j_gemiini2 on ‎10-07-2014 02:09 PM - last edited on ‎08-12-2015 09:33 AM by Administrator Administrator

Hi,

 

We would like to update the status of an ARB to 'suspended' via the API, but I don't see an obvious way to do this. I'm using the php sdk.

 

I see that there is the ARBUpdateSubscriptionRequest method, but status isn't a member of AuthorizeNet_Subscription, so it gives me a E00003 (unexpected element) error when I try sending 'status' or 'ARBSubscriptionStatusEnum'.

Is there anyone who knows how to do this?

 

Thanks!

Status: Accepted
0 Votes

Authnet Java SDK doesnt support TLS 1.2. Need to update util classes.

Status: Accepted
by TonyC ‎06-13-2017 11:45 AM - edited ‎06-13-2017 11:53 AM

Our company was having trouble with our connection to Authnet in the sandbox environment due to the recent upgrade requiring TLS 1.2. Our company's app is running with Java 1.7. We tried setting our project's http protocols to force TLS 1.2 but this didnt seem to be working. Eventually we discovered that the anet-java-sdk:1.9.3 is usign a default HTTPClient. We had to override the HttpClient and HttpCallTask classes in the util directory.  

 

Anywhere that the class set up a defaultHttpClient, we replaced that code with this:

 

SSLContext sslContext = SSLContexts.custom()
.useTLS()
.build();

SSLConnectionSocketFactory f = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1.2"},
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(f)
.build();

 

 

The entire HttpClient and HttpCallTask classes are below. If we could get these changes added to a new SDK from Authnet, that may help other customers avoid this same problem. Also, it would be helpful for us as then we can continue just importing the entire file library rather than including all the anet files in our own code structure. 

 

HttpClient:

 

package net.authorize.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;

import net.authorize.Environment;
import net.authorize.ResponseField;
import net.authorize.Transaction;

import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.CloseableHttpClient;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.SSLContexts;
import javax.net.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;


/**
* Transportation object used to facilitate the communication with the respective gateway.
*
*/
public class HttpClient {
private static Log logger = LogFactory.getLog(HttpClient.class);

public static final String ENCODING = "UTF-8";
static boolean proxySet = false;

static boolean UseProxy = Environment.getBooleanProperty(Constants.HTTPS_USE_PROXY);
static String ProxyHost = Environment.getProperty(Constants.HTTPS_PROXY_HOST);
static int ProxyPort = Environment.getIntProperty(Constants.HTTPS_PROXY_PORT);
static int httpConnectionTimeout = Environment.getIntProperty(Constants.HTTP_CONNECTION_TIME_OUT);
static int httpReadTimeout = Environment.getIntProperty(Constants.HTTP_READ_TIME_OUT);

static {
LogHelper.info(logger, "Use Proxy: '%s'", UseProxy);

httpConnectionTimeout = (httpConnectionTimeout == 0 ? Constants.HTTP_CONNECTION_TIME_OUT_DEFAULT_VALUE : httpConnectionTimeout );
httpReadTimeout = (httpReadTimeout == 0 ? Constants.HTTP_READ_TIME_OUT_DEFAULT_VALUE : httpReadTimeout);
}
/**
* Creates the http post object for an environment and transaction container.
*
* @param env
* @param transaction
* @return HttpPost object
*
* @throws Exception
*/
private static HttpPost createHttpPost(Environment env, Transaction transaction) throws Exception {
URI postUrl;
HttpPost httpPost = null;

if(transaction instanceof net.authorize.aim.Transaction ||
transaction instanceof net.authorize.sim.Transaction) {

if(transaction instanceof net.authorize.aim.Transaction &&
((net.authorize.aim.Transaction)transaction).isCardPresent()) {

postUrl = new URI(env.getCardPresentUrl() + "/gateway/transact.dll");
} else {
postUrl = new URI(env.getBaseUrl() + "/gateway/transact.dll");
}

httpPost = new HttpPost(postUrl);

httpPost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);

//set the tcp connection timeout
httpPost.getParams().setIntParameter(HttpConnectionParams.CONNECTION_TIMEOUT, httpConnectionTimeout);
//set the time out on read-data request
httpPost.getParams().setIntParameter(HttpConnectionParams.SO_TIMEOUT, httpReadTimeout);

httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
httpPost.setEntity(new StringEntity(transaction.toNVPString(), HTTP.UTF_8));
} else if (transaction instanceof net.authorize.arb.Transaction ||
transaction instanceof net.authorize.cim.Transaction ||
transaction instanceof net.authorize.reporting.Transaction) {

postUrl = new URI(env.getXmlBaseUrl() + "/xml/v1/request.api");
httpPost = new HttpPost(postUrl);
httpPost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);

//set the TCP connection timeout
httpPost.getParams().setIntParameter(HttpConnectionParams.CONNECTION_TIMEOUT, httpConnectionTimeout);
//set the time out on read-data request
httpPost.getParams().setIntParameter(HttpConnectionParams.SO_TIMEOUT, httpReadTimeout);

httpPost.setHeader("Content-Type", "text/xml; charset=utf-8");
httpPost.setEntity(new StringEntity(transaction.toXMLString(), HTTP.UTF_8));
}

return httpPost;
}

/**
* Creates a response map for a given response string and transaction container.
*
* @param transaction
* @param responseString
* @return container map containing semi-processed data after request was posted
* @throws UnsupportedEncodingException
*/
private static Map<ResponseField, String> createResponseMap(Transaction transaction, String responseString)
throws UnsupportedEncodingException {

Map<ResponseField, String> responseMap = null;

// aim/sim
if(transaction instanceof net.authorize.aim.Transaction ||
transaction instanceof net.authorize.sim.Transaction) {

String decodedResponseData = URLDecoder.decode(responseString, HTTP.UTF_8);


responseMap = ResponseParser.parseResponseString(decodedResponseData);
}

return responseMap;
}

/**
* Executes a Transaction against a given Environment.
*
* @param environment
* @param transaction
* @return container map containing semi-processed data after request was posted
*/
public static Map<ResponseField, String> execute(Environment environment, Transaction transaction) {
Map<ResponseField, String> responseMap = new HashMap<ResponseField, String>();

if(environment != null && transaction != null) {
try {
SSLContext sslContext = SSLContexts.custom()
.useTLS()
.build();

SSLConnectionSocketFactory f = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1.2"},
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(f)
.build();

setProxyIfRequested(httpClient);

// create the HTTP POST object
HttpPost httpPost = createHttpPost(environment, transaction);

// execute the request
HttpResponse httpResponse = httpClient.execute(httpPost);
String rawResponseString;
if(httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();

// get the raw data being received
InputStream instream = entity.getContent();
rawResponseString = convertStreamToString(instream);
}
// handle HTTP errors
else {
StringBuilder responseBuilder = new StringBuilder();
responseBuilder.append(3).append(net.authorize.aim.Transaction.TRANSACTION_FIELD_DELIMITER);
responseBuilder.append(3).append(net.authorize.aim.Transaction.TRANSACTION_FIELD_DELIMITER);
responseBuilder.append(22).append(net.authorize.aim.Transaction.TRANSACTION_FIELD_DELIMITER);
responseBuilder.append(httpResponse != null ? httpResponse.getStatusLine().getReasonPhrase() : " ");
rawResponseString = responseBuilder.toString();
}

httpClient.getConnectionManager().shutdown();

String cleanResponseString = XmlUtility.descapeStringForXml(rawResponseString);

responseMap = HttpClient.createResponseMap(transaction, cleanResponseString);
} catch (Exception e) {
LogHelper.warn(logger, "Exception getting response: '%s': '%s', '%s'", e.getMessage(), e.getCause(), Arrays.toString(e.getStackTrace()));
}
}

return responseMap;
}

/**
* Converts a response inputstream into a string.
*
* @param is
* @return String
*/
public static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();

String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
} catch (IOException e) {
LogHelper.warn(logger, "Exception reading data from Stream: '%s'", e.getMessage());
} finally {
if ( null != reader){
try {
reader.close();
} catch (IOException e) {
LogHelper.warn(logger, "Exception closing BufferedReader: '%s'", e.getMessage());
}
}

if ( null != is) {
try {
is.close();
} catch (IOException e) {
LogHelper.warn(logger, "Exception closing InputStream: '%s'", e.getMessage());
}
}
}
return sb.toString();
}


/**
* Executes a Transaction against a given Environment.
*
* @param environment
* @param transaction
* @return BasicXmlDocument containing semi-processed data after request was posted
*/
public static BasicXmlDocument executeXML(Environment environment, Transaction transaction) {
BasicXmlDocument response = new BasicXmlDocument();

if(environment != null && transaction != null) {
try {
SSLContext sslContext = SSLContexts.custom()
.useTLS()
.build();

SSLConnectionSocketFactory f = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1.2"},
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(f)
.build();

setProxyIfRequested(httpClient);

// create the HTTP POST object
HttpPost httpPost = createHttpPost(environment, transaction);

// execute the request
HttpResponse httpResponse = httpClient.execute(httpPost);
String rawResponseString;
if(httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();

// get the raw data being received
InputStream instream = entity.getContent();
rawResponseString = convertStreamToString(instream);
}
else {
StringBuilder responseBuilder = new StringBuilder();
if(transaction instanceof net.authorize.arb.Transaction ||
transaction instanceof net.authorize.cim.Transaction ||
transaction instanceof net.authorize.reporting.Transaction) {

responseBuilder.append("<?xml version=\"1.0\" ?>");
responseBuilder.append("<messages><resultCode>Error</resultCode>");
responseBuilder.append("<message><code>E00001</code>");
responseBuilder.append("<text>");
responseBuilder.append(httpResponse != null?httpResponse.getStatusLine().getReasonPhrase():"");
responseBuilder.append("</text></message></messages>");
} else {
responseBuilder.append("<?xml version=\"1.0\" ?>");
responseBuilder.append("<response>");
responseBuilder.append("<ResponseCode>3</ResponseCode>");
responseBuilder.append("<Errors><Error><ErrorCode>22</ErrorCode><ErrorText><![CDATA[");
responseBuilder.append(httpResponse != null?httpResponse.getStatusLine().getReasonPhrase():"");
responseBuilder.append("]]></ErrorText></Error></Errors></response>");
}

rawResponseString = responseBuilder.toString();
}


httpClient.getConnectionManager().shutdown();

if(rawResponseString == null) return null;


int mark = rawResponseString.indexOf("<?xml");
if(mark == -1){
return null;
}

response.parseString(rawResponseString.substring(mark,rawResponseString.length()));
if(response.IsAccessible() == false){
return null;
}
} catch (Exception e) {
LogHelper.warn(logger, "Exception getting response: '%s': '%s', '%s'", e.getMessage(), e.getCause(), Arrays.toString(e.getStackTrace()));
}
}

return response;
}

/**
* if proxy use is requested, set http-client appropriately
* @param httpClient the client to add proxy values to
*/
public static void setProxyIfRequested(CloseableHttpClient httpClient) {
if ( UseProxy)
{
if ( !proxySet) {
LogHelper.info(logger, "Setting up proxy to URL: '%s://%s:%d'", Constants.PROXY_PROTOCOL, ProxyHost, ProxyPort);
proxySet = true;
}
HttpHost proxyHttpHost = new HttpHost(ProxyHost, ProxyPort, Constants.PROXY_PROTOCOL);
httpClient.getParams().setParameter( ConnRoutePNames.DEFAULT_PROXY, proxyHttpHost);
}
}
}

 

HttpCallTask:

 

package net.authorize.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.Callable;

import javax.xml.bind.JAXBException;
import javax.xml.bind.UnmarshalException;

import net.authorize.Environment;
import net.authorize.api.contract.v1.ANetApiRequest;
import net.authorize.api.contract.v1.ANetApiResponse;
import net.authorize.api.contract.v1.MessageTypeEnum;
import net.authorize.api.contract.v1.MessagesType;
import net.authorize.api.contract.v1.MessagesType.Message;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
import javax.net.ssl.SSLContext;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.conn.ssl.SSLContexts;
import javax.net.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
//import net.authorize.api.controller.base.ErrorResponse;

/**
* Callable task to make http calls in future
* @author ramittal
*
*/
public class HttpCallTask implements Callable<ANetApiResponse> {
private static Log logger = LogFactory.getLog(HttpCallTask.class);

Environment env = null;
ANetApiRequest request = null;
@SuppressWarnings("rawtypes")
Class classType = null;

//private static ANetApiResponse errorResponse = null;
private Message errorMessage = null;

/**
* Creates task to be called in future for making http call
* @param env Env to point to
* @param request Http request to send
* @param classType Expected response type if successful
*/
public <T> HttpCallTask(Environment env, ANetApiRequest request, Class<T> classType) {
this.env = env;
this.request = request;
this.classType = classType;
this.errorMessage = new Message();
}

@SuppressWarnings("unchecked")
/**
* Makes a http call, using the proxy if requested, and returns apiresponse
* with error code set appropriately
* @return ANetApiResponse successful or failed response
*/
public ANetApiResponse call() throws Exception {
ANetApiResponse response = null;
StringBuilder buffer = new StringBuilder();

CloseableHttpClient httpCaller = null;

try {
HttpPost httppost = HttpUtility.createPostRequest(this.env, this.request);
SSLContext sslContext = SSLContexts.custom()
.useTLS()
.build();

SSLConnectionSocketFactory f = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1.2"},
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

httpCaller = HttpClients.custom()
.setSSLSocketFactory(f)
.build();
HttpClient.setProxyIfRequested(httpCaller);
HttpResponse httpResponse = httpCaller.execute(httppost);

if ( null != httpResponse) {
if ( null != httpResponse.getStatusLine()) {
if ( 200 == httpResponse.getStatusLine().getStatusCode()) {

HttpEntity entity = httpResponse.getEntity();
// get the raw data being received
InputStream instream = entity.getContent();
buffer.append(HttpUtility.convertStreamToString(instream));
}
}
}
LogHelper.debug(logger, "Raw Response: '%s'", buffer.toString());
// handle HTTP errors
if (0 == buffer.length()) {
response = createErrorResponse(httpResponse, null);
} else { // i.e. if ( StringUtils.isNotEmpty(buffer.toString()))
Object localResponse = null;

try {
localResponse = XmlUtility.create(buffer.toString(), this.classType);
} catch(UnmarshalException ume) {
try {
//try deserializing to error message
localResponse = XmlUtility.create(buffer.toString(), net.authorize.api.contract.v1.ErrorResponse.class);
} catch(JAXBException jabex) {
response = createErrorResponse(httpResponse, jabex);
}
} catch(JAXBException jabex) {
response = createErrorResponse(httpResponse, jabex);
}

//ObjectFactory factory = new ObjectFactory();
//JAXBElement<ANetApiResponse> error = factory.createErrorResponse();

//check if error
if ( null == localResponse) {
try {
response = XmlUtility.create(buffer.toString(), ANetApiResponse.class);
} catch(JAXBException jabex) {
response = createErrorResponse(httpResponse, jabex);
}
} else {
if (localResponse instanceof ANetApiResponse)
{
response = (ANetApiResponse) localResponse;
} else {
LogHelper.warn( logger, "Unknown ResponseType: '%s'", localResponse);
}
}
}
} catch (ClientProtocolException cpe) {
response = createErrorResponse(null, cpe);
} catch (IOException ioe) {
response = createErrorResponse(null, ioe);
} finally {
if ( null != httpCaller) {
httpCaller.getConnectionManager().shutdown();
}
}

return response;
}

private ANetApiResponse createErrorResponse(HttpResponse httpResponse, Exception exception) {
ANetApiResponse response = new ANetApiResponse();

MessagesType aMessage = new MessagesType();
aMessage.setResultCode(MessageTypeEnum.ERROR);
response.setMessages(aMessage);

List<Message> messages = response.getMessages().getMessage();
//clear all messages
messages.clear();

setErrorResponse(messages, httpResponse);
setErrorResponse(messages, exception);

return response;
}

private void setErrorResponse(List<Message> messages, HttpResponse httpResponse) {
if ( null != httpResponse) {
messages.add(errorMessage);
String code = "Error";
String text = "Unknown Error";
if (null != httpResponse.getStatusLine())
{
LogHelper.warn( logger, "Error deserializing response to '%s'", this.classType);

code = String.format("%d", httpResponse.getStatusLine().getStatusCode());
if (null != httpResponse.getStatusLine().getReasonPhrase()) { text = httpResponse.getStatusLine().getReasonPhrase();}
}
setErrorMessageValues(code, text);
}
}

private void setErrorResponse(List<Message> messages, Exception exception) {
if ( null != exception) {
messages.add(errorMessage);
String code = "Error";
String text = "Unknown Error";
LogHelper.error( logger, "Http request execute failed: '%s'", exception.getMessage());
code = exception.getClass().getCanonicalName();
//code = exception.getClass().getTypeName();// requires java1.8
text = exception.getMessage();

setErrorMessageValues(code, text);
}
}

private void setErrorMessageValues(String code, String text) {
errorMessage.setCode(code);
errorMessage.setText(text);
LogHelper.warn(logger, "Adding ErrorMessage: Code: '%s', Text: '%s'", code, text);
}
}

 

Hopefully this is helpful for anyone else struggling to connect to the Sandbox environment. 

 

-Tony

Status: Accepted
0 Votes

We are using the AuthorizeNet Nuget package in our code base to communicate with Authorize.Net. After the TLS1.2 upgrade at Authorize.Net in the sandbox environment, we have been using 

 

 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

 So that the communication does not fail. It would be great if the fix was applied on the Nuget Package.

 

Thanks,

Reji

Status: Accepted
0 Votes

Support 19 Digit Card Numbers

Status: Accepted
by jmagaro88 on ‎01-24-2017 06:30 AM - last edited on ‎02-13-2017 04:13 PM by Administrator Administrator

A customer on my site just attempted to place an order with a valid Discover card number that is 19 digits long. Apparently, Discover and Visa have begun rolling out valid cards with 19 digits. The card passed my Luhn algorithm validation and was passed to Authorize.NET for authorization. The XML request was sent succefully; however, I received the following error response from Authorize.NET:

 

The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:cardNumber' element is invalid - The value XXXXXXXXXXXXXXXXXXXXX is invalid according to its datatype 'String' - The actual length is greater than the MaxLength value.

I checked on the Authorize.NET documentation, and it appears that only card numbers between 13 and 16 characters long are supported. When will this be changed to accommodate 19 digit card numbers?

Status: Accepted

Converted community thread to an idea and changed to accepted.

0 Votes

I'm currently working on a solution where our customers have requested a migration-tool, to tie existing CIM entries to their business partners in their ERP system.

 

In this case a method to retrieve all CIM profiles along with their corresponding payment profiles would be helpful.

 

Currently the only option is to query the API for all CIM profile IDs and then iterate them and call the API for each one.

In the sandbox environment this takes roughly 20 minutes for 4000 entries, using multi-threaded requesting. This performance is obviously pretty poor, and I imagine the method I described above would allviate this problem.

Status: Accepted
0 Votes

It seems so stupid that this is not already available.

 

If you have an ARB subscriber for a service you are offering on a monthly basis, you would of course want to know, often and simply, if that subscriber has paid his last bill before you continue to service him.

 

But instead of a simple API function, I have to parse through mountains of data and, if I dont want to have to do this everytime someone logs in ( to check if they should be able to), i also now have to create a database table to track this status and when it was last checked.

 

CRAZY!

 

Please Authorize.net, create a simple API to do this simple check!!!

 

 

Status: Accepted
0 Votes

Hi AuthorizeNet,

 

With the complexities of SAQ A, EF, D and the opportunities of globalization (i.e. en-CA, fr-CA, en-US, es-US, es-MX; North America + Mexico) it would be great to have localizable capabilities offered in your HostedForm and DirectPostMethod implementations.

 

This would simplify product integration (Redirect, IFRAME, DirectPost, and JavaScript) and allow a SAQ A or SAQ EF implementation.

 

My thought is to add hidden text fields i.e.;

 

For fields like;

 - input type="hidden" name="x_invoice_num" value="dpm3-inv3-123"

Add a new tag like;

- input type="hidden" name="x_invoice_num_label" value="Invoice Number:" .

 

This would go a long way to improving/solving localization and keeping PCI DSS to a minimum for the companies building solution with AuthorizeNet's SDK. 

 

Regards,

Rocklin Software

Status: Accepted