Straight Capture (Do we need doauthorize?)

For general questions and discussions specific to the AbleCommerce 7.0 Asp.Net product.
Post Reply
mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Straight Capture (Do we need doauthorize?)

Post by mezojeff » Thu Jan 28, 2010 10:55 am

Hello,

I'm trying to implement a gateway for Braintree Payment Solutions. There API is very simple in that it has you simply pass a direct post the server that includes your username and pass as the parameters. In a test transaction I would simply pass this to the gateway

username=demoapi&password=password1&ccnumber=4111111111111111&ccexp=1010&type=sale&amount=10.00&customer_vault=add_customer

and it would return a query string with the response items. I have the source code for the authorize.net implementation and it seems like it is way more than I need. I have been using this link

http://wiki.ablecommerce.com/index.php/ ... nt_Gateway

As a guide but it doesn't really explain the order in which ablecommerce executes these items. I'm probably overlooking something, but if someone can possibly break the process down for me perhaps I can understand what's going on in the code sample a bit better.

Another question I have is, if my gateway supports recurring billing and someone buys a subscription item does abelcommerce automatically fire the DoAuthorizeRecurring method?

Thanks,

User avatar
mazhar
Master Yoda
Master Yoda
Posts: 5084
Joined: Wed Jul 09, 2008 8:21 am
Contact:

Re: Straight Capture (Do we need doauthorize?)

Post by mazhar » Fri Jan 29, 2010 7:28 am

In sample gateway code you will see three major function types. 1)- Required for gateway interaction with application via UI for example configuration 2)- Method that are required to work against different commands to perform payment actions.

So UI methods will be called by application when some one try to configure it via merchant where it prompts merchant to add/edit required data about gateway for example gateway request URL etc.

When someone places order and try to process the payment AbleCommerce looks for associated payment gateway for customer picked payment method. Then ablecommerce creates an instance of correct gateway and determine what transaction it supports. Then if merchant is set the gateway to Authorize and Capture mode it will first call DoAuthorize method and then DoCapture.

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Fri Jan 29, 2010 8:06 am

Hi mazhar, thank you for the reply. So in the doauthorize and docapture methods is it performing two seperate calls to the gateway? Or if authorize and capture is enabled is it merely building he authorization part of the direct post, then passing it along to the docapture method?

Also on the recurring billing, is the DoAuthorizeRecurring called automatically on subscription items when recurring billing is enabled for a gateway?

Thanks for all of your help.

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Tue Feb 02, 2010 11:53 am

anyone on the recurring billing question?

User avatar
mazhar
Master Yoda
Master Yoda
Posts: 5084
Joined: Wed Jul 09, 2008 8:21 am
Contact:

Re: Straight Capture (Do we need doauthorize?)

Post by mazhar » Tue Feb 02, 2010 12:28 pm

Both are separate calls made by ablecommerce depending upon the mode of gateway. Some merchants only want to authorize payments and want to capture manually. In this case only authorize will be called. But if you set you gateway mode to Authorize & Capture then it will first call authorize and then it will capture the authorized amount.

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Tue Feb 02, 2010 1:53 pm

so if i get what you're saying, it does not run the doauthorizereccuring method on subscription items automatically. That would have to be done within docapture?

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Tue Feb 09, 2010 9:56 pm

Okay, so I have my custom gateway implemented and I'm trying to do a test purchase on a subscription item... I've adjusted doauthorize and docapture to use this information. Nothing is happening, transactions are not pending. I put some debugging that writes to a text file at the beginning of docapture and doauthorize. The debugging code never fires, so doauthorize and docapture are never getting called. I put debugging code in the "initialize" event and it is getting called.

I suspect it has to do with subscription items (which I asked about above twice with no answer) and I hope I can get a helpful reply.

On check out I noticed this message on the receipt page

Order #28 has a balance due but it includes one or more subscription payments. Please contact us in order to complete your order.

Is this why authorize/capture is not happening? Can someone please help me out with this. I am literally days away from purchasing ablecommerce for our solution if I can get this working as advertised. Thanks in advance.

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Tue Feb 09, 2010 10:02 pm

Okay, I just did a test with a non-subscription item and it worked like a charm... Now I'm convinced that it's the subscription items. Can someone please give me some help with how the gateway implementation handles subscriptions? Thanks!

User avatar
Logan Rhodehamel
Developer
Developer
Posts: 4116
Joined: Wed Dec 10, 2003 5:26 pm

Re: Straight Capture (Do we need doauthorize?)

Post by Logan Rhodehamel » Wed Feb 10, 2010 12:04 pm

Hello mezojeff-

I am familiar with Braintree although I haven't worked with it in a while. From this thread I assume your goal is to implement a recurring charge system through this gateway?

One thing to understand about our subscription / recurring billing implementation is that the gateways we support all have a similar approach. We tell the gateway up front about the payment schedule, how much is the first payment, how much are repeat payments, how often do payments get made, etc. Once we pass this information to the gateway, the gateway handles all of the recurring billing events.

Braintree is a little different. You request a payment and get a token. You can subsequently charge a customer with this token. In this scenario, it's the client software that has responsibility for initiating future events.

You could make this work, but you need to build in some way of identifying future events and then requesting the payments. You would not need to use the recurring billing portions of the gateway - instead you'd be working with the plain DoAuthorize / DoCapture methods. Subsequent capures wuld be made using the token rather than the credit card info.

Am I in the right direction or is my memory of Braintree too faded?
Cheers,
Logan
Image.com

If I do not respond to an unsolicited private message, it's not because I'm ignoring you. It's because the answer to your question is valuable to others. Try the new topic button.

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Wed Feb 10, 2010 12:16 pm

your memory is fine on braintree. As I posted above I can get it to do a authorize and capture fine on regular products. However those methods get fired when buying subscription product. That's where my problem now lies.

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Wed Feb 10, 2010 12:20 pm

this is from the gateway debug, the top is an attempt to purchase a subscription item, the bottom two is just buying a normal non-subscription product.

Send: <?xml version="1.0" encoding="utf-8"?><ARBCreateSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"><merchantAuthentication><name>demoapi</name><transactionKey>password1</transactionKey></merchantAuthentication><subscription><name>MezoVault Basic - Monthly</name><paymentSchedule><interval><length>1</length><unit>months</unit></interval><startDate>2010-02-09</startDate><totalOccurrences>32767</totalOccurrences></paymentSchedule><amount>9.99</amount><payment><creditCard><cardNumber>xxxxxxxxxxxx1111</cardNumber><expirationDate>2010-10</expirationDate></creditCard></payment><order><invoiceNumber>28:27</invoiceNumber><description>Order #28, Sub #27</description></order><customer><type>individual</type><id>1</id><email>jeff@mezolink.com</email><phoneNumber>2175555555</phoneNumber></customer><billTo><firstName>Jeff</firstName><lastName>Turner</lastName><company>Mezolink</company><address>400 Neil</address><city>Champaign</city><state>IL</state><zip>61820</zip><country>US</country></billTo></subscription></ARBCreateSubscriptionRequest>

Receive: <?xml version="1.0" encoding="utf-8"?><ErrorResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"><messages><resultCode>Error</resultCode><message><code>E00003</code><text>The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:totalOccurrences' element is invalid - The value '32767' is invalid according to its datatype 'Short' - The MaxInclusive constraint failed.</text></message></messages></ErrorResponse>

Send: username=xxxxxxxx&password=xxxxxxxx&firstname=Jeff&lastname=Turner&company=Mezolink&address1=400+Neil&city=Champaign&state=IL&zip=61820&country=US&phone=2175555555&fax=&ipaddress=127.0.0.1&email=&shipping_firstname=DEMO&shipping_lastname=DEMO&shipping_company=&shipping_address1=DEMO&shipping_city=DEMO&shipping_state=DEMO&shipping_zip=DEMO&shipping_country=US&amount=22.74&payment=creditcard&type=auth&ccnumber=xxxxxxxxxxxx1111&ccexp=102010&cvv=xxx

Receive: response=1&responsetext=SUCCESS&authcode=123456&transactionid=1185463424&avsresponse=N&cvvresponse=M&orderid=&type=auth&response_code=100&customer_vault_id=

Send: username=xxxxxxxx&password=xxxxxxxx&firstname=Jeff&lastname=Turner&company=Mezolink&address1=400+Neil&city=Champaign&state=IL&zip=61820&country=US&phone=2175555555&fax=&customer_vault=add_customer&ipaddress=127.0.0.1&email=&shipping_firstname=DEMO&shipping_lastname=DEMO&shipping_company=&shipping_address1=DEMO&shipping_city=DEMO&shipping_state=DEMO&shipping_zip=DEMO&shipping_country=US&amount=43.19&payment=creditcard&type=auth&ccnumber=xxxxxxxxxxxx1111&ccexp=102010&cvv=xxx

Receive: response=1&responsetext=SUCCESS&authcode=123456&transactionid=1185465071&avsresponse=N&cvvresponse=M&orderid=&type=auth&response_code=100&customer_vault_id=1387509031

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Wed Feb 10, 2010 6:30 pm

after further experimentation I see that ablecommerce automatically goes straight to the DoAuthorizeRecurring method when purchasing a subscription item... So, I will most likely need to run the doauthorize and docapture events inside of that method, then append the extra code to setup a recurring billing... So it would look something like this.

DoAuthorizeRecurring()
{
DoAuthorize()
DoCapture()
SetupRecurringBilling()
return transaction?
}

Does this look like it will work?

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Thu Feb 11, 2010 9:56 am

I've played with this for a little while longer this morning. I have a question, I've deduced that the DoAuthorizeRecurring gets called first for subscription items. I've also realized that I do not need to run the doauthorize and docapture inside of that method. Does anything get called upon success of the DoAuthorizeRecurring? In other words if you have Authorize and Capture enabled, will it run the DoCapture method after DoAuthorizeRecurring?

Thanks,

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Fri Feb 12, 2010 8:27 am

Still at the same spot as yesterday. I'll break down my inquiry into simpler terms.

On subscription items, with recurring billing set as an option on the gateway, what methods are fired when AuthorizeAndCapture are set to true.

I know that DoAuthorizeRecurring is called first, where I'm stuck is do I do the code for the authorize and the capture within that method, or is the DoCapture method called after a successful authorization inside of the DoAuthorizeRecurring method.

Thank you

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Fri Feb 12, 2010 11:08 am

Okay, finally figured this out (on my own). and I'm posting it here for the benefit of future users.

If you have recurring billing set as a supported transaction for your gateway, when a person purchases a subscription item it does all of the work inside of this method.

DoAuthorizeRecurring

It does not touch DoAuthorize or DoCapture during this process, those are used for non-subscription transactions. So what you will need to do inside of DoAuthorizeRecurring is this.

Create your payment,order,and user objects from the AuthorizeRecurringTransactionRequest

Build your gatewayrequest

Send Request to Gateway

Parse the response into a transaction object

return the transaction object

Inside of my gatewayrequest I put all of the code to both setup the recurring billing, and do an initial capture for the monthly rate.

User avatar
sohaib
Developer
Developer
Posts: 1079
Joined: Fri Jan 23, 2004 1:38 am

Re: Straight Capture (Do we need doauthorize?)

Post by sohaib » Fri Feb 12, 2010 11:17 am

Implementation of payment gateways has been discussed at http://wiki.ablecommerce.com/index.php/ ... nt_Gateway. The source of the Authorize.net gateway implementation is also available for reference. ftp://ftp.ablecommerce.com/evals/AuthorizeNet.zip
You can have a look at it to see how recurring payments are handled.

Here is the relevant code from Authorize.Net implementation

Code: Select all

        public override AuthorizeRecurringTransactionResponse DoAuthorizeRecurring(AuthorizeRecurringTransactionRequest authorizeRequest)
        {
            //ACCESS REQUIRED DATA FOR BUILDING REQUEST
            Payment payment = authorizeRequest.Payment;
            if (payment == null) throw new ArgumentNullException("request.Payment");
            Order order = payment.Order;
            if (order == null) throw new ArgumentNullException("request.Payment.Order");
            Transaction errTrans;
            //KEEP TRACK OF SENSITIVE DATA THAT SHOULD NOT BE RECORDED
            Dictionary<string, string> debugReplacements = new Dictionary<string, string>();
            //GENERATE REQUEST
            XmlDocument arbRequest = new XmlDocument();
            arbRequest.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><ARBCreateSubscriptionRequest />");
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "merchantAuthentication/name", this.MerchantLogin);
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "merchantAuthentication/transactionKey", this.TransactionKey);
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/name", authorizeRequest.SubscriptionName);
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/paymentSchedule/interval/length", authorizeRequest.PaymentFrequency.ToString());
            switch (authorizeRequest.PaymentFrequencyUnit)
            {
                case PaymentFrequencyUnit.Day:
                    XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/paymentSchedule/interval/unit", "days");
                    break;
                case PaymentFrequencyUnit.Month:
                    XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/paymentSchedule/interval/unit", "months");
                    break;
                default:
                    errTrans = Transaction.CreateErrorTransaction(this.PaymentGatewayId, authorizeRequest, "U", "Unsupported payment frequency unit: " + authorizeRequest.PaymentFrequencyUnit.ToString());
                    return new AuthorizeRecurringTransactionResponse(errTrans);                    
                    
            }
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/paymentSchedule/startDate", LocaleHelper.LocalNow.ToString("yyyy-MM-dd"));
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/paymentSchedule/totalOccurrences", authorizeRequest.NumberOfPayments.ToString());
            //DETERMINE IF THERE IS A DIFFERENT INITIAL AND RECURRING AMOUNT
            if (authorizeRequest.RecurringChargeSpecified)
            {
                XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/paymentSchedule/trialOccurrences", "1");
                XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/amount", authorizeRequest.RecurringCharge.ToString("F2"));
                XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/trialAmount", authorizeRequest.Amount.ToString("F2"));
            }
            else
            {
                XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/amount", authorizeRequest.Amount.ToString("F2"));
            }
            //DETERMINE METHOD AND TYPE
            AccountDataDictionary accountData = new AccountDataDictionary(payment.AccountData);
            PaymentInstrument instrument = payment.PaymentMethod.PaymentInstrument;
            switch (instrument)
            {
                case PaymentInstrument.AmericanExpress:
                case PaymentInstrument.Discover:
                case PaymentInstrument.MasterCard:
                case PaymentInstrument.Visa:
                    string accountNumber = accountData.GetValue("AccountNumber");
                    XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/payment/creditCard/cardNumber", accountNumber);
                    if (this.UseDebugMode) debugReplacements.Add(accountNumber, MakeReferenceNumber(accountNumber));
                    string expirationMonth = accountData.GetValue("ExpirationMonth");
                    if (expirationMonth.Length == 1) expirationMonth.Insert(0, "0");
                    string expirationYear = accountData.GetValue("ExpirationYear");
                    if (expirationYear.Length == 2) expirationYear = "20" + expirationYear;
                    XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/payment/creditCard/expirationDate", expirationYear + "-" + expirationMonth);
                    break;
                case PaymentInstrument.Check:
                    errTrans =  Transaction.CreateErrorTransaction(this.PaymentGatewayId, authorizeRequest, "E", "Check is not yet implemented!");
                    return new AuthorizeRecurringTransactionResponse(errTrans);
                
                default:
                    errTrans = Transaction.CreateErrorTransaction(this.PaymentGatewayId, authorizeRequest, "E", "The requested payment instrument is not supported: " + instrument.ToString());
                    return new AuthorizeRecurringTransactionResponse(errTrans);
            }

            //COMBINE ORDER AND PAYMENT ID TO PREVENT DUPLICATE ERRORS
            //WHEN MORE THAN ONE SUBSCRIPTION EXISTS FOR A SINGLE ORDER
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/order/invoiceNumber", string.Format("{0}:{1}", order.OrderNumber, payment.SubscriptionId));
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/order/description", string.Format("Order #{0}, Sub #{1}", order.OrderNumber, payment.SubscriptionId));

            //CUSTOMER TYPE SHOULD BE 'I' FOR INDIVIDUAL OR 'B' FOR BUSINESS
            string customerType = accountData.GetValue("CustomerType");
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/customer/type", ((customerType == "B") ? "business" : "individual"));
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/customer/id", order.UserId.ToString());
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/customer/email", order.BillToEmail);
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/customer/phoneNumber", order.BillToPhone);
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/customer/faxNumber", order.BillToFax, true, false);
            //look for drivers license data
            if (accountData.ContainsKey("LicenseNumber") && accountData.ContainsKey("LicenseState") && accountData.ContainsKey("BirthDate"))
            {
                string licenseNumber = HttpUtility.UrlEncode(accountData.GetValue("LicenseNumber"));
                string licenseState = HttpUtility.UrlEncode(accountData.GetValue("LicenseState"));
                DateTime birthDate = DateTime.Parse(accountData.GetValue("BirthDate"));
                XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/customer/driversLicense/number", licenseNumber);
                XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/customer/driversLicense/state", licenseState);
                XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/customer/driversLicense/dateOfBirth", birthDate.ToString("yyyy-MM-dd"));
                if (this.UseDebugMode)
                {
                    //need to replace license number with truncated version
                    debugReplacements.Add(licenseNumber, MakeReferenceNumber(licenseNumber));
                }
            }
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/billTo/firstName", StringHelper.Truncate(order.BillToFirstName, 50));
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/billTo/lastName", StringHelper.Truncate(order.BillToLastName, 50));
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/billTo/company", StringHelper.Truncate(order.BillToCompany, 50));
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/billTo/address", StringHelper.Truncate(order.BillToAddress1, 60));
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/billTo/city", StringHelper.Truncate(order.BillToCity, 40));
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/billTo/state", StringHelper.Truncate(order.BillToProvince, 40));
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/billTo/zip", StringHelper.Truncate(order.BillToPostalCode, 20));
            XmlUtility.SetElementValue(arbRequest.DocumentElement, "subscription/billTo/country", order.BillToCountryCode);
            string requestDocument = arbRequest.OuterXml;
            //INSERT THE NAMESPACE FOR THE DOCUMENT ELEMENT
            requestDocument = requestDocument.Replace("<ARBCreateSubscriptionRequest", "<ARBCreateSubscriptionRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\"");
            //RECORD REQUEST
            if (this.UseDebugMode)
            {
                //ALWAYS MASK THE CREDENTIALS
                string credentials = String.Format("x_login={0}&x_tran_key={1}", this.MerchantLogin, this.TransactionKey);
                string debugCredentials = "x_login=xxxxxxxx&x_tran_key=xxxxxxxx";
                debugReplacements[credentials] = debugCredentials;
                this.RecordCommunication(this.Name, CommunicationDirection.Send, requestDocument, debugReplacements);
            }
            //SEND REQUEST
            arbRequest = new XmlDocument();
            arbRequest.LoadXml(requestDocument);
            XmlDocument arbResponse = this.SendXmlRequestToGateway(arbRequest);
            //RECORD RESPONSE
            if (this.UseDebugMode) this.RecordCommunication(this.Name, CommunicationDirection.Receive, arbResponse.OuterXml, null);
            //PROCESS RESPONSE AND RETURN RESULT
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(arbResponse.NameTable);
            nsmgr.AddNamespace("ns1", "AnetApi/xml/v1/schema/AnetApiSchema.xsd");
            string responseCode = XmlUtility.GetElementValue(arbResponse.DocumentElement, "ns1:messages/ns1:message/ns1:code", nsmgr);
            string responseMessage = XmlUtility.GetElementValue(arbResponse.DocumentElement, "ns1:messages/ns1:message/ns1:text", nsmgr);
            if (XmlUtility.GetElementValue(arbResponse.DocumentElement, "ns1:messages/ns1:resultCode", nsmgr).ToLowerInvariant() == "ok")
            {
                //SUCCESS RESPONSE
                Transaction transaction = new Transaction();
                transaction.PaymentGatewayId = this.PaymentGatewayId;
                transaction.TransactionType = TransactionType.AuthorizeRecurring;
                transaction.TransactionStatus = TransactionStatus.Successful;
                transaction.Amount = authorizeRequest.Amount;
                transaction.RemoteIP = authorizeRequest.RemoteIP;
                transaction.ResponseCode = responseCode;
                transaction.ResponseMessage = responseMessage;
                transaction.TransactionDate = LocaleHelper.LocalNow;
                transaction.AuthorizationCode = XmlUtility.GetElementValue(arbResponse.DocumentElement, "ns1:subscriptionId", nsmgr);
                return new AuthorizeRecurringTransactionResponse(transaction);
            }
            //ERROR RESPONSE
            errTrans = Transaction.CreateErrorTransaction(this.PaymentGatewayId, TransactionType.AuthorizeRecurring, authorizeRequest.Amount, responseCode, responseMessage, authorizeRequest.RemoteIP);
            return new AuthorizeRecurringTransactionResponse(errTrans);
        }

mezojeff
Lieutenant, Jr. Grade (LT JG)
Lieutenant, Jr. Grade (LT JG)
Posts: 27
Joined: Fri Jan 08, 2010 7:23 am

Re: Straight Capture (Do we need doauthorize?)

Post by mezojeff » Fri Feb 12, 2010 11:38 am

right... but what isn't discussed in that wiki article is what methods are touched for each type of transaction. Trust me I read through that article about a dozen times while going through the process of setting up this custom gateway for Braintree. It was very helpful, but could have been more so. See below.

If something like this were added into the wiki it could have saved me alot of time.

::Implemented methods on custom gateways based off of authorize.net example::
Authorize - DoAuthorize() is the only method that is implemented
AuthorizeAndCapture - DoAuthorize() and DoCapture() are implemented in that order.
RecurringBilling - DoAuthorizeRecurring() is the only method that is implemented when this is a supported transaction for your gateway.

I definitely appreciate the resources that are out there, and they've been very helpful. I now have a very granular understanding of how the custom gateway is implemented and have ablecommerce doing everything that I need it to do. I feel like I can create a library for pretty much any gateway out there now thanks to going through this process. Thanks for your suggestions.

Post Reply