[ http://issues.apache.org/jira/browse/OFBIZ-274?page=all ]

Marco Risaliti updated OFBIZ-274:
---------------------------------

    Attachment: Dev.pdf
                java_aim.zip

> Authorize.NET Payment Gateway Implementation
> --------------------------------------------
>
>                 Key: OFBIZ-274
>                 URL: http://issues.apache.org/jira/browse/OFBIZ-274
>             Project: OFBiz (The Open for Business Project)
>          Issue Type: New Feature
>          Components: accounting
>    Affects Versions: SVN trunk
>            Reporter: Marco Risaliti
>         Attachments: AIM_guide.pdf, aimdoc.txt, AIMPaymentServices.java.txt, 
> authnet_20060614.tgz, authnetcredit.patch, AuthorizeResponse.java.txt, 
> Dev.pdf, java_aim.zip
>
>
> A lot of people over the years have requested and implemented Authorize.NET 
> payment gateway for OFBiz. This issue is for an official implementation 
> that's part of the standard OFBiz distribution. 
> I'm going to start by posting some suggestions from Andy on how to implement 
> it and also some documentation and samples. If you have code that you can 
> share, please use this issue tracker. 
>  
>  
>  All    Comments    Work Log    Change History       Sort Order:   
> Comment by Si Chen [26/Jul/05 01:52 PM] [ Permlink ] 
> Andy's suggestions (from email): 
> > Looks like this will be very simple to implement. It does not appear that 
> > any external libraries will be needed so this integration will be able to 
> > come working with OFBiz out of the box. 
> > 
> > Just follow the examples included in OFBiz for CyberSource or any of the 
> > other currently implemented gateways this should give you a good start. 
> > 
> > You'll want to add the necessary configuration fields to the payment 
> > properties file. The transaction key, etc. 
> > 
> > -Andy 
> Comment by Si Chen [26/Jul/05 01:53 PM] [ Permlink ] 
> Sample Java code for Authorize.NET. 
> Comment by Si Chen [26/Jul/05 01:56 PM] [ Permlink ] 
> Official API guide 
> Comment by Si Chen [26/Jul/05 01:57 PM] [ Permlink ] 
> More developer's guide. 
> Comment by David E. Jones [30/Nov/05 11:06 PM] [ Permlink ] 
> BTW, this last comment was from Brett Palmer, not from me. It is a re-post 
> with some small changes of what Brett sent before. 
> Comment by David E. Jones [30/Nov/05 11:22 PM] [ Permlink ] 
> Here is our implementation of the Authorize.net interface. We use a simple 
> service to invoke the Authorize.net credit card processor. The service calls 
> the processCard method and returns the response from Authorize.net. Authorize 
> uses a simple HTTP protocol so it is pretty easy to work with. You will also 
> notice that we Authorize's test credit whenever we process a credit card that 
> starts with "7777". This is helpful when you want to test your implementation 
> and if you want to verify if Authorize is working. 
> We wrote this service before we started using common ofbiz credit card 
> processors like Verisign. We would like to see a common Authorize.net 
> implementation to follows the ofbiz standards. 
> /*********************************************/ 
> public class AuthorizeNet { 
>     public static final String module = AuthorizeNet.class.getName(); 
>     public static HashMap validateCCard(Map params) { 
> HashMap results = new HashMap(); 
> if ("7777".equals(params.get("ccNumber"))) { 
> String number = "4111111111111111"; 
> String monthExp = "01"; 
> String yearExp = "01"; 
> String type = "VISA"; 
> String orderId = "1234"; 
> String testReq = "TRUE"; 
> String transAmt = "100"; 
> String description = "test authorization"; 
> Map testParams = new HashMap(); 
> testParams.put("ccType",type); 
> testParams.put("ccNumber",number); 
> testParams.put("ccMonth",monthExp); 
> testParams.put("ccYear",yearExp); 
> testParams.put("orderId",orderId); 
> testParams.put("testReq",testReq); 
> testParams.put("ccTransDescription",description); 
> testParams.put("ccTransAmount",transAmt); 
> results = processCard(testParams); 
> } else { 
> params.put("testReq","FALSE"); 
> params.put("ccTransDescription","authorization transaction"); 
> results = processCard(params); 
> } 
> return results; 
> } 
> private static String getUrl() { 
> Properties props = UtilProperties.getProperties("authorize.properties"); 
> String url = (String) props.get("authorize.net.url"); 
> Debug.logInfo("Authorize url: " + url ,module); 
> //return "https://transact.authorize.net/gateway/transact.dll";; 
> return url; 
> } 
> private static HashMap processCard(Map params) { 
> HashMap result = new HashMap(); 
> String type = (String) UtilFormatOut.checkNull((String)params.get("ccType")); 
> String number = (String) 
> UtilFormatOut.checkNull((String)params.get("ccNumber")); 
> String monthExp = (String) 
> UtilFormatOut.checkNull((String)params.get("ccMonth")); 
> String yearExp = (String) 
> UtilFormatOut.checkNull((String)params.get("ccYear")); 
> String orderId = (String) 
> UtilFormatOut.checkNull((String)params.get("orderId")); 
> String testReq = (String) 
> UtilFormatOut.checkNull((String)params.get("testReq")); 
> String amount = (String) 
> UtilFormatOut.checkNull((String)params.get("ccTransAmount")); 
> String description = (String) 
> UtilFormatOut.checkNull((String)params.get("ccTransDescription")); 
> String url = getUrl(); 
> String expDate = monthExp + yearExp; 
> Debug.logInfo("type = " + type,module); 
> Debug.logInfo("number = " + number,module); 
> Debug.logInfo("amount = " + amount,module); 
> Debug.logInfo("monthExp = " + monthExp,module); 
> Debug.logInfo("yearExp = " + yearExp,module); 
> Debug.logInfo("orderId = " + orderId,module); 
> Debug.logInfo("testReq = " + testReq,module); 
> Debug.logInfo("amount = " + amount,module); 
> Debug.logInfo("description = " + description,module); 
> // check minimum required values 
> if ((amount.length() == 0) || (number.length() == 0) || 
> (testReq.length() == 0)||(expDate.length() == 0) || 
> (type.length() == 0) || (orderId.length() == 0) || 
> (amount.length() == 0) || (description.length() == 0)) { 
> result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); 
> result.put(ModelService.ERROR_MESSAGE, "Minimum required - invalid values"); 
> return result; 
> } 
> Map data = new HashMap(); 
> String phone1 = 
> (String)UtilFormatOut.checkNull((String)params.get("contactPhone1")); 
> String phone2 = 
> (String)UtilFormatOut.checkNull((String)params.get("contactPhone2")); 
> String phone3 = 
> (String)UtilFormatOut.checkNull((String)params.get("contactPhone3")); 
> String phone = phone1 + "-" + phone2 + "-" + phone3; // not sure of the 
> format here 
> // contact information 
> data.put("x_first_name",UtilFormatOut.checkNull((String)params.get("billingFirstName")));
>  
> data.put("x_last_name",UtilFormatOut.checkNull((String)params.get("billinglastName")));
>  
> data.put("x_phone",phone); 
> data.put("x_address",UtilFormatOut.checkNull((String)params.get("billingAddress1")));
>  
> data.put("x_city",UtilFormatOut.checkNull((String)params.get("billingCity")));
>  
> data.put("x_state",UtilFormatOut.checkNull((String)params.get("billingState")));
>  
> data.put("x_zip",UtilFormatOut.checkNull((String)params.get("billingZip"))); 
> data.put("x_country",UtilFormatOut.checkNull((String)params.get("billingCountry")));
>  
> data.put("x_email",UtilFormatOut.checkNull((String)params.get("email"))); 
> // order information 
> data.put("x_card_num",number); 
> data.put("x_exp_date",expDate); 
> data.put("x_amount",amount); 
> data.put("x_cust_id","in2m-" + orderId); 
> data.put("x_invoice_num","in2m-" + orderId); 
> data.put("x_description",description); 
> // shipping information 
> if( "true".equals(params.get(UserEnroll.SETUP_SHIPPING))) { 
> data.put("x_ship_to_first_name",UtilFormatOut.checkNull((String)params.get("shippingFirstName")));
>  
> data.put("x_ship_to_last_name",UtilFormatOut.checkNull((String)params.get("shippingLastName")));
>  
> data.put("x_ship_to_address",UtilFormatOut.checkNull((String)params.get("shippingAddress")));
>  
> data.put("x_ship_to_city",UtilFormatOut.checkNull((String)params.get("shippingCity")));
>  
> data.put("x_ship_to_state",UtilFormatOut.checkNull((String)params.get("shippingState")));
>  
> data.put("x_ship_to_zip",UtilFormatOut.checkNull((String)params.get("shippingZip")));
>  
> data.put("x_ship_to_country",UtilFormatOut.checkNull((String)params.get("shippingCountry")));
>  
> }else{ 
> data.put("x_ship_to_first_name",UtilFormatOut.checkNull((String)params.get("billingFirstName")));
>  
> data.put("x_ship_to_last_name",UtilFormatOut.checkNull((String)params.get("billingLastName")));
>  
> data.put("x_ship_to_address",UtilFormatOut.checkNull((String)params.get("billingAddress")));
>  
> data.put("x_ship_to_city",UtilFormatOut.checkNull((String)params.get("billingCity")));
>  
> data.put("x_ship_to_state",UtilFormatOut.checkNull((String)params.get("billingState")));
>  
> data.put("x_ship_to_zip",UtilFormatOut.checkNull((String)params.get("billingZip")));
>  
> data.put("x_ship_to_country",UtilFormatOut.checkNull((String)params.get("billingCountry")));
>  
> } 
> // authorize configuration defaults 
> data.put("x_version","3.1"); 
> data.put("x_delim_data","TRUE"); 
> data.put("x_method","CC"); 
> data.put("x_type","AUTH_ONLY"); 
> data.put("x_email_customer","FALSE"); 
> data.put("x_email_merchant","TRUE"); 
> data.put("x_Test_Request",testReq); 
> data.put("x_relay_reponse","FALSE"); 
> data.put("x_login","XXXXX"); 
> data.put("x_tran_key","XXXXX"); 
> Debug.logInfo("Authorize.net data string " + data.toString(),module); 
> String respCode = EcommerceServices.VALID; 
> try { 
> HttpClient httpClient = new HttpClient(url,data); 
> httpClient.setClientCertificateAlias("AUTHORIZE_NET"); 
> String httpResponse = httpClient.post(); 
> AuthorizeResponse authorizeResponse = new AuthorizeResponse(httpResponse); 
> String authRespCode = authorizeResponse.get("x_response_code"); 
> if (!authRespCode.equals("1")) { 
> respCode = EcommerceServices.DECLINED; 
> } 
> result.put("httpResponse",httpResponse); 
> result.put("authorizeResponse",authorizeResponse); 
> } catch (HttpClientException e) { 
> respCode = EcommerceServices.PENDING; 
> } 
> result.put("respCode",respCode); 
> result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); 
> return result; 
> } 
> } 
> Comment by Kyle Tippetts [17/Jan/06 06:59 PM] [ Permlink ] 
> Skeletal Authorize.Net implementation 
> Comment by Kyle Tippetts [17/Jan/06 07:04 PM] [ Permlink ] 
> Here's a skeletal implementation based on what David posted here earlier, and 
> designed (to the best of my knowledge/ability) to work with the OFBiz credit 
> card processing system. (See the attached AIMPaymentServices and 
> AuthorizeResponse classes above). I only implemented the AUTH_CAPTURE 
> process, since that's what my client wanted (and didn't want OFBiz to handle 
> the capture -- go figure). Anyway, it's a start, I suppose. Any suggestions 
> would be *greatly* appreciated. 
> Here is a snippet of the authorizedotnet payment configuration from 
> payment.properties and below it the service definition. I'm sure the service 
> def could be cleaned up, but there it is: 
> ############################################ 
> # Authorize.Net Configuration 
> ############################################ 
> # Transaction Url 
> payment.authorizedotnet.url=https://secure.authorize.net/gateway/transact.dll 
> # Version 
> payment.authorizedotnet.version=3.1 
> # Delimited data 
> payment.authorizedotnet.delimited=TRUE 
> # Delimited Character 
> payment.authorizedotnet.delimiter=| 
> # Method 
> payment.authorizedotnet.method=CC 
> # Transaction Type 
> payment.authorizedotnet.type=AUTH_CAPTURE 
> # Email Customer? 
> payment.authorizedotnet.emailcustomer=FALSE 
> # Email Merchant? 
> payment.authorizedotnet.emailmerchant=TRUE 
> # Test Mode 
> payment.authorizedotnet.test=TRUE 
> # Relay Response? 
> payment.authorizedotnet.relay=FALSE 
> # Username 
> payment.authorizedotnet.login= 
> # Password 
> payment.authorizedotnet.password= 
> # Default Transaction Description 
> payment.authorizedotnet.transdescription= 
> -------------------------------------------------------- 
> ### Service Definition ### 
> <service name="aimAuthCapture" engine="java" 
> location="org.ofbiz.accounting.thirdparty.authorizedotnet.AIMPaymentServices" 
> invoke="ccAuthCapture"> 
> <attribute name="billingAddress" type="GenericValue" mode="IN" 
> optional="true"/> 
> <attribute name="cardSecurityCode" type="Object" mode="IN" optional="true"/> 
> <attribute name="contactEmail" type="Object" mode="IN" optional="true"/> 
> <attribute name="contactPerson" type="Object" mode="IN" optional="true"/> 
> <attribute name="creditCard" type="GenericValue" mode="IN" optional="true"/> 
> <attribute name="currency" type="Object" mode="IN" optional="true"/> 
> <attribute name="orderId" type="String" mode="IN" optional="true"/> 
> <attribute name="orderItems" type="Object" mode="IN" optional="true"/> 
> <attribute name="orderPaymentPreference" type="Object" mode="IN" 
> optional="true"/> 
> <attribute name="paymentConfig" type="Object" mode="IN" optional="true"/> 
> <attribute name="processAmount" type="Double" mode="INOUT" optional="true"/> 
> <attribute name="shippingAddress" type="GenericValue" mode="IN" 
> optional="true"/> 
> <attribute name="authResult" type="Boolean" mode="OUT" optional="true"/> 
> <attribute name="captureResult" type="Boolean" mode="OUT" optional="true"/> 
> <attribute name="captureAmount" type="Double" mode="OUT" optional="true"/> 
> <attribute name="captureFlag" type="String" mode="OUT" optional="true"/> 
> <attribute name="captureMessage" type="String" mode="OUT" optional="true"/> 
> <attribute name="authCode" type="String" mode="OUT" optional="true"/> 
> <attribute name="authRefNum" type="String" mode="OUT" optional="false"/> 
> <attribute name="authFlag" type="String" mode="OUT" optional="true"/> 
> <attribute name="authMessage" type="String" mode="OUT" optional="true"/> 
> <attribute name="cvCode" type="String" mode="OUT" optional="true"/> 
> <attribute name="avsCode" type="String" mode="OUT" optional="true"/> 
> <attribute name="scoreCode" type="String" mode="OUT" optional="true"/> 
> <attribute name="captureCode" type="String" mode="OUT" optional="true"/> 
> <attribute name="captureRefNum" type="String" mode="OUT" optional="true"/> 
> <attribute name="internalRespMsgs" type="List" mode="OUT" optional="true"/> 
> <attribute name="customerRespMsgs" type="List" mode="OUT" optional="true"/> 
> </service> 
> Comment by Si Chen [20/Jan/06 06:00 PM] [ Permlink ] 
> Kyle, 
> I'll help you with this. Would you mind sending in one patch file including 
> the config, the service definitions, and the .java files you made? In general 
> that is a good thing to do--copying and pasting can lead to errors. 
> Thanks, 
> Si 
> Comment by Kyle Tippetts [21/Jan/06 11:02 PM] [ Permlink ] 
> Si, 
> Thanks for helping me out -- I'm new to all of this. To that end, can you 
> direct me to some instructions on how to create a patch file? I can't seem to 
> find anything online that provides that information. I think I need to use 
> diff and patch, but I want to make sure I do it right.... 
> Thanks, 
> --Kyle 
> Comment by Si Chen [25/Jan/06 09:11 AM] [ Permlink ] 
> Go to your ofbiz/ directory and from the command line 
> $ svn diff > ofbiz385.patch 
> Then upload that file ofbiz385.patch 
> If you don't have the command line svn, go download it from here: 
> http://subversion.tigris.org/project_packages.html 
> There may also be plugins for eclipse, etc., but the idea is the same. 
> Comment by Fred Forester [10/Jun/06 01:10 PM] [ Permlink ] 
> Si, 
> have you done any work on this? If not I may run with it if that's ok. 
> Thanx 
> Fred 
> Comment by Si Chen [13/Jun/06 11:59 AM] [ Permlink ] 
> If you could that'd be great! 
> Comment by Fred Forester [14/Jun/06 10:05 AM] [ Permlink ] 
> Si, 
> I have something that works with version 3.0 of the certification gateway. 
> before I submit it I wanted to know the proper license info I should add if 
> any. 
> Thanx 
> Fred 
> Comment by Jacopo Cappellato [14/Jun/06 10:08 AM] [ Permlink ] 
> Hi Fred, 
> you'll find the license header in the file "APACHE2_HEADER" in the OFBiz 
> folder. 
> Thanks for asking this. 
> Comment by Fred Forester [14/Jun/06 10:48 AM] [ Permlink ] 
> Si, 
> version 3.0 only allows Auth,Capture,AuthCapture. there was some paranoia in 
> setting up a transkey on our account so I couldn't use 3.1. 
> The test property will log more data but testing is done via the 
> certification url. you can use live cards or test card #s. I havent tried the 
> live url but everything passes on the certification url. 
> thanx 
> Fred 
> Comment by Fred Forester [22/Jun/06 01:23 PM] [ Permlink ] 
> I recently founnd that it is possible to handle a credit transaction with AIM 
> 3.0. 
> I'll try to get to it in a few weeks. 
> Fred 
> Comment by Si Chen [23/Jun/06 01:00 PM] [ Permlink ] 
> Ok, that'd be great! 
> Comment by Fred Forester [26/Jun/06 12:48 PM] [ Permlink ] 
> si, 
> this should add support for the CREDIT transaction. I was not able to do much 
> testing on this since the test gateway doesn't return a transid. according to 
> authdotnet you have to "test" these "live" :). 
> Comment by Si Chen [26/Jun/06 04:25 PM] [ Permlink ] 
> So should I wait for your AIM 3.0 implementation or look at these as they 
> are? 
> Comment by Fred Forester [26/Jun/06 04:33 PM] [ Permlink ] 
> Si, 
> these should do it. 
> authnet_20060614.tgz, authnetcredit.patch 
> and this is the 3.0 implementation. 
> Thanx. 
> Fred 
>   
> Comment by Leon Torres [27/Jun/06 05:38 PM] [ Permlink ] 
> Hi Fred, 
> The authnet_20060614.tgz, authnetcredit.patch have been committed into ofbiz 
> accounting as of r 7883. It would be nice if you could add some documentation 
> too, like how the test is triggered. Some of the comments and logging could 
> also be improved or cleaned up, otherwise it's looking good. Just send a 
> patch against 7883. 
> Leon 
> Comment by Fred Forester [27/Jun/06 05:47 PM] [ Permlink ] 
> Hi Leon 
> Sure, I can put something together for doc. 
> thanx for getting this in. 
> Fred 
> Comment by Fred Forester [28/Jun/06 05:07 PM] [ Permlink ] 
> Hi Leon, 
> Here is a text file with a short writeup. 
> Thanx 
> Fred 

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to