Announcement

Collapse
No announcement yet.

NetIDMe Integration

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    NetIDMe Integration

    Hi,

    We are trying to Integrate the NetIdMe Age Verification service into our Actinic store and have seen the post: -

    http://community.actinic.com/showthread.php?t=42689

    We would like to break out of the Actinic checkout process after payment with Sage but before the receipt page in Actinic.

    We have tried a couple of suggestions from support neither of which have worked.

    We have the integration with NetIdMe working but can’t figure out how we break out of the Actinic process at the correct place.

    Can anyone shed any light on this for us?

    Alternatively could someone recommend a developer/company that actually understands the Actinic checkout scripts? We have now approached two Plugin developers neither of which has been able to help.

    Regards
    William

    #2
    If it's after the payment stage then it looks to me as if you'll either need to:

    a) intercept the receipt page with the netidme code and then continue what was happening afterwards

    b) Put some code on the receipt page to launch the netidme code (possibly in a new window which could then be closed to reveal the receipt page on completion).

    c) Put some clear text on the receipt page that says "You must verify your age before we can ship your order. Please click here to proceed."

    The last 2 sound fairly simple and should do what you want.

    The thing to remember is that 'order' has been created on actinic when they hand over to the psp so you cannot subsequently add any information to it. It's fully locked and encrypted at that stage.

    Mike
    -----------------------------------------

    First Tackle - Fly Fishing and Game Angling

    -----------------------------------------

    Comment


      #3
      Mike

      Your absolutely spot on with observation 1, we know that there must be a variable or piece of data that tells Sage where and how to call the receipt page but no one knows what it is or where it resides.

      Armed with this, it should then be a simple task of calling our PHP script instead, doing our age checks before finally calling the receipt page and passing on the data that Sage passed into our script.

      This should not be rocket science but so far: -
      1. NetIDme have provided nothing that indicates what needs to be done in Actinic.
      2. The extremely experienced members of the community have not been able to help.
      3. Actinic basic support doesn’t know and they can provide no documentation of their checkout process. They did however inform me that if I want to know about how all of the scripts interact I would need the “PSP Developer Kit” which sales have kindly offered to sell me at £5,000.{sic}
      4. Actinic Premium support have provided two solutions neither of which has worked.
      5. I have contacted a well known company that has made numerous plug-in for Actinic to try and procure their services on a consultancy basis. Unfortunately they don’t understand the checkout scripts and can’t help.
      6. I have approached two Actinic development companies none of which will touch the Actinic scripts.
      7. I have approached a company currently using the NetIDme service and Actinic they will not respond to my request for the name of the developer they used.
      8. I have had a contract developer look at the issue for ten hours.

      Any suggestions would be greatly received.

      Regards
      William

      Comment


        #4
        OK. From what I can tell, the way you want to do this is to send a different success URL to sagepay so you can intercept the return callback, call NetIDme and then recreate the correct callback.

        Pretty much all the information you need is below. It Looks to me as if you could change the receipt URL by creating a new variable, assigning it the return url you want and then placing the variable in this line in place of $::sCallBackURLUser in the script template (highlighted in red below):

        $sCrypt .= "&InvoiceURL=" . Base64Encode($::sCallBackURLUser) . "&";

        I can see possible problems with doing it this way but don't know enough to be sure or how to get around them. The other ways I mentioned above would be far easier.

        If you really want to do this the person I would suggest contacting is Norman Rouxel at drillpine. No idea if he'll be interested though.

        Mike

        **************************************************

        A normal return url is in the form

        http://www.yourdomain.co.uk/cgi-bin/...2dpage%2ehtml&

        There are two setup files that define the handover to the psp.

        1. Act_OCCPROTXTemplate.html

        This creates the HTML for submission

        !-- Template for PROTX OCC HTML template -->
        </FORM><!-- Terminate the parent template form -->


        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
        <font face="Tahoma">
        <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
        <TR>
        <TD>
        <font color="#006699"><font size="6">_______________________________vsp</font></font>
        </TD>
        </TR>
        <TR>
        <TD>
        <BR>You will now be automatically transferred to the Sage Pay VSP secure server
        to process your credit card details with complete confidence. NETQUOTEDEL:TESTMODE
        <P>
        <BIG>This catalog is currently running in test mode. Your credit card will not be debited.</BIG>
        NETQUOTEDEL:TESTMODE

        <FORM NAME="formOCC" METHOD=POST ACTION="NETQUOTEVAR:OCC_URL">
        NETQUOTEVAR:OCC_VALUES
        <P>
        <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
        <TR><TD ALIGN=RIGHT>
        NETQUOTEDEL:TESTMODE
        <INPUT TYPE=SUBMIT NAME="\&quot;SUBMIT\&quot;" VALUE="Next&gt;">
        NETQUOTEDEL:TESTMODE
        </TD></TR>
        </TABLE>
        </FORM>
        <FORM METHOD=POST ACTION="NETQUOTEVAR:OCC_URL">
        </table>
        </font><!-- Create a bogus form to keep the parent template happy -->
        <!-- End of template for PSP OCC -->
        2. OCCPROTXScriptTemplate.pl

        This defines what data is presented to the PSP.

        #---------------------------------------------------------------
        #
        # OCCPROTXScriptTemplate.pl - code part of OCC script
        #
        # Copyright (c) Actinic Software Ltd 2001 All rights reserved
        #
        # *** Do not change this code unless you know what you are doing ***
        #
        # Written by George Menyhert
        # Adapted for PROTX VPS Version 2.2 by Mat Peck - 27/05/2002
        # Includes simple XOR encryption and Base64 encode functions
        #
        # This script is called by an eval() function and it will already
        # have the following variables set up:
        #
        # Expects: $::sOrderNumber - the alphanumeric order number for this order
        # $::nOrderTotal - the total for this order (stored in based currency format e.g. 1000 = $10.00)
        # %::PriceFormatBlob - the price format data
        # %::InvoiceContact - the customer invoice contact information
        # %::OCCShipData - the customer delivery contact information
        # $::sCallBackURLAuth - the URL of the authorization callback script
        # $::sCallBackURLBack - the URL of the backup script
        # $::sCallBackURLUser - the URL of the receipt script
        # $::sPath - the path to the Catalog directory
        # $::sWebSiteUrl - the Catalog web site URL
        # $::sContentUrl - the content URL
        #
        # Affects: $::eStatus - the status of the transaction:
        # $::FAILURE - Failure
        # $::ACCEPTED - Accepted
        # $::REJECTED - Rejected
        # $::PENDING - Pending
        # $::sErrorMessage - error message if any
        # $::sHTML - the HTML to display
        #
        # $Revision: 22493 $
        #
        #---------------------------------------------------------------

        use strict;

        $::eStatus = $::PENDING; # The OCC plug-in runs in pending mode. This script does not
        # perform the transaction. Rather, it forwards the customer to
        # the OCC site for completion.
        my (%VarTable);

        ######################################################################
        # PROTX VPS Specific constants here
        ######################################################################

        my $sMerchantID = $sADF01;
        my $sPassword = $sADF03;
        my $sConfirmationEMail = $sADF04;

        ######################################################################

        my $sSagePayURL = '';

        if ($bTestMode) {
        # $sSagePayURL = "http://localhost/";
        $sSagePayURL = "https://test.sagepay.com/";
        } else {
        # $sSagePayURL = "http://localhost/";
        $sSagePayURL = "https://live.sagepay.com/";
        }

        ######################################################################


        ## Shared Script, different HTML templates;

        $VarTable{$::VARPREFIX . 'OCC_URL'} = # insert the OCC web site URL into the HTML template
        $sProcessScriptURL;

        #
        # only the Vendor name, Protocol ID and Transaction type are plain text for VPS
        # all other values are passed in the encrypted CRYPT field
        # First add the plain text values
        #

        my $sHiddenValues;
        my $sCrypt;

        $sHiddenValues .= "<INPUT TYPE=HIDDEN NAME=\"VPSProtocol\" VALUE=\"2.22\">\n";
        if (!$bAuthorize) # if in pre-authorize mode, change the TxType to DEFERRED
        {
        $sHiddenValues .= "<INPUT TYPE=HIDDEN NAME=\"TxType\" VALUE=\"DEFERRED\">\n";
        }
        else
        {
        $sHiddenValues .= "<INPUT TYPE=HIDDEN NAME=\"TxType\" VALUE=\"PAYMENT\">\n";
        }
        $sHiddenValues .= "<INPUT TYPE=HIDDEN NAME=\"Vendor\" VALUE=\"$sMerchantID\">\n";

        #
        # build up a string of all other values to encrypt and place in the crypt field
        #

        #
        # VendorTxCode needs a random element to ensure this code has not been used before
        #
        $sCrypt .= "VendorTxCode=". $::sOrderNumber . "-" . int(rand(100000)) . "&";

        #
        # VPS requires decimal places in the amount (not lowest digits, so work them out).
        #

        my $nNumDigits = $::PriceFormatBlob{"ICURRDIGITS"}; # read the currency format values
        my ($nAmount, $nFactor, $sAmount);
        if(defined $nNumDigits) {$nFactor = (10 ** $nNumDigits);} else {$nFactor = 100;}
        $sAmount = sprintf("%d.%02d", $::nOrderTotal / $nFactor, $::nOrderTotal % $nFactor);

        $sCrypt .= "Amount=". $sAmount . "&";
        $sCrypt .= "Currency=". $::PriceFormatBlob{SINTLSYMBOLS} . "&";
        $sCrypt .= "Description=Items from ". $sMerchantID . "&";

        #
        # URLs:
        # Strip them out and URL encode them for inclusion in the completion URL.
        # AUTH - the URL to create the authorization blob
        # BACK - the URL to return to the Catalog checkout process
        # USER - the URL to the receipt script
        #

        $sCrypt .= "SuccessURL=".$sSagePayURL."vps2Form/ActSuccess.asp?ActVendor=" .$sMerchantID. "&ActAmount=" . $::nOrderTotal . "&AuthURL=" . Base64Encode($::sCallBackURLAuth);
        $sCrypt .= "&InvoiceURL=" . Base64Encode($::sCallBackURLUser) . "&";
        $sCrypt .= "FailureURL=".$sSagePayURL."vps2Form/ActFail.asp?ActVendor=" .$sMerchantID. "&RedirectURL=" . Base64Encode($::sCallBackURLBack) . "&";


        #
        # add the invoice address and customer name
        #
        $sCrypt .= "CustomerName=" . $::InvoiceContact{NAME} . "&";
        $sCrypt .= "BillingAddress=" . $::InvoiceContact{NAME} . "\n";
        if (length($::InvoiceContact{JOBTITLE})!=0) { $sCrypt .= $::InvoiceContact{JOBTITLE} . "\n"; }
        if (length($::InvoiceContact{COMPANY})!=0) { $sCrypt .= $::InvoiceContact{COMPANY} . "\n"; }
        if (length($::InvoiceContact{ADDRESS1})!=0) { $sCrypt .= $::InvoiceContact{ADDRESS1} . "\n"; }
        if (length($::InvoiceContact{ADDRESS2})!=0) { $sCrypt .= $::InvoiceContact{ADDRESS2} . "\n"; }
        if (length($::InvoiceContact{ADDRESS3})!=0) { $sCrypt .= $::InvoiceContact{ADDRESS3} . "\n"; }
        if (length($::InvoiceContact{ADDRESS4})!=0) { $sCrypt .= $::InvoiceContact{ADDRESS4} . "\n"; }
        if (length($::InvoiceContact{COUNTRY})!=0) { $sCrypt .= $::InvoiceContact{COUNTRY} . "\n"; }

        #
        # add the invoice post code
        #

        $sCrypt .= "&BillingPostCode=" . substr($::InvoiceContact{POSTALCODE}, 0, 10);

        if (length($::InvoiceContact{PHONE})!=0) { $sCrypt .= "&ContactNumber=" . $::InvoiceContact{PHONE}; }
        if (length($::InvoiceContact{FAX})!=0) { $sCrypt .= "&ContactFax=" . $::InvoiceContact{FAX}; }


        #
        # add the delivery address
        #
        $sCrypt .= "&DeliveryAddress=" . $::OCCShipData{NAME} . "\n";
        if (length($::OCCShipData{JOBTITLE})!=0) { $sCrypt .= $::OCCShipData{JOBTITLE} . "\n"; }
        if (length($::OCCShipData{COMPANY})!=0) { $sCrypt .= $::OCCShipData{COMPANY} . "\n"; }
        if (length($::OCCShipData{ADDRESS1})!=0) { $sCrypt .= $::OCCShipData{ADDRESS1} . "\n"; }
        if (length($::OCCShipData{ADDRESS2})!=0) { $sCrypt .= $::OCCShipData{ADDRESS2} . "\n"; }
        if (length($::OCCShipData{ADDRESS3})!=0) { $sCrypt .= $::OCCShipData{ADDRESS3} . "\n"; }
        if (length($::OCCShipData{ADDRESS4})!=0) { $sCrypt .= $::OCCShipData{ADDRESS4} . "\n"; }
        if (length($::OCCShipData{COUNTRY})!=0) { $sCrypt .= $::OCCShipData{COUNTRY} . "\n"; }
        if (length($::OCCShipData{PHONE})!=0) { $sCrypt .= "Tel: " . $::OCCShipData{PHONE} . "\n"; }
        if (length($::OCCShipData{FAX})!=0) { $sCrypt .= "Fax: " . $::OCCShipData{FAX} . "\n"; }

        if (length($::OCCShipData{POSTALCODE})!=0) { $sCrypt .= "&DeliveryPostCode=" . substr($::OCCShipData{POSTALCODE}, 0, 10); }

        #
        # Add confirmation email addresses if present.
        #

        if (length($::InvoiceContact{EMAIL})!=0) { $sCrypt .= "&CustomerEMail=" . $::InvoiceContact{EMAIL}; }
        if (length($sConfirmationEMail)!=0) { $sCrypt .= "&VendorEMail=" . $sConfirmationEMail; }

        # Add new 2.22 fields as well

        $sCrypt .= "&eMailMessage=You can put your own message in here";
        $sCrypt .= "&AllowGiftAid=0";
        $sCrypt .= "&ApplyAVSCV2=0";
        $sCrypt .= "&Apply3DSecure=0";

        #
        # add the crypt field to the POST
        #

        $sCrypt = Base64Encode(SimpleXOR($sCrypt,$sPassword));
        $sHiddenValues .= "<INPUT TYPE=HIDDEN NAME=\"Crypt\" VALUE=\"$sCrypt\">\n";


        #
        # Original OCC Script routines continue...
        #


        $VarTable{$::VARPREFIX . 'OCC_VALUES'} = # add the OCC values to the template
        $sHiddenValues;

        my $sLinkHTML = 'occlink.html';
        if(defined $::g_pPaymentList)
        {
        $sLinkHTML = $$::g_pPaymentList{ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'})}{BOUNCE_HTML};
        }
        @Response = ACTINIC::TemplateFile($::sPath . $sLinkHTML, \%VarTable); # build the file

        if ($Response[0] != $::SUCCESS)
        {
        $::eStatus = $::FAILURE; # return a plug-in error
        $::sErrorMessage = $Response[1];
        return ($::SUCCESS); # always return success if the script runs
        }

        @Response = ACTINIC::MakeLinksAbsolute($Response[2], $::sWebSiteUrl, $::sContentUrl);
        if ($Response[0] != $::SUCCESS)
        {
        $::eStatus = $::FAILURE; # return a plug-in error
        $::sErrorMessage = $Response[1];
        return ($::SUCCESS); # always return success if the script runs
        }

        $::sHTML = $Response[2]; # grab the resulting HTML
        #
        # process the test mode warning
        #
        my ($sDelimiter) = $:ELPREFIX . 'TESTMODE';
        if ($bTestMode) # only include the test mode block if we are in test mode
        {
        $::sHTML =~ s/$sDelimiter//g; # remove the delimiter text
        }
        else # not in test mode - remove the block
        {
        $::sHTML =~ s/$sDelimiter(.*?)$sDelimiter//gs; # remove the test mode warning blob (/s removes the \n limitation of .)
        }

        return ($::SUCCESS);

        #
        # End of Original OCCPROTXScriptTemplate.pl
        #


        #
        # Base64 encoding
        #
        sub Base64Encode ($;$)
        {
        my $res = "";
        my $eol = $_[1];
        $eol = "\n" unless defined $eol;
        pos($_[0]) = 0; # ensure start at the beginning

        $res = join '', map( pack('u',$_)=~ /^.(\S*)/, ($_[0]=~/(.{1,45})/gs));

        $res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs
        # fix padding at the end
        my $padding = (3 - length($_[0]) % 3) % 3;
        $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
        return $res;
        }


        #
        # Base64 decoding
        #
        sub Base64Decode ($)
        {
        local($^W) = 0;

        my $str = shift;
        $str =~ tr|A-Za-z0-9+=/||cd; # remove non-base64 chars
        if (length($str) % 4) {
        require Carp;
        Carp::carp("Length of base64 data not a multiple of 4")
        }
        $str =~ s/=+$//; # remove padding
        $str =~ tr|A-Za-z0-9+/| -_|; # convert to uuencoded format

        return join'', map( unpack("u", chr(32 + length($_)*3/4) . $_),
        $str =~ /(.{1,60})/gs);
        }


        #
        # SimpleXor password encryption
        #
        sub SimpleXOR ($;$)
        {
        my $plain = $_[0];
        my $password = $_[1];
        my $passstring = $_[1];
        my $res = "";

        while (length($passstring) <= length($plain)) { $passstring .= $password; }
        $passstring = substr($passstring,0,length($plain));

        $res = $plain ^ $passstring;

        return $res;

        }
        -----------------------------------------

        First Tackle - Fly Fishing and Game Angling

        -----------------------------------------

        Comment


          #5
          You're very close. Below are the changes you need to make. NetIDMe should be contacting you with details as well...

          Find the following in OCCPROTXScriptTemplate.pl:

          Code:
          #
          # URLs:
          # Strip them out and URL encode them for inclusion in the completion URL.
          # AUTH - the URL to create the authorization blob
          # BACK - the URL to return to the Catalog checkout process
          # USER - the URL to the receipt script
          #
          
          $sCrypt .= "SuccessURL=".$sSagePayURL."vps2Form/ActSuccess.asp?ActVendor=" .$sMerchantID. "&ActAmount=" . $::nOrderTotal . "&AuthURL=" . Base64Encode($::sCallBackURLAuth);
          $sCrypt .= "&InvoiceURL=" . Base64Encode($::sCallBackURLUser) . "&";
          $sCrypt .= "FailureURL=".$sSagePayURL."vps2Form/ActFail.asp?ActVendor=" .$sMerchantID. "&RedirectURL=" . Base64Encode($::sCallBackURLBack) . "&";
          Change this to:

          Code:
          #
          # URLs:
          # Strip them out and URL encode them for inclusion in the completion URL.
          # AUTH - the URL to create the authorization blob
          # BACK - the URL to return to the Catalog checkout process
          # USER - the URL to the receipt script
          # UserNetIDME - NetIDMe Script location with USER appended as querystring
          
          $::sCallBackURLUserNetIDMe = "http://www.yourwebsite.co.uk/NetIDMe/netidverify.php?receiptpage=".$::sCallBackURLUser;
          $sCrypt .= "SuccessURL=".$sPROTXURL."vps2Form/ActSuccess.asp?ActVendor=" .$sMerchantID. "&ActAmount=" . $::nOrderTotal . "&AuthURL=" . Base64Encode($::sCallBackURLAuth);
          $sCrypt .= "&InvoiceURL=" . Base64Encode($::sCallBackURLUserNetIDMe) . "&";
          $sCrypt .= "FailureURL=".$sPROTXURL."vps2Form/ActFail.asp?ActVendor=" .$sMerchantID. "&RedirectURL=" . Base64Encode($::sCallBackURLBack) . "&";
          And change "www.yourwebsite.co.uk" to the correct URL for your site. This also assumes that netidverify.php has been uploaded to a folder called NetIDMe on the web server.


          What we are doing is defining a new URL in the perl script so that SagePay will bounce back to the netidverify.php page instead of going straight to the receipt page. Netidverify.php will then send the customer to the receipt page after the age verification check has completed. It also appends the original receipt page URL to the end so that netidverify.php knows which receipt page to bounce the customer to afterwards (includes customer and order details). So instead of returning the user to the defined URL for $::sCallBackURL (the receipt page) it returns the customer to the newly defined $::sCallBackURLUserNetIDMe (i.e. netidverify.php).

          NOTE:

          There are other changes that need to be made in this file which relate to which fields are used for customer details as we are now splitting first and last name and the address fields for the netidme check.

          EDIT:

          This is all from Actinic v8 so it may be slightly different in v9!

          Comment


            #6
            Thanks for the help.

            Olderscot & Cooks-knives

            Thank you both for your assistance.

            Whilst we have moved forward based on your comments progress is slow, painful and very expensive.

            The choice we are faced with is either pay Actinic £5,000 for the PSP Developer kit which explains how all of the checkout scripts all interact or continue to pay our developer to slowly piece things together one bit at a time. As it stands we are going to spend three times as much learning about and ammending Actinic than we have paid NetIdMe for their service, its just crazy.

            Cooks-Knives; did you employ a company to make the changes needed? If so could you let me have their details?

            Regards
            William

            Comment


              #7
              The PSP kit won't help.

              From what I can tell you now have all the information you need in this thread. I really don't understand why your developer is having to do anything slowly.

              All you have to do is:

              1. Change the lines of code as specified by Cooks-Knives. This sends the customer to netidme and adds the success url so that the customer can be sent back to actinic when completed.

              2. That's pretty much it.

              There must be some netidme setup as well but I'm sure they can help on that.

              What exactly is the problem your developer is having?

              Mike
              -----------------------------------------

              First Tackle - Fly Fishing and Game Angling

              -----------------------------------------

              Comment


                #8
                Mike

                Once again thanks for your assistance.

                The latest problem we were having was that when we were returned to Actinic no output was produced from the checkout script and no receipt page was therefore rendered. As I understand it was an issue with the session file being made invalid in some way? This has now been fixed.

                Regards
                William

                Comment


                  #9
                  Excellent news, I'm glad it's now working.

                  Thnaks for posting back on what the problem was. It will help anyone else who's trying to do the same thing.

                  Mike
                  -----------------------------------------

                  First Tackle - Fly Fishing and Game Angling

                  -----------------------------------------

                  Comment

                  Working...
                  X