0 Comments

If you have data in a form in an ASP.NET page that you want to post to another web site, this can be problematic.  ASP.NET is designed so that only one form (with runat="server" attribute) is allowed on a page, and when you do something like click on a button, the page will post back to itself, so that the data in the form can be processed.

But say you have a simple ecommerce site and want to post the data in the form to a payment provider (eg PayPal, DataTrans or Secure Trading) to request a payment, how can you do that?

Using the PostBackUrl Property

Fortunately ASP.NET buttons have a property called "postbackurl":

<asp:button id="payNowButton" runat="server"
  text="Pay Now"
  postbackurl="https://securetrading.net/authorize/form.cgi" >
</asp:button>
You simply set this to the external page you want to post too, and all the data in the form will be redirected there, when the button is clicked on.

Creating the Form data

The form data to be posted has to be contained in <input> fields, visible or hidden.  The name of each field has to match the parameter name that the payment provider specifies.

One technique I like for preparing the parameters to be sent to the payment provider is to populate a generic IDictionary<string, string> with the names & values of the parameters to be sent (eg currency, your account identifier, order id, price etc).  Then in the page, I make this Dictionary the datasource for a repeater which creates a separate hidden <input> field for each parameter:

paymentParametersRepeater.DataSource 
  = SecureTradingPaymentProvider.GetPaymentParameters(order); 
paymentParametersRepeater.DataBind();

<asp:Repeater ID="paymentParametersRepeater" runat="server" 
  EnableViewState="False">
  <ItemTemplate>
    <input id="Hidden1" type="hidden"
      name='<%# Eval("key") %>'
     value='<%# Eval("value") %>' />
  </ItemTemplate>
</asp:Repeater>

In this example I've put the code that populates the Dictionary into a separate payment provider class (not shown here), so all code that is unique to the particular payment company is kept in one place.

Sending data in the QueryString

Many payment providers also allow you to send the payment parameters in the QueryString, using a GET request:

http://www.paymentprovidersurl/?amount=125&id=myIdCode&currency=GBP
This may be simpler to construct, but leaves the important variables temptingly visible for someone to edit (perhaps to reduce the price).  For that reason I favour posting the data cross-site so at least more casual hacking is deterred.

Other Approaches

If the data to be posted cannot be added to the page, it is possible to create an HttpWebRequest programmatically, POST  the data to an external site, then stream the response received back to your user's browser.

I found this blog entry describing how to tackle the problem this way:

Hope this is useful.