Thursday, June 7, 2012

Paypal IPN and PDT in ASP.net

To support a customer who needs to process payments through Paypal, I created a small code package that encapsulates the functionality necessary for the operations used in Paypal's Payment Data Transfer (PDT) and Instant Payment Notification (IPN). This way, the code is reusable for future projects within Rubicite. I'm sharing it on Github, so that it can save some time for the rest of the world: https://github.com/jgb146/Paypal-util

Most of the functionality involved is derived from various tutorials in Paypal's documentation, but this way everything is encapsulated into a single pdt_hander object, or a single ipn_handler object (depending on which technology you're using). The resulting object automatically takes the steps required for confirming the contents with Paypal, and then provides you with access to your payment information through a Dictionary.

To use either component, simply instantiate the object and provide the required information. For PDT, that means including the transaction ID that Paypal sent, your PDT ID token, and an optional boolean to indicate whether or not you are using Paypal's sandbox. For IPN, the only parameter to include is an optional boolean to indicate whether or not you are using Paypal's sandbox. Use looks roughly like this:

IPN:
protected void Page_Load(object sender, EventArgs e)
{
    processIpnPost();
            
    Response.Clear();
    Response.StatusCode = 200;
    Response.Write("");
    Context.ApplicationInstance.CompleteRequest();
}

public void processIpnPost()
{//process the IPN post
    
    //use ipn_handler util to get response and load into a dictionary
    PayPalUtil.ipn_handler ipn_handler = new PayPalUtil.ipn_handler();
    Dictionary dic_ipnResponse = ipn_handler.dic_data;
    
    //deal with invalid responses
    if (dic_ipnResponse["response"] != "VERIFIED")
        return;

    //---Insert code to use dic_ipnResponse to process the transaction
}

PDT:
protected void Page_Load(object sender, EventArgs e)
{
    ProcessTransaction();
}

protected void ProcessTransaction()
{
    //deal with unspecified transactions
    if ((Request["tx"] == null) || (Request["tx"] == ""))
    { 
        InvalidTransaction();
        return; //stop processing; 
    }
                
    //use the transactionID in the GET to request & process PDT data
    my_pdt_handler = new PayPalUtil.pdt_handler(Request["tx"], PDT_ID_Token);

    //deal with invalid responses
    if (my_pdt_handler.dic_data["response"] != "VERIFIED")
    { 
        InvalidTransaction(Request["tx"], my_pdt_handler.dic_data);
        return; //stop processing; 
    }

    //---Insert code to use my_pdt_handler.dic_data to process the transaction           
}

protected void InvalidTransaction(String pStr_transactionID = "", Dictionary pDic_data = null)
{//invalid transaction -> handle however you feel is best

}

Tuesday, June 5, 2012

New Directions & New Digs

Things at Rubicite have been a bit tumultuous of late. One of our partners (we'll call him X) decided to leave the company. X and our CEO are brothers, and family drama entered into work on more than one occasion - something for which they were both at fault. In the end, X chose to leave because the stressful conditions that this created weren't worth it in his eyes. All parties were happy and pleasant about the break; we took X out to lunch at his favorite restaurant (a tradition I enjoyed at NSA, and one I intend to continue here with Rubicite).

A few things will be happening as a result of this. First, Rubicite is buying X's shares. That's creating some difficulty because X held around 35% of the company and a large chunk of our financial assets are in a set of invoices that haven't yet been paid. In the end, he's going to have to wait a few weeks for the final payout. And we're going to be strapped for cash for a few weeks until some invoices get paid.

Second, the remaining partners all have more ownership of Rubicite now. X's shares are being split proportionally to our previous distribution, which takes me from 15% to around 23%.

Third, I get X's office. That was going to happen anyway, since X worked from home a lot. But the timing worked out pretty well, since I just got my new desk delivered and it was going to make my old office pretty crammed. The new office is bigger than my old one (around 14 x 11 instead of 11 x 10), and it has two windows. In the new office, the desk fits comfortably, with room for a nice seating area should I need it.

Fourth, Rubicite's finances should improve more quickly. For at least the last six months, X has been working on internal projects that did not make us money right now. Among other things, those projects included coding for our first computer game, and improvements to Grinderschool. Both were valued contributions, but having a large portion of our work-force not on paying work led to slower growth than we might have seen otherwise. Instead, we will now see slower improvements to Grinderschool and the game will likely take a bit longer to get to the point of seeking funding, BUT we should be making money significantly more quickly than we are spending it - meaning salary increases should be a bit less distant on the horizon.

Finally, the rest of us will have to adjust our work in order to keep moving forward on the projects X was working on. We want to do so in a way that will lead to minimal drain on our billable time. That will probably mean some extra hours for each of us here and there, and it will also probably mean that X's projects slow down a bit. I'm becoming a bit excited at the prospect of getting my hands into the mix for our first game - previously I had envisioned myself as being more-or-less only in the web development side of Rubicite.

We are having a company meeting later this week to look at finances and develop the future work-plan for Rubicite. More will certainly be decided then.