Using Authorize.NET DPM (Direct Post Method) from ASP.NET Web Forms

While thousands of custom websites with custom checkout procedures process credit cards, relatively few meet PCI compliance standards. Basically, when a credit card number TOUCHES your server, even if you do not store it, your system falls under PCI compliance guidelines which are pretty nasty.  The easiest thing to do is never let a credit card number even pass through your server.  Many folks use Authorize.NET’s SIM method, but it requires the credit card number passing through your server, setting you up for a likely PCI audit failure.  Granted, credit card companies don’t run around auditing small online businesses, but I like doing things right and treating sensitive information with respect.

Authorize.NET DPM seems like a great method.  However, I found the documentation at Authorize.NET confusing, and they do not provide an ASP.NET Web Forms example of DPM. So I extracted one from a recent project I worked on.  Here are a few key points required to get this to work.

  1. ASP.NET doesn’t appear to support posting a form to an alternate address, but actually, it does. Check out Button’s PostBackURL property.  Using this property will allow your app to submit a form directly to Authorize.NET’s server.
  2. The ‘x_relay_url’ that you passed to Authorize.NET to confirm the purchase is called directly from Authorize.NET’s servers to your server to inform your website of purchase success, failure, etc…  It should point to your server and a special page that knows how to deal with the data being posted to it.  Any output from your relay page is piped through the submission URL at Authorize.NET and displayed in the client’s browser.  Basically, the URL the web browser displays is an Authorize.NET URL, but it displays any data from your replay response page.  This means you get no cookies (IE no Session variables) from the client browser.  This page should perform some validation, and  issue very simple HTML/javascript redirect code through your SIM response page. Response.Redirect didn’t work for me.

Check out the following downloadable demo.

This has been tested in Visual Studio 2010 / ASP.NET 4.0.  Your mileage may vary in other environments.  It is written in VB.Net, but should easily convert to C# or your CLR language of choice.

In order for application to compile, please first download Authorize.Net .NET SDKs, click through their EULA, then extract:

  • AuthorizeNet.dll
  • AuthorizeNet.Helpers.dll

And place them in the bin/ directory.  Then edit the Web.config and replace the AUTHORIZE_NET variables with values from your developer account at Lastly, make sure Authorize.NET can reach your relay URL (which should be “http://domain/siteroot/SIM.aspx”).  This may require running your application in IIS (NOT the Visual Studio development server) and poking a hole through your firewall for testing.  See notes in the code for more details, or check the Authorize.NET documentation.

The demo also has error handling and log4net to log any errors to a log.txt file in the site root.

Tagged with: ,
Posted in All, Software Development
38 comments on “Using Authorize.NET DPM (Direct Post Method) from ASP.NET Web Forms
  1. Bill says:

    Thank you! Much better than’s documentation.

  2. David Cooper says:

    Thanks very much. This is a great example. I can’t get it to work on my site, but that’s not your fault. When does a post to my relay page, is responding with a 302 redirect instead of executing the relay page. I have no idea why, but it’s causing my hair to fall out.

    • Bill says:

      Having a similar issue. No idea either. Losing hair too!

    • andrew says:

      Have you attached your debugger to IIS and put a breakpoint in SIM.aspx? Is the breakpoint even hitting on Page_Load? Are 100% sure you can hit your SIM.aspx URL (or your test site in general) from outside of your firewall?

      Also, is the site URL pointing back to https or http link? I recall reading somewhere that may not work with a self-signed certificate on an https site… so for testing, you might need to use http, not https.

    • David Cooper says:

      Well, I’m not sure how I would be able to debug the relay page. Running the site in the debugger (in Visual Studio 2010) attaches only to localhost. So, I couldn’t find a way to let the external request from get to the debugging session. However, perhaps using IIS for the debugging session (rather than VS2010′s debugging web server) would allow me to do that. I didn’t get that far.

      My first thoughts were to explicitly turn off the automatic form validation and authorization features so that it wouldn’t try to redirect me back to a login page. That didn’t help, but they probably weren’t turned on in the first place.

      I did end up getting past the problem for now. The x_relay_url was being specified with https. It’s not a self-assigned certificate but a genuine Thawte certificate. However, the problem did go away when switching the relay URL to http instead. It’s unlcear to me as to why. However, this will get me moving along for the moment. I can revisit it later if needed. I’m thinking it must actually be something with my site. My site is what’s giving the redirect back, which I found via the server logs. So, I don’t think it actually has anything to do with https other than how my site might be processing it.

      At any rate, none of this is probably generally applicable, but I thought I’d mention it “just in case”.

      Thanks again for this example. I owe you at least a beer. If you’re ever in Seattle and want to collect on that, let me know!

  3. josh says:

    I am so hoping this works for my project… I’m at wits end because I know this is not rocket science, nowhere all this MVC stuff is killing me. why on earth has built the bulk of their class libraries on the MVC framework?

  4. Steve Fink says:

    THANK YOU for creating this in good ol’ tried-and-true web forms! I worked for too long on the MVC mess, finally got the OOB functionality, but taking it any further was a nightmare.

    As for your nice creation, I did get everything in place and compiling properly, easily etc. However, once submitted the page returns to my Error.aspx page with the following message:

    Error Occurred

    Error: Validation failed:(TESTMODE) This transaction has been approved., ResponseCode:1

    This error has been recorded. We have been notified automatically.

    Your credit card transaction was approved. We will examine the cause of the error immediately, and ensure that your purchase is honored or refunded. We apologize for any inconvenience. If you have any questions, please contact us at XXX.

    PurchaseID (if applicable): n/a

    Here is the URL:

    I checke my Authorize.Net test account, and there is no record of any transactions today.

    I believe I have set everything according to your instructions. I do not have, and never have had, an MD5 hash. With my MVC test site, I never needed one either. Is this necessary for the test environment? This is the only deficiency I can identify.

    Thanks again Andrew.

    • andrew says:

      It’s obviously failing on the sr.Validate() call in SIM.aspx.vb. That call helps validate that the response is from and not someone else. To be honest, I’m no expert, but this seems like an important step. So… an MD5 hash would be a good idea in my humble opinion.


      • Steve Fink says:

        I went into my test account settings, generated the hash, applied it to my web.config, and still the same results. Could there be any validation issues in the hidden input type fields (first name, last name, etc.)?

        • andrew says:

          I doubt any of the fields would cause what you are seeing. Please check the code and make sure the hash is being passed into the Authorize.NET API correctly. If you still run into problems, you might have to contact Authorize.NET to help you troubleshoot the issue. I’d also search their forums. Note that the SIM API operates very similarly when it comes to validating results, so there should be lots of help out there on this topic.

          Best of luck.

    • Wendi says:

      i am experiencing the same result and hoping you have found a solution.

      Error Occurred

      Error: Validation failed:(TESTMODE) This transaction has been approved., ResponseCode:1

      This error has been recorded. We have been notified automatically.

      Your credit card transaction was approved. We will examine the cause of the error immediately, and ensure that your purchase is honored or refunded. We apologize for any inconvenience. If you have any questions, please contact us at XXX.

      PurchaseID (if applicable): n/a

      • Tito says:

        Hi Wendi,
        I have the same issue that you are/were having; exact same error message, and I was wondering if you ever get a way around it. I have not implemented hash on the web.config.

        could you please give me a hint on this if you found a solution??


    • Tito says:

      Hi Steve,
      I am getting the same issue with the test account. The exact same message. Were you able to find a way around this issue??? is the MD5 hash setting required on the webconfig??

      If you found a solution, or have hints, could you please provide some guidance???


      • Tito says:

        Hi Steve,
        After adding MD5 has configuration to both the web.config and testing interface, I am not longer receiving the error message, and I am being forwarded to the Thanks.aspx page, which I think it is the expected result if no errors occur on sim.aspx. This means that th sr.validation was failing because i had not configured the MD5 in either place. so, this is a required configuration to make it work.

        Now, on another topic: I noticed that my transactions are not getting reflected on sandbox or testing account at

        Do you have an idea why this may be happening???

        Please, help.


        • andrew says:


          First, thanks for posting your MD5 solution. I suggested as much to folks having the problem, but no one bothered to post a response back.

          It’s been a while since I’ve looked at this, but if you are using the test URL, and you have x_test_request=”FALSE”, I think you’ll see it go through into the test interface. Good luck!

          – Andrew

  5. Steve Fink says:

    Another question regarding the web.config line:
    <!– IE should hit Confirm.aspx –>

    Adding “…/Confirm.aspx” to the value of my main URL fails because it would cause other redirects to go to ie: “”. So am I to assume I should set my home page of in IIS to ?

    • andrew says:

      Hi Steve…

      It’s possible I have a small bug in there. Please examine the code and modify it to your needs. What I provided is simply an example on how to get DPM working.

      - Andrew

  6. James says:

    Hi Andrew,

    Excellent post! New to Authorize.Net and your documentation for ASP.Net is far superior. What’s your take on using .Net controls/Validation controls. In an effort to not have anything postback, do I have to resort to JavaScript to check simple things like a zip code being numeric? Your example seems to capture all the “general” fields ahead of the CC fields. Is that the best approach so sensitive data doesn’t go anywhere but the servers?


    • andrew says:

      Yes… that’s exactly why I did it. I prefer to capture as much of the general information before it goes to the server. It also allows me to use as many .NET validation controls as I want on the other pages. If I have a postback to work with, I also be assured that any server side validation will also be processed. I also can record the customer details in a database, and then fill in the authorization numbers when I get the postback from Authorize.NET. Lastly, it’s a pretty typical part of the checkout process to have a final verification page where you enter the CC number.

      You probably can get away with using ASP.NET validation controls, but I personally wouldn’t do it since I don’t 100% for sure know the behavior of the validation control, and can’t guarantee it WON’T post back (with possible CC number in tow!)… If you go this route, I would test thoroughly in as many browsers as possible to ensure the built-in ASP.NET client-side validation scripts are sufficient, actually work, and most importantly, DO NOT post back for any reason. It’s risky. It would be safer to use jquery / javascript validations that never post back.

      Best of luck,

  7. Ben says:

    Thanks for taking the stupid out of DPM with your excellent example. I had a question now that this post is more than a year old. On page 31 of the DPM guide, there is a sentence that states “Redirects or frames in the relay script are not recommended because the information might not be transferred properly.”

    Have you had any any problems redirecting from sim.aspx to your various pages? In your comments on sim.aspx.vb it appears that you are saving to your db prior to redirect, so I assume you have been fine.

    • andrew says:

      Well, note that I don’t use Response.Redirect. I call my own Sub, EndWithRedirect, which pushes out some simple javascript to redirect the client browser then ending the response stream before the page even renders. I’ve had no problems with this technique, but I’d be sure to test thoroughly regardless.

      I imagine calling Response.Redirect wouldn’t work because it redirects through HTTP protocol, not HTML… something that Authorize.Net isn’t going to be able to deal with. However, javascript works fine, and I’d bet a <meta http-equiv=”refresh”> in the header would probably do the trick as well. (

  8. Rob says:


    Thanks for this awesome post! It got me up and running in no time and the checkout process is now tightly integrated with my site and works great. There is only one thing that is confusing me in the sample project you posted.

    In SIM.aspx, after you have verified that everything went fine, you pull the sr.InvoiceNumber from the SIMResponse and store it in a variable. You then have some code which is commented out which says to ‘Make sure the purchase ID is valid…. if not….’ and then you use some undefined object drPurchase to presumably determine if the purchase ID was valid or not. Can you tell me what this is all about?

    Thanks again. If you have PayPal, send me an email and I’ll donate a few bucks for your efforts.

    • andrew says:

      Hi Rob…

      sorry for the delayed response. (I was setting up a new server and didn’t get email notifications about these comments… resolved now thankfully!)

      That commented out code is basically saying “verify that nPurchaseID exists in the database.” Stepping back for a sec… the way I use SIM is to gather as many purchase details as possible from the user before presenting them the page that collects credit card details and posts to Authorize.NET. I store those details in a database, and nPurchaseID is the ID of the record in the database. When the response comes back from Authorize.NET to the SIM page, that commented code (and other code that I removed for clarity) performs additional verification on the response to ensure that the nPurchaseID exists in the database, and that, say, the amount from Authorize.NET matches what the Purchase record expects. If something goes wrong, the system would send me an email, requiring further examination of the situation. If all checks out, the code might then write additional details to the purchase record in the database to indicate that the purchase was successful.


  9. hima says:

    Hi andrew, this is a wonderful piece of code and I am glad I found this at the right time. I completely rely on your demo code now. All is well so far, when I hit ‘Complete the purchase’ the postbackurl is hit but no sign of SIM.aspx being called though x_relay_url is rightly set. What am I missing?

    • andrew says:

      I don’t know enough about your environment to really help here. SIM.aspx must be reachable from the servers (IE the public internet)… from the original post:

      “…make sure Authorize.NET can reach your relay URL (which should be “http://domain/siteroot/SIM.aspx”). This may require running your application in IIS (NOT the Visual Studio development server) and poking a hole through your firewall for testing.”

      Hope this helps.

  10. RC says:

    I was curious – isn’t x_login exposed here obviously to the client side? Are there ways to not do that? Thanks!

  11. Bruce says:

    Since the card number is a property of the SIMResponse, doesn’t that mean that the card number does touch your web site at the point the payment gateway posts to the sim.aspx page?

  12. Simon says:

    Hi Andrew,

    It is my duty to acknowledge. Your sample code (not code samples at helped me move ahead. So happy that found your article. Followed your code and successfully placed tests. Thanks you very much.

    At this moment I am trying to save in the database the response details. Added the following code

    Dim r_reason_text As String = sr.Message.ToString
    Dim r_code As String = sr.ResponseCode.ToString
    Dim r_reason_code As Integer = Integer.Parse(Request(“x_response_reason_code”))
    Dim trans_id As String = sr.TransactionID.ToString
    Dim auth_code As String = sr.AuthorizationCode.ToString
    Dim amount As Decimal = Decimal.Parse(sr.Amount)
    Dim account_number As String = sr.CardNumber.ToString
    Dim x_type As String = Request(“x_type”).ToString
    Dim card_type As String = Request(“x_card_type”).ToString
    Dim OrderID As Integer = AddOrderReturnOrderID(CustEmail, x_type, r_code, r_reason_code, r_reason_text, auth_code, trans_id, nPurchaseID, amount, account_number, card_type)

    The function AddOrderReturnOrderID was tested on localhost and is fine. But the code above produces he following message
    “Error Occurred
    Error: Fatal error. This error has been logged and you will be contacted shortly.
    This error has been recorded. We have been notified automatically.
    Your credit card transaction was approved. We will examine the cause of the error immediately, and ensure that your purchase is honored or refunded. We apologize for any inconvenience. If you have any questions, please contact us at XXX.
    PurchaseID (if applicable): n/a”.

    Please, If by the chance you will see my this. Do you see any problem in code lines above?



    • andrew says:

      You’ve passed along the user facing error information. The error presented to the user is not intended to help you debug your program. I would review the error handling source code and rewrite it to meet your needs. Good luck…

  13. Simon says:


    Your quick response is much appreciated. Searched and found the help from

    as was suggested by RaynorC1emen7 (with correction by juantoro ) used another expression for definition of the variable account_number (4 last digits). I used

    Dim account_number as string = Request.Form.Get(“x_account_number”)

    It was enough (all other variables worked as are). Able to read and save in database.

    Almost done. Now working on Thanks.aspx page.


    Have a good day,



  14. Sam says:


    Please advice what it could be. In your code values of Card Number and Expiration code are hard code within code behind. For example
    Public ReadOnly Property CardNumber() As String
    If strAuthorizeNet_x_test_request.Equals(“TRUE”) Then
    Return “4111111111111111″
    End If
    Return “”
    End Get
    End Property

    I am trying to read those values from form controls like

    Public ReadOnly Property CardNumber() As String
    Return cardNumberBox.Text.ToString
    End Get
    End Property

    For some reason the value I typed is not submitted. Getting Transaction denied. Response code3.



    • Sam says:

      Hi Andrew,

      Hours ago I submit the post seeking your help. Just want to inform that I managed to fix the “bug”. Now everthing is OK.

      Thank you very much for this article.


      • andrew says:

        Glad to hear you fixed the problem. Please note that you should never allow credit card numbers to post back to your site for PCI compliance reasons. This is actually why Authorize.NET DPM exists. The reason you couldn’t see it is because of the PostBackURL property on the button:

        Hope this helps explain things.


        • Sam says:

          Andrew – Thank you very much for reply.

          Actually I was able to solve the problem only when one more time looked at your code in the downloaded sample. All form fields for posting to MUST be HTML controls but not ASP.NET server controls. By mistake for Card number and Expiration Date in my code were used ASP.NET server controls. As soon as I found out this the problem was fixed.

          It is true that fix came after long battle. Programming some times looks like boxing!

          Thanks again!


Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>