Giter Club home page Giter Club logo

sdk-java's People

Contributors

acharjee0712 avatar adavidw avatar akankaria avatar akashshah1203 avatar anuragg29 avatar arktseytlin avatar ashtru avatar beccagaspard avatar benkiefer avatar billboyde avatar brianmc avatar claytondus avatar gnongsie avatar kikmak42 avatar lilithmm avatar mkienenb avatar nagarikantipavan avatar ncpga avatar ramittal avatar ravishankar54 avatar sapbasu15 avatar vijayabraj avatar vkandroiddev avatar xianwang423 avatar zalak1612 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sdk-java's Issues

HttpClient extra UTF-8 decode problem?

A few weeks back a came across a HTTP response map decode exception caused by a product description that has "... 100% ..." on.

The immediate fix was to simply encode this description string before making the API request with net.authorize.data.Order, but after some digging I found what might be an extra

URLDecoder.decode(responseString, HTTP.UTF_8);

richardrega@9155b3f

Can anyone else confirm this problem? I can provide more details if needed.

ApiOperationBase context thread-safe?

ApiOperationBase.setMerchantAuthentication(merchantAuthenticationType);
ApiOperationBase.setEnvironment(Environment.SANDBOX);

Is there currently a way to wrap the environment and authentication values into an object that gets used and destroyed per request? The above usage may not be great for those supporting several auth.net accounts. Plz correct me if wrong. thx.

Using executors incorrectly.

The SDK's HttpUtility is needlessly creating threads for every request execution.

        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<ANetApiResponse> future = executor.submit(new HttpCallTask(env, request, classType));
        executor.shutdown(); // Important!
		
        try {
        	response = future.get();
        	logger.debug(String.format("Response: '%s'", response));
	} ...

This is creating a new thread for every execution. EXPENSIVE!
I could be wrong, but I think it's a race condition where to assume the HTTPCallTask is started before the executor gets shutdown.
Waiting on future.get() which means no call is ever asynchronous.

Support createCustomerProfileFromTransactionRequest in the API

As it stands, I have to duplicate more of the API than I want in order to get this functionality since I cannot extend net.authorize.cim.Transaction (no default constructor means I cannot extend it).

I basically had to copy/paste a lot of the communication code in HttpClient in order to support this very basic request/response because that class specifically checks for instanceof net.authorize.cim.Transaction, that object requires an net.authorize.cim.TransactionType, and there is not a TransactionType for createCustomerProfileFromTransactionRequest.

It seems that all that would be required is to:

  1. Add the createCustomerProfileFromTransactionRequest enum value to auth.net.cim.TransactionType
  2. Add a property to net.authorize.cim.Transaction for transId
  3. Provide support for the new enum type serialization in the net.authorize.cim.Transaction.toXML() method
  4. Provide support for the new enum type in deserialization in net.authorize.cim.Result

Environment not set running example code

Hi all,

Anyone having this issue?
I'm just running the Java example code the perform an authorization and getting a null response.
Debugging it I see that controller object has no properly set the environment. The exact message is:
"Environment not set. Set environment using setter or use overloaded method to pass appropriate environment"

I'm setting the environment as the example, didn't change anything:
ApiOperationBase.setEnvironment(Environment.SANDBOX);

Any idea?

NullPointerException

NullPointerException is thrown in net.authorize.reporting.Result

---- Stack Trace -----

CAUSED_BY: java.lang.NullPointerException :::
-- net.authorize.reporting.Result.importRefId(Result.java:491)
-- net.authorize.reporting.Result.createResult(Result.java:58)
-- net.authorize.Merchant.postTransaction(Merchant.java:300)

This is occurring frequently after the transaction processing outage on Jan 29, 2016.

Compile errors with Environment enum

The recent change to Environment.java added semi-colons to the end of LOCAL_VM and HOSTED_VM instead of commas. This is causing the build to fail.

Unable to retrieve Reporting Billing or Shipping Information via Java API

http://community.developer.authorize.net/t5/Integration-and-Testing/Unable-to-retrieve-Reporting-Billing-or-Shipping-Information-via/m-p/38865#U38865

We are unable to retrieve shipping or billing information for one of our transactions due to a defect in the Java Reporting API.

The XML that we are receiving is missing the "customer" element, and as a result it is not falling into the

if(customer_list != null && customer_list.getLength() == 1)

block of code of the net.authorize.reporting.Results class so that the shipTo and billTo elements can be processed.

According to the authorize.net xml schema, the billto and shipto elements are not children of a customer element, so the java code should not require the customer element to be present before processing these records.

I will take a look at hacking together a solution that will get me by. Please let me know when I can expect a fix.

Quick follow up question. Is anyone else using the Java Reporting API? I've submitted three defects for it in the past two months, and none of them have been fixed yet. Is everyone working off of their own forked version of the code? Just trying to find out if there is a better way of getting these fixes pushed out to our customers.

Thank you for your help.

NPE Result.importResponseCode

I have used this SDK for years without issues, but yesterday this came up repeatedly for a particular transaction:

java.lang.NullPointerException
at net.authorize.aim.cardpresent.Result.importResponseCode(Result.java:166)

I went on authorize.net web site and manually entered the card; It worked fine.

How to set MarketType and DeviceType

I was looking at this sample of yours ChargeCreditCard
and comparing it with the one that I have

Merchant merchant = Merchant.createMerchant("environment", "loginId", "transactionKey"); merchant.setMarketType(MarketType.RETAIL); merchant.setDeviceType(DeviceType.VIRTUAL_TERMINAL);

I was wondering how can I set a MarketType and DeviceType using MerchantAuthenticationType

The element in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has incomplete content.

I am getting following error for the Java code below. Basically I am looking to get the Transaction Details, settled and unsettled..
The element 'getTransactionDetailsRequest' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has incomplete content. List of possible elements expected: 'refId, transId' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'.

The Java code for reference

Merchant merchant = Merchant.createMerchant(Environment.SANDBOX, apiLoginID, transactionKey);
        Transaction transaction = merchant.createReportingTransaction(TransactionType.GET_TRANSACTION_DETAILS);
        ReportingDetails details = ReportingDetails.createReportingDetails();
        details.setBatchIncludeStatistics(true);
        transaction.setReportingDetails(details);

        Result<Transaction> result = (Result<Transaction>) merchant.postTransaction(transaction);
        System.out.println("Code : "+result.getMessages().get(0).getResultCode());
        System.out.println("Text : "+result.getMessages().get(0).getText());

        for (BatchDetails batchDetail : result.getReportingDetails().getBatchDetailsList()) {
            System.out.println("---------------------");
            System.out.println("ID : "+ batchDetail.getBatchId() );
            System.out.println("Settlement State : "+ batchDetail.getSettlementState().value());
            System.out.println("local settlementTime: "+ batchDetail.getSettlementTimeLocal().toString());
        }

Cannot use customer profile with API

    Merchant merchant = Merchant.createMerchant(authorizeEnvironment, authorizeLoginId, authorizeTransactionId);
    Subscription subscription = Subscription.createSubscription();
    subscription.setCustomerProfile(); <--- does not exist
    Transaction transaction = merchant.createARBTransaction(TransactionType.CREATE_SUBSCRIPTION, subscription);
    Result<Transaction> result = (Result<Transaction>) merchant.postTransaction(transaction);

how can I get / add sample bank details in Authorized.net ?

I'm using DebitBankAccount.java and simply I run it so it gives me following error
how can I get / add sample bank details in Authorized.net ?

11/05/15 22:24:44,05: INFO [pool-1-thread-1] (net.authorize.util.LogHelper:24) - Use Proxy: 'false' Failed Transaction: 2

public class DebitBankAccount {
    public static final String apiLoginId= "CXXXX";
    public static final String transactionKey= "XXXXXXXX";

    public static void main(String[] args) {
        //Common code to set for all requests
        ApiOperationBase.setEnvironment(Environment.SANDBOX);

        MerchantAuthenticationType merchantAuthenticationType  = new MerchantAuthenticationType() ;
        merchantAuthenticationType.setName(apiLoginId);
        merchantAuthenticationType.setTransactionKey(transactionKey);
        ApiOperationBase.setMerchantAuthentication(merchantAuthenticationType);

        // Populate the payment data
        PaymentType paymentType = new PaymentType();
        BankAccountType bankAccountType = new BankAccountType();
        bankAccountType.setAccountType(BankAccountTypeEnum.CHECKING);
        bankAccountType.setRoutingNumber("125000024");
        bankAccountType.setAccountNumber("12345678");
        bankAccountType.setNameOnAccount("John Doe");
        paymentType.setBankAccount(bankAccountType);

        // Create the payment transaction request
        TransactionRequestType txnRequest = new TransactionRequestType();
        txnRequest.setTransactionType(TransactionTypeEnum.AUTH_CAPTURE_TRANSACTION.value());
        txnRequest.setPayment(paymentType);
        txnRequest.setAmount(new BigDecimal(500.00));

        // Make the API Request
        CreateTransactionRequest apiRequest = new CreateTransactionRequest();
        apiRequest.setTransactionRequest(txnRequest);
        CreateTransactionController controller = new CreateTransactionController(apiRequest);
        controller.execute();


        CreateTransactionResponse response = controller.getApiResponse();

        if (response!=null) {

            // If API Response is ok, go ahead and check the transaction response
            if (response.getMessages().getResultCode() == MessageTypeEnum.OK) {

                TransactionResponse result = response.getTransactionResponse();
                if (result.getResponseCode().equals("1")) {
                    System.out.println(result.getResponseCode());
                    System.out.println("Successful Debit Bank Transaction");
                    System.out.println(result.getAuthCode());
                    System.out.println(result.getTransId());
                }
                else {
                    System.out.println("Failed Transaction: "+result.getResponseCode());
                }
            }
            else{
                System.out.println("Failed Transaction:  "+response.getMessages().getResultCode());
            }
        }
    }
} 

Sandbox TLS 1.2 support and Apache HttpClient/HttpCore best practices?

This SDK currently uses "DefaultHttpClient()" to make HTTP requests. As an experiment I upgraded the httpclient-4.0.1 and httpcore-4.0.1 JARs and added some functions to build a custom SSLContext into the HttpClient executed by the SDK API calls.

Does this SDK expect us to configure our servers to only make TLS 1.2 HTTPS requests?
Options like "-Dhttps.protocols=TLSv1.2 -Djdk.tls.client.protocols=TLSv1.2" or "SSLProtocol -all +TLSv1.2"

Is there a newer version of the SDK coming that has the upgraded HttpClient libraries built in for us?
Is there some way to insert a custom HttpClient into the
CreateTransactionController controller = new CreateTransactionController(apiRequest); controller.execute(); CreateTransactionResponse response = controller.getApiResponse();
or
response = merchant.postTransaction(transaction);
process?

So far, I've only been able to place new sandbox transactions with my modified SDK, changing my web and application server options has not worked yet.

Redesign

This API is needlessly difficult to use. It lacks a coherent abstraction for what it is actually doing. Ideally, this API would work like the following:

AuthorizeAndCaptureResponse authorizeAndCapture(boolean testMode, String userId, String userKey, String cardNumber, Expiration expiration, double amount) {
    try {
        Gateway gateway = new Gateway(testMode);
        Client client = new Client(userId, userKey);

        AuthorizeAndCaptureRequest request = client.getAuthorizeAndCaptureBuilder()
                                                 .setCardNumber(cardNumber)
                                                 .setExpiration(expiration)
                                                 .setAmount(amount)
                                                 .build();

        return (AuthorizeAndCaptureResponse) client.send(request, gateway);
    } catch(ValidationException e) {
        e.printStackTrace();
        return null;
    }
}

Gateway is responsible for processing requests. Client is responsible for providing builders for all of the request types and for sending authenticated requests to Gateway. The Response objects should provide straightforward access to the results by encapsulating their underlying objects rather than the obnoxious layers that we have to try to wrap our heads around now. Objects like Expiration provide more convenient and intuitive abstractions for things like the expiration date with methods like setMonth(int month) and setYear(int year) or similar constructors like Expiration(int month, int year). As a bonus, these kinds of objects can provide early validation to inform users when the data they've entered makes no sense.

Not only will this type of straightforward abstraction be easier for users to work with, but it should also be easier for you to maintain. I'm considering doing some of this work for you since I don't want to put the code I've written against your current API into production because of how hard it is to read and understand.

Also, you SHOULD NOT provide examples of embedding this kind of code into JSPs since that represents a severe violation of the Separation of Concerns. JSPs should only contain presentation logic and should delegate this kind of work to Servlets which should delegate it to Services which bear responsibility for the business logic.

Deleting User Profile via Java API returns a "reccord cannot be found error" but deletion successful

I am trying to delete user profiles in java via the code below.

net.authorize.cim.Transaction transaction=merchant.createCIMTransaction(TransactionType.DELETE_CUSTOMER_PROFILE);

transaction.setRefId(generateRefId());

transaction.setCustomerProfileId(profileId);

Result result = (Result) merchant.postTransaction(transaction);

Every response I get it the following

deleting user with profileId =32441194
Result Code: Error

E00040 - The record cannot be found.

The weird thing is the user profile Id is in fact active/correct and the deletion of the account completes successfully in the sandbox, even though the response claims there is an error.

Any ideas?

Updating payment profile with CIM fails for cardCode validation

When updating an existing customer payment profile (createCustomerPaymentProfileRequest) using CIM and the profile contains existing credit card info, the element includes an empty element which causes XML schema validation error. The element should only be included when a value is specified.

'Connection to https://apitest.authorize.net refused': 'java.net.ConnectException: Connection refused: connect', '[org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:127), org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147), org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108), org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415), org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641), org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576), org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554), net.authorize.util.HttpClient.executeXML(HttpClient.java:227), net.authorize.Merchant.postTransaction(Merchant.java:298), com.auth.net.commons.authorize.net.SettledTransactionDetails.main(SettledTransactionDetails.java:39)]'

Hello,

I am facing below error:

2016-08-18 11:28:34 INFO  net.authorize.util.HttpClient - Use Proxy: 'false'
2016-08-18 11:28:34 DEBUG o.a.h.i.conn.SingleClientConnManager - Get connection for route HttpRoute[{s}->https://apitest.authorize.net]
2016-08-18 11:28:35 DEBUG o.a.h.i.conn.DefaultClientConnection - Connection shut down
2016-08-18 11:28:35 DEBUG o.a.h.i.conn.SingleClientConnManager - Releasing connection org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter@14a2ec7
2016-08-18 11:28:35 WARN  net.authorize.util.HttpClient - Exception getting response: 'Connection to https://apitest.authorize.net refused': 'java.net.ConnectException: Connection refused: connect', '[org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:127), org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147), org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108), org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415), org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641), org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576), org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554), net.authorize.util.HttpClient.executeXML(HttpClient.java:227), net.authorize.Merchant.postTransaction(Merchant.java:298), com.auth.net.commons.authorize.net.SettledTransactionDetails.main(SettledTransactionDetails.java:39)]'
Exception in thread "main" java.lang.NullPointerException
    at net.authorize.reporting.Result.importRefId(Result.java:490)
    at net.authorize.reporting.Result.createResult(Result.java:58)
    at net.authorize.Merchant.postTransaction(Merchant.java:299)
    at com.auth.net.commons.authorize.net.SettledTransactionDetails.main(SettledTransactionDetails.java:39)

It looks like proxy is enabled and which is blocking the transaction to be hit to target system. We must need to set/write proxy code to allow proxy to pass this transaction in the following code, how we can do that ? Does Auth.net SDK allows such provision? It looks to me that Auth.net using HTTPClient API to make the call, so it must be possible to do that isn't it ?

BankAccountType for Business Account fails

See http://community.developer.authorize.net/t5/Integration-and-Testing/Java-SDK-Bugs-Report/m-p/39159#M21363

bug with BankAccountType. The CIM and ARB APIs expect a value of checking, savings, and businessChecking for the account type for bank account payments. However when the request is being built, the code simply lower cases the enum, therefore all the specific requests involing the the business checking type fail because it evaluates to businesschecking instead of businessChecking. You can see my temporary work around below. I added a second value value2 which holds the right value to be used when making a request.

package net.authorize.data.echeck;

import java.io.Serializable;

/**

  • Supported bank account types.
    *
    */
    public enum BankAccountType implements Serializable {
    CHECKING("CHECKING","checking"),
    BUSINESSCHECKING("BUSINESSCHECKING","businessChecking"),
    SAVINGS("SAVINGS","savings"),
    UNKNOWN("UNKNOWN","unknown");

    private final String value;
    private final String value2;

    private BankAccountType(String value, String value2) {
    this.value = value;
    this.value2 = value2;
    }

    public static BankAccountType findByValue(String value) {
    for(BankAccountType bankAccountType : values()) {
    if(bankAccountType.value.equals(value) || bankAccountType.value2.equals(value)) {
    return bankAccountType;
    }
    }

    return BankAccountType.UNKNOWN;
    

    }

    /**

    • @return the value
      */
      public String getValue() {
      return value;
      }

    /**

    • @return the value2
      */
      public String getValue2() {
      return value2;
      }
      }
      On both the arb/Transaction.java and cim/Transaction.java, i updated the following code:

if(bank_account.getBankAccountType() != null) {
Element account_type_el = document.createElement(AuthNetField.ELEMENT_ACCOUNT_TYPE.getFieldName());
account_type_el.appendChild(document.getDocument().createTextNode(bank_account.getBankAccountType().getValue().toLowerCase()));
bankacct_el.appendChild(account_type_el);
}
to make use of value2 instead of the lower cased value:

if(bank_account.getBankAccountType() != null) {
Element account_type_el = document.createElement(AuthNetField.ELEMENT_ACCOUNT_TYPE.getFieldName()); account_type_el.appendChild(document.getDocument().createTextNode(bank_account.getBankAccountType().getValue2()));
bankacct_el.appendChild(account_type_el);
}

ant build process flawed -- please remove or maintain

When the SDK is built from ant, the following error occurs whenever submitting a request:

SEVERE: Execution error for http post Message: 'java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy'

Also, the ant build produces jars labeled "1.8.2" rather than "1.8.9".

Please either remove the Apache Ant build process if it will not be maintained, or update it so that it produces identical results as using Apache Maven. Thanks!

No proxy authentication

Is it possible to implement proxy authentication? Or at least decouple code from util.HttpClient static calls to use custom configurable instance of HttpClient?

x_ref_trans_id not present

Currently, x_trans_id is sent for CNP transactions, but x_ref_trans_id must be used for CP. The Card Present implementation is built on top of AIM, but doesn't make the necessary change from x_trans_id to x_ref_trans_id.

UTF-8 encoding not set on StringEntity during HttpPost in HttpUtility.java

Hi,

I've been trying to migrate to use your SDK and found that I've been unable to send international characters without the request failing. I've figured out that you are missing encoding the StringEntity in HttpUtility.java.

Can you please change (currently line 68):

httpPost.setEntity(new StringEntity(xmlRequest));

to be:

httpPost.setEntity(new StringEntity(xmlRequest,"UTF-8"));

and it fixes the issue.

Thanks!

Upgrading to 1.8.2 causes 404

Hi,

I upgraded anet-java-sdk version from 1.8.1 to 1.8.2. Upon testing, I encountered a 404 when creating a transaction. It looks like the endpoint for Environment.SANDBOX was changed from test.authorize.net to sandbox.authorize.net . Here's the 404 I'm getting:

INFO : net.authorize.util.HttpClient - Use Proxy: 'false'
DEBUG: org.apache.http.wire -  >> "POST /gateway/transact.dll HTTP/1.1[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Content-Type: application/x-www-form-urlencoded; charset=utf-8[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Content-Length: 408[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Host: sandbox.authorize.net[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Connection: Keep-Alive[\r][\n]"
DEBUG: org.apache.http.wire -  >> "User-Agent: Apache-HttpClient/4.3.1 (java 1.5)[\r][\n]"
DEBUG: org.apache.http.wire -  >> "[\r][\n]"
DEBUG: org.apache.http.wire -  >> "x_tran_key=9Ktc364dmk6T94Fz&x_allow_partial_Auth=FALSE&x_market_type=2&x_card_num=&x_method=CC&x_delim_data=TRUE&x_exp_date=&x_relay_response=FALSE&x_login=3uDJcL26PRN&x_version=3.1&x_device_type=10&x_amount=1.75&x_test_request=FALSE&x_type=AUTH_CAPTURE&x_delim_char=%7C&x_cpversion=1.0&x_response_format=0&x_track2=&x_encap_char=&x_track1=BMASKED**0002%5ECARDUSER%2FJOHN%5EMASKED**0000MASKED**0000"
DEBUG: org.apache.http.wire -  << "HTTP/1.1 404 Not Found[\r][\n]"
DEBUG: org.apache.http.wire -  << "Content-Type: text/html[\r][\n]"
DEBUG: org.apache.http.wire -  << "Server: Microsoft-IIS/7.5[\r][\n]"
DEBUG: org.apache.http.wire -  << "X-Powered-By: ASP.NET[\r][\n]"
DEBUG: org.apache.http.wire -  << "Date: Fri, 10 Oct 2014 02:01:51 GMT[\r][\n]"
DEBUG: org.apache.http.wire -  << "Content-Length: 103[\r][\n]"
DEBUG: org.apache.http.wire -  << "[\r][\n]"

Any ideas why I'm getting a 404 when communicating with sandbox.authorize.net?

Thanks!

CreateCustomerProfileController disallows creating profile without payment methods

We are looking into managing all payment method information using CIM with hosted forms so that credit card information never passes through our services. However, since CreateCustomerProfileController's validation methods require that PaymentProfiles be provided, as currently implemented, you cannot use hosted forms until a customer profile exists, and you cannot create a customer profile without providing payment information, which forces credit card information to pass through the merchant's services at least once.

I was able to work around the issue by creating my own FixedCreateCustomerProfileController which doesn't validate PaymentProfiles or ValidationMode settings, but the correct fix would be to allow empty payment profile values and ValidationMode to be undefined whenever no payment profiles are provided.

private static class FixedCreateCustomerProfileController extends ApiOperationBase<CreateCustomerProfileRequest, CreateCustomerProfileResponse>  {
    public FixedCreateCustomerProfileController(CreateCustomerProfileRequest apiRequest) {
        super(apiRequest);
    }

    @Override
    protected void validateRequest() {
        CreateCustomerProfileRequest request = this.getApiRequest();

        if ( null == request.getProfile()) throw new NullPointerException("Profile cannot be null");
        // if ( null == request.getRefId()) throw new NullPointerException("RefId cannot be null");
        // if ( null == request.getValidationMode() || ValidationModeEnum.NONE == request.getValidationMode()) throw new NullPointerException("ValidationMode cannot be null");
        // if ( null == request.getProfile().getPaymentProfiles() || 0 == request.getProfile().getPaymentProfiles().size()) throw new NullPointerException("Payment Profile cannot be null or empty");
    }

    @Override
    protected Class<CreateCustomerProfileResponse> getResponseType() {
        return CreateCustomerProfileResponse.class;
    }
}

I also hit the non-null RefId validation issue, but I see that's been fixed in the Future branch.

ValidateCustomerPaymentProfile throwing exception.

Basically while running ValidateCustomerPaymentProfile.java, I was getting exceptions. This was caused because cardCode and CustomerShippingAddressID were not being set in the sample code. However, the controller validates these fields and throws exception if not found. Following is the piece of code which does the validation in the ValidateCustomerPaymentProfileController:

//validate required fields
if ( null == request.getCustomerProfileId()) throw new NullPointerException("CustomerProfileId cannot be null");
if ( null == request.getCardCode()) throw new NullPointerException("CardCode cannot be null");
if ( null == request.getCustomerPaymentProfileId()) throw new NullPointerException("CustomerPaymentProfileId cannot be null");
if ( null == request.getCustomerShippingAddressId()) throw new NullPointerException("CustomerShippingAddressId cannot be null");

Now in the API reference nothing is mentioned about which fields are required.

Remove log4j.xml from jar file

It has broken all the loggin of my jboss application and got me crazy until I found this. Not sure if it is a way to everride it, but it should not re-define the root logger

E00003: invalid child element 'track2'

Every time I set

PaymentType paymentType = new PaymentType();
CreditCardTrackType creditCardTrackType = new CreditCardTrackType();
creditCardTrackType.setTrack1("track1");
creditCardTrackType.setTrack2("track2");
paymentType.setTrackData(creditCardTrackType);

TransRetailInfoType retailInfo = new TransRetailInfoType();
retailInfo.setMarketType(MarketType.RETAIL.getValue());
retailInfo.setDeviceType(DeviceType.VIRTUAL_TERMINAL.getValue());

        // Create the payment transaction request
TransactionRequestType transactionRequestType = new TransactionRequestType();
transactionRequestType.setTransactionType(TransactionTypeEnum.AUTH_CAPTURE_TRANSACTION.value());
transactionRequestType.setPayment(paymentType);
transactionRequestType.setOrder(orderType);
transactionRequestType.setRetail(retailInfo);

I'm getting this error E00003:The element 'trackData' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has invalid child element 'track2' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'.

{
        "code" : "E00003",
        "text" : "An error occurred while parsing the XML request.",
        "description" : "This is the result of an XML parser error.",
        "integration_suggestions": "",
        "other_suggestions": ""
    }

if I remove track2 I get transaction Approved

Thanks

Cardpresent result does not handle split tender ID

The result object for AIM card present currently does not provide a method of obtaining the split tender ID or the prepaid card elements.

This data can be accessed by reading the XML response directly, but it should be parsed automatically like the other response elements.

createCustomerProfile: null cardCode results in invalid XML error

Hi,

I'm using the CIM API in your sdk. I have a use case where I need to be able to create a customer profile with a payment profile that does not have a card code. To do that, I set the card code to null and then call the API. However, the SDK calls Authorize.net and receives an error message:

[Error] E00003: The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:cardCode' element is invalid - The value '' is invalid according to its datatype 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:cardCode' - The Pattern constraint failed.

The reason it receives the error is because the SDK creates the cardCode element in the XML and it is left empty (Please notice the '' in the request below):

<?xml version="1.0"?>
<createCustomerProfileRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
  <merchantAuthentication>
    <name>LOGIN_ID_MASKED</name>
    <transactionKey>TRANSACTION_KEY_MASKED</transactionKey>
  </merchantAuthentication>
  <profile>
    <merchantCustomerId>AAAAAA</merchantCustomerId>
    <description>df98d979-0dd0-4f98-bc66-ed654b3f1388</description>
    <email></email>
    <paymentProfiles>
      <customerType>individual</customerType>
      <billTo>
        <firstName></firstName>
        <lastName></lastName>
        <company></company>
        <address></address>
        <city></city>
        <state></state>
        <zip></zip>
        <country></country>
        <phoneNumber></phoneNumber>
        <faxNumber></faxNumber>
      </billTo>
      <payment>
        <creditCard>
          <cardNumber>MASKED**0002</cardNumber>
          <expirationDate>2029-07</expirationDate>
          <cardCode></cardCode>
        </creditCard>
      </payment>
    </paymentProfiles>
  </profile>
  <validationMode>testMode</validationMode>
</createCustomerProfileRequest>

Here is a test case that you can use to reproduce this issue:

@Test
public void testCase() {
    final String authorizeNetCardNotPresentApiLoginId = "YOUR_API_LOGIN_ID";
    final String authorizeNetCardNotPresentTransactionKey = "YOUR_TRANSACTION_KEY";

    final Merchant merchant = Merchant.createMerchant(Environment.SANDBOX, authorizeNetCardNotPresentApiLoginId, authorizeNetCardNotPresentTransactionKey);

    final CreditCard creditCard = CreditCard.createCreditCard();
    creditCard.setCreditCardNumber("370000000000002");
    creditCard.setExpirationDate("2029-07");
    creditCard.setCardCode(null);

    final Address address = Address.createAddress();
    address.setZipPostalCode(null);

    final PaymentProfile paymentProfile = PaymentProfile.createPaymentProfile();
    paymentProfile.addPayment(Payment.createPayment(creditCard));
    paymentProfile.setCustomerType(CustomerType.INDIVIDUAL);
    paymentProfile.setBillTo(address);

    final CustomerProfile customerProfile = CustomerProfile.createCustomerProfile();
    customerProfile.setMerchantCustomerId("AAAAAA");
    customerProfile.setDescription(UUID.randomUUID().toString());

    final ValidationModeType validationMode = ValidationModeType.TEST_MODE;

    // Create a new customer profile
    final net.authorize.cim.Transaction transaction = merchant.createCIMTransaction(TransactionType.CREATE_CUSTOMER_PROFILE);
    transaction.setCustomerProfile(customerProfile);
    transaction.addPaymentProfile(paymentProfile);
    transaction.setValidationMode(validationMode);

    final net.authorize.cim.Result<Transaction> result = (net.authorize.cim.Result<Transaction>) merchant.postTransaction(transaction);

    if (false == result.isOk()) {
        final StringBuilder stringBuilder = new StringBuilder();

        boolean isFirst = true;
        for (final Message message : result.getMessages()) {
            final String code = message.getCode();
            final String text = message.getText();

            if (isFirst == false) {
                stringBuilder.append(", ");
            }
            stringBuilder.append(code+": "+text);

            isFirst = false;
        }

        throw new RuntimeException("["+result.getResultCode()+"] "+stringBuilder.toString());
    }

}

Luckily, the fix for this is very simple. In your net.authorize.cim.Transaction.java file, in the addPayment method you need to modify the following lines:

Element card_code_el = document.createElement(AuthNetField.ELEMENT_CARD_CODE.getFieldName());
card_code_el.appendChild(document.getDocument().createTextNode(credit_card.getCardCode()));
cc_el.appendChild(card_code_el);

All you need to do is wrap an if statement around it, like so:

if (StringUtils.isNotEmpty(credit_card.getCardCode())) {
    Element card_code_el = document.createElement(AuthNetField.ELEMENT_CARD_CODE.getFieldName());
    card_code_el.appendChild(document.getDocument().createTextNode(credit_card.getCardCode()));
    cc_el.appendChild(card_code_el);
}

NumberFormatException when voiding a transaction made with Track Data

Hi,

I tested the use case where a transaction is created using the card's track data (a card present transaction) and then followed up with voiding that transaction. When I void it, it fails with a NumberFormatException. I think I've traced it down to the response code being "1.0" instead of "1", which triggers the exception when trying to convert it to an Integer. It's important to note that if the transaction is created without using the track data, say by setting the card number manually, the void works fine (that's because the response code returns a "1" instead of a "1.0" allowing a successful integer conversion.

Also, note that I'm using a Card Not Present (CNP) Authorize.net account with CIM enabled, if that matters.

Let's start with the test case (substitute your credentials):

package com.thinkreservations.service.gateway.impl;

import java.math.BigDecimal;

import net.authorize.Environment;
import net.authorize.Merchant;
import net.authorize.Transaction;
import net.authorize.data.creditcard.CreditCard;

import org.junit.Test;

import com.thinkreservations.service.exception.restful.CreditCardProcessorFailedException;

public class AuthorizeNetTest {

    @Test
    public void test() {

        final String apiLoginId = "YOUR_API_LOGIN_ID_TO_A_CARD_NOT_PRESENT_ACCOUNT";
        final String transactionKey = "YOUR_TRANSACTION_KEY_TO_A_CARD_NOT_PRESENT_ACCOUNT";

        // Create the Card Present transaction
        String transactionId;
        {
            final Merchant merchant = Merchant.createMerchant(Environment.SANDBOX, apiLoginId, transactionKey);
            merchant.setDeviceType(net.authorize.DeviceType.VIRTUAL_TERMINAL);
            merchant.setMarketType(net.authorize.MarketType.RETAIL);

            final CreditCard creditCard = CreditCard.createCreditCard();
            creditCard.setTrack1("%B370000000000002^CARDUSER/JOHN^1803101000000000020000831000000?");

            final BigDecimal amount = BigDecimal.valueOf(1.99);

            final net.authorize.aim.Transaction transaction = merchant.createAIMTransaction(net.authorize.TransactionType.AUTH_CAPTURE, amount);
            transaction.setCreditCard(creditCard);

            final net.authorize.aim.cardpresent.Result<Transaction> result = (net.authorize.aim.cardpresent.Result<Transaction>) merchant.postTransaction(transaction);

            if (false == result.isApproved()) {
                throw new CreditCardProcessorFailedException("["+result.getResponseCode()+"] "+result.getResponseReasonCodes().get(0)+": "+result.getResponseReasonCodes().get(0).getReasonText());
            }

            transactionId = result.getTransId();
        }

        // Void the transaction
        {
            final Merchant merchant = Merchant.createMerchant(Environment.SANDBOX, apiLoginId, transactionKey);

            final net.authorize.aim.Transaction transaction = merchant.createAIMTransaction(net.authorize.TransactionType.VOID, null);
            transaction.setTransactionId(transactionId);

            final net.authorize.aim.Result<Transaction> result = (net.authorize.aim.Result<Transaction>) merchant.postTransaction(transaction);

            if (false == result.isApproved()) {
                throw new CreditCardProcessorFailedException("["+result.getResponseCode()+"] "+result.getResponseText());
            }
        }
    }

}

Wire log:

DEBUG: org.apache.http.wire -  >> "POST /gateway/transact.dll HTTP/1.1[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Content-Type: application/x-www-form-urlencoded; charset=utf-8[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Content-Length: 408[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Host: test.authorize.net[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Connection: Keep-Alive[\r][\n]"
DEBUG: org.apache.http.wire -  >> "User-Agent: Apache-HttpClient/4.3.1 (java 1.5)[\r][\n]"
DEBUG: org.apache.http.wire -  >> "[\r][\n]"
DEBUG: org.apache.http.wire -  >> "x_tran_key=9Ktc364dmk6T94Fz&x_allow_partial_Auth=FALSE&x_market_type=2&x_card_num=&x_method=CC&x_delim_data=TRUE&x_exp_date=&x_relay_response=FALSE&x_login=3uDJcL26PRN&x_version=3.1&x_device_type=10&x_amount=1.99&x_test_request=FALSE&x_type=AUTH_CAPTURE&x_delim_char=%7C&x_cpversion=1.0&x_response_format=0&x_track2=&x_encap_char=&x_track1=BMASKED**0002%5ECARDUSER%2FJOHN%5EMASKED**0000MASKED**0000"
DEBUG: org.apache.http.wire -  << "HTTP/1.1 200 OK[\r][\n]"
DEBUG: org.apache.http.wire -  << "Cache-Control: private, must-revalidate, max-age=0[\r][\n]"
DEBUG: org.apache.http.wire -  << "Content-Length: 516[\r][\n]"
DEBUG: org.apache.http.wire -  << "Content-Type: text/xml[\r][\n]"
DEBUG: org.apache.http.wire -  << "Expires: Tue, 01 Jan 1980 00:00:00 GMT[\r][\n]"
DEBUG: org.apache.http.wire -  << "Server: Microsoft-IIS/7.5[\r][\n]"
DEBUG: org.apache.http.wire -  << "X-Powered-By: ASP.NET[\r][\n]"
DEBUG: org.apache.http.wire -  << "Date: Fri, 10 Oct 2014 18:34:24 GMT[\r][\n]"
DEBUG: org.apache.http.wire -  << "Connection: close[\r][\n]"
DEBUG: org.apache.http.wire -  << "[\r][\n]"
DEBUG: org.apache.http.wire -  << "<?xml version="1.0" ?><response><ResponseCode>1</ResponseCode><Messages><Message><Code>1</Code><Description><![CDATA[This transaction has been approved.]]></Description></Message></Messages><AuthCode><![CDATA[AXOFVN]]></AuthCode><AVSResultCode>Y</AVSResultCode><CVVResultCode></CVVResultCode><TransID>2222211937</TransID><RefTransID></RefTransID><TransHash>305F339BA37F634C7B4FA0A7DA8894EC</TransHash><TestMode>0</TestMode><AccountNumber>XXXX0002</AccountNumber><AccountType>American Express</AccountType></response>"
DEBUG: org.apache.http.wire -  >> "POST /gateway/transact.dll HTTP/1.1[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Content-Type: application/x-www-form-urlencoded; charset=utf-8[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Content-Length: 229[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Host: test.authorize.net[\r][\n]"
DEBUG: org.apache.http.wire -  >> "Connection: Keep-Alive[\r][\n]"
DEBUG: org.apache.http.wire -  >> "User-Agent: Apache-HttpClient/4.3.1 (java 1.5)[\r][\n]"
DEBUG: org.apache.http.wire -  >> "[\r][\n]"
DEBUG: org.apache.http.wire -  >> "x_tran_key=9Ktc364dmk6T94Fz&x_allow_partial_Auth=FALSE&x_trans_id=2222211937&x_version=3.1&x_amount=0.00&x_delim_data=TRUE&x_type=VOID&x_test_request=FALSE&x_delim_char=%7C&x_relay_response=FALSE&x_encap_char=&x_login=3uDJcL26PRN"
DEBUG: org.apache.http.wire -  << "HTTP/1.1 200 OK[\r][\n]"
DEBUG: org.apache.http.wire -  << "Cache-Control: private, must-revalidate, max-age=0[\r][\n]"
DEBUG: org.apache.http.wire -  << "Content-Length: 128[\r][\n]"
DEBUG: org.apache.http.wire -  << "Content-Type: text/html[\r][\n]"
DEBUG: org.apache.http.wire -  << "Expires: Tue, 01 Jan 1980 00:00:00 GMT[\r][\n]"
DEBUG: org.apache.http.wire -  << "Server: Microsoft-IIS/7.5[\r][\n]"
DEBUG: org.apache.http.wire -  << "X-Powered-By: ASP.NET[\r][\n]"
DEBUG: org.apache.http.wire -  << "Date: Fri, 10 Oct 2014 18:34:24 GMT[\r][\n]"
DEBUG: org.apache.http.wire -  << "Connection: close[\r][\n]"
DEBUG: org.apache.http.wire -  << "[\r][\n]"
DEBUG: org.apache.http.wire -  << "1.0|1|1|This transaction has been approved.||P||2222211937|12B1AA66FCCF02D998C3CD2623973A91||||||||||||XXXX0002|American Express"

Stack trace:

java.lang.NumberFormatException: For input string: "1.0"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Integer.parseInt(Integer.java:458)
    at java.lang.Integer.parseInt(Integer.java:499)
    at net.authorize.aim.Result.createResult(Result.java:33)
    at net.authorize.Merchant.postTransaction(Merchant.java:287)
    at com.thinkreservations.service.gateway.impl.AuthorizeNetTest.test(AuthorizeNetTest.java:53)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

If you look at the last line of the wire log, you'll notice that the response code (the first number in the string) is set to "1.0". That causes line 33 in Result.java to throw an exception. Here's the relevant code (the Integer.parseInt method throws the exception):

String responseCodeStr = responseMap.get(ResponseField.RESPONSE_CODE);
result.responseCode = responseCodeStr!=null && !"".equals(responseCodeStr)?
        ResponseCode.findByResponseCode(Integer.parseInt(responseCodeStr)):
            ResponseCode.ERROR;

Thanks for looking into this.

Alfred

Issues running SDK on Java 1.5

XMLUtility.java line 73 uses java.lang.String.isEmpty() which is only available starting from java 1.6. So API fails to run on Java 1.5

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.