Integrate 3-D Secure Online Payment Processing

Requirements: /n software 3-D Secure Integrator

Contents

  1. Introduction
  2. 3-D Secure Basics
  3. Set up the MPI Component
  4. Check Eligible Card Ranges
  5. Verify Customer Enrollment
  6. Payer Authentication Request
  7. Payer Authentication Response
  8. Process Payments
  9. Test and Debug
  10. Integration with Production Environments

Introduction

You can use the /n software 3-D Secure Merchant Plug-in Interface (MPI) to enable secure online payment processing using 3-D Secure for applications running on any major platform or technology. We show how to use the MPI component of E-Payment Integrator - 3-D Secure to integrate into a merchant order page the 3-D Secure services Verified by Visa, MasterCard SecureCode, JCB J/Secure, American Express SafeKey, and Diners Club International ProtectBuy. We also cover how to successfully complete PIT testing.

3-D Secure Basics

3-D Secure is a protocol developed by Visa to make online payments more secure through password authentication and cardholder verification. Here are the basics of secure online payment processing with 3-D Secure:

Enroll

The cardholder is eligible to take advantage of 3-D Secure services offered by online merchants after enrollment, at which time he/she sets a password. Information about the cardholder is then created in the enrollment server, which keeps track of cardholders participating in the 3-D Secure service, and in the access control servers (ACS), which are used at the time of purchase to verify cardholder enrollment.

Authenticate Cardholders

At the time of purchase, the merchant contacts a directory server to check for enrollment. If the cardholder is enrolled, the directory server will respond back with the URL of an ACS, which can be used to authenticate the cardholder.

Next, the merchant sends a payer authentication request (PAReq) to the ACS through the cardholder's browser or device. The cardholder then authenticates themselves directly to the ACS - the merchant is not involved in this part of the process. Next, the ACS sends a signed payer authentication response (PARes) containing the results of the cardholder authentication to the MPI. The MPI verifies the ACS signature on the PARes and parses the response.

Supply Additional Authorization Information

At this point, the merchant continues with the normal credit card authorization process; the only difference is that when the customer's credit card information is sent for authorization, the merchant can submit additional values returned in a successful 3-D Secure authentication: XID (transaction Id), ECI (electronic commerce indicator), and CAVV (cardholder authentication verification value). Submitting these values is required in order to qualify for the protections and discounted rates that 3-D Secure transactions provide.

Set up the MPI Component

The MPI component enables you to use the same code to support any 3-D Secure service: Simply use different values for the authentication properties depending on which card brand is in use. These values will be provided by the merchant's acquiring bank when the account is set up for Verified by Visa, SecureCode, J/Secure, SafeKey, or ProtectBuy. When the customer presents his or her card, you can use the CardValidator component to determine the card type and perform basic validation checks; after calling the ValidateCard method, the CardType property will be available. Once the card type has been determined, you can set up the MPI. The only properties you will need to change depending on the card type are:

  • DirectoryServerURL

    The DirectoryServerURL property should be set to the URL of the directory server provided to you.

  • RootCertificate

    The RootCertificate property is used to verify the digital signature of the payer authentication response. It should be set to the Base64-encoded public key value of the certificate of the ACS. There may be more than one possible signing certificate, so you can append to the RootCertificate property by prepending a "+" character to the Base64-encoded string value.

  • SSLAcceptServerCert

    The Base64-encoded public key of the certificate to trust. This value is compared with the certificate presented by the server during SSL negotiation, and if they match, the server certificate is accepted and the connection will continue normally. Set this property to unconditionally accept a server certificate that matches this value, overriding the default behavior of the component, which terminates the connection if an issue with the certificate is encountered. Setting the SSLAcceptServerCert property is optional, since the SSLServerAuthentication event could also be used (except in classic ASP).

  • Client Certificate Properties

    Set SSLCert to point to the SSL client certificate that you will use to provide authentication to the directory and access control servers during SSL negotiation. The client certificate is not necessarily required: Your acquiring bank will provide you with the type of authentication you need to use (either a password or a client certificate).

  • Merchant Properties

    Other information provided to the merchant by the acquiring bank are the merchant number (Id), password, and graphics that can be displayed on your websites to show that you use 3-D Secure authentication.

Check Eligible Card Ranges

This step is optional, but is useful to avoid unnecessary authentication attempts. Not all credit cards are eligible for 3-D Secure authentication, such as some check cards, gift cards, and corporate cards. You can call the RequestCardRanges method of the MPI component to check if a card is eligible for enrollment and to avoid downloading a large list too often.

The RequestCardRanges method can either retrieve all eligible card ranges from the directory server, or only the changes in eligible card ranges since a previous request. This behavior is controlled by the SerialNumber property. If the SerialNumber property has a non-empty value of "" (an empty string) before calling RequestCardRanges, the full list of eligible card ranges will be returned and SerialNumber set to a serial number that shows when the local cache was last updated. If the SerialNumber property has a non-empty value prior to calling the RequestCardRanges method, then the directory server will return only the changes since the last response that match the specified serial number.

if (MPI1.SerialNumber == "") {
  MPI1.MessageId = "001";
  MPI1.RequestCardRanges();
}
if(!InCardRange(txtCardNumber.Text)){
  NotEnrolled();
  return;
}

The results returned are stored in the CardRanges property, so that for subsequent card range requests you can simply update your saved list of ranges with the changes. For example, CardRanges[0].Begin and CardRanges[0].End may be one range of eligible card numbers. If the value of CardRanges[0].Action is "A", the cards in that range are eligible. If CardRanges[0].Action is "D", the cards in that range are no longer eligible and should be deleted from the local cache of card ranges. (It is recommended that you periodically refresh the local cache with a full list).

If the customer card number does not fall within any of these ranges, then the customer is not enrolled in 3-D Secure and regular credit card authorization should continue without 3-D Secure authentication. If the card number presented by the customer falls within one of these ranges, the customer might be enrolled in 3-D Secure service, but the VerifyEnrollment method needs to be used to determine enrollment with certainty.

Verify Customer Enrollment

You can use the VerifyEnrollment method of the MPI component to determine if a cardholder is enrolled in a 3-D Secure service. When this method returns, one of the following values will be stored in the CardEnrolled property:

  • Y: The customer is enrolled.
  • N: the customer is not enrolled.
  • U: The customer is enrolled, but authentication is currently unavailable.

If the value of CardEnrolled is "Y", you can continue with the next step of 3-D Secure; otherwise, the credit card will need to be authorized without 3-D Secure authentication. Note that many U.S. card issuers automatically enroll cards in 3-D Secure programs; these cardholders can be authorized using 3-D Secure even if they have not set a password. In these cases, the payer authentication response from the issuing bank will contain a specific ECI value that shows the merchant has sent the authentication request.

MPI1.CardNumber = tbCardNumber.Text;
MPI1.DirectoryServerURL = "https://url.obtainedfrom.acquiringbank/";
MPI1.VerifyEnrollment();
if (MPI1.CardEnrolled == "Y")
{
SendAuthenticationRequest();
}
//else the customer is not enrolled

Payer Authentication Request

Calling the VerifyEnrollment method sets the ACSURL property, where the customer is sent to authorize the transaction. Before the customer leaves the merchant's site and is directed to the ACS, you will need to send the payer authentication request (PAReq). This contains the necessary information to authenticate the cardholder and the transaction, and to redirect the customer back to the merchant's site. You can use the component to automate and organize this exchange:

Step One: Generate the Request

To generate the request, call the GetAuthenticationPacket method, which uses the properties of the component to generate a compressed and encoded request. Prior to calling GetAuthenticationPacket, you will need to set at least MessageId, TransactionId, TransactionAmount, TransactionDisplayAmount, and the card properties:

MPI1.MessageId = "11292007120208046";
MPI1.TransactionId = "11292007120208046";
MPI1.CardExpMonth = tbCardExpMonth.Text;
MPI1.CardExpYear = tbCardExpYear.Text;
MPI1.TransactionAmount = "7256";
MPI1.TransactionDisplayAmount = "$72.56";
string PAReq = MPI1.GetAuthenticationPacket();

Note that after calling VerifyEnrollment the response may encrypt, encode, or otherwise modify the CardNumber property value. If CardNumber is reset to the actual card number before calling GetAuthenticationPacket, the ACS may respond with an error. Additionally, the TransactionAmount property is specified without a decimal point; for example, $72.56 is represented as 7256.

Step Two: Complete the Request

Besides the payer authentication request, you will need to send two additional pieces of data: the termination URL (TermUrl) and the merchant data (MD). TermUrl supplies the ACS with the URL to post back to after the customer has authenticated themselves. The merchant data enables you to match the response from the ACS to the sale; it is posted back to the termination URL. Typically this data is a unique identifier associated with the transaction to be authorized. (Note that you should never send the card number in the MD field on a production system.) In this example, the MD field contains the key of a database record that temporarily stores the transaction information until the response from the ACS is received. The fields in the response are checked against this record of the transaction.

The transaction information you will need to store is exactly the same information used to generate the payer authentication request (MessageId, TransactionId, CardNumber, TransactionAmount). Note that when storing data your application will be subject to the PCI Data Security Standard (PCI DSS). See https://www.pcisecuritystandards.org/index.php for more information.

Step Three: Send the Request

Next, you will need to send the request, including TermUrl and MD, to the ACS. The 3-D Secure standard requires that the request must be sent through the cardholder's browser, and thus cannot be sent by the MPI component itself. One way to do this is with JavaScript:

ClientScript.RegisterHiddenField("PAReq",PAReq);
ClientScript.RegisterHiddenField("TermUrl",Request.Url.Authority +
                                  "/mpiResponse.aspx");
ClientScript.RegisterHiddenFied("MD",mytransactionkey);
myBody.Attributes.Add("onLoad", "javascript: document." + myForm.ID + 
  ".action='" + MPI.ACSURL +  "'; document." +
  myForm.ID + ".submit();");

The above sample code will write the JavaScript code to the HTML page body, setting the action of the HTML form named "myForm" (the form where the cardholder submitted their data) to the ACS URL, and submitting the form. The data is submitted as three hidden fields, PAReq, TermUrl, and MD.

Payer Authentication Response

After the customer has been authenticated, the ACS redirects the customer to the termination URL. mpiResponse.aspx accesses the two form variables that were posted back by the ACS: PARes, containing the authentication response, and MD, the merchant data containing the unique transaction identifier that was passed in with the authentication request. This information is needed to verify that the response matches the transaction information stored by the merchant; use the merchant data as the key for this record in the transaction database. You can call the CheckAuthenticationResponse method to verify the digital certificate of the ACS and the data integrity of the response:

MPI1.RootCertificate = "MIIBwDCCASmgAwIB...";
MPI1.RootCertificate = "+MIICHjCCAYegAwIB...";
MPI1.MerchantBankId = "999999";
MPI1.MerchantNumber = "TEST_NUMBER";
MPI1.TransactionId = transaction_id;
MPI1.TransactionAmount = transaction_amount;
MPI1.CardNumber = transaction_cardnumber;
MPI1.MessageId = transaction_messageid;
MPI1.CheckAuthenticationResponse(Request.Form["PARes"]);

If the authentication was successful, the AuthenticationStatus property will contain "Y". You will then need to pass the TransactionId, AuthenticationCAVV, and AuthenticationECI properties in the credit card authorization request in order to qualify for the extra protection and discount. You can use these properties to integrate 3-D Secure into other credit card processing applications; you can also use both E-Payment Integrator and Direct Payment Integrator to build payment processing applications.

If AuthenticationStatus is "N", the authentication failed and you must not complete the transaction. Note that even if AuthenticationStatus contains "Y", the transaction should not be considered authentic if the signature verification fails. A transaction may only be considered authentic if the value of AuthenticationStatus is "Y" and no errors are generated by the CheckAuthenticationResponse method.

Process Payments

After CheckAuthenticationResponse has succeeded, 3-D secure authentication has been completed and the customer's credit card can be charged. Here are a few examples of how to accomplish this with /n software components:

Direct Payment Integrator

Direct Payment Integrator provides a uniform interface for processing credit card payments with the major payment processors directly, rather than through a payment gateway. The code example below shows using the TSYSECommerce component of Direct Payment Integrator to process a payment with TSYS:

    TSYS:
    Tsysecommerce1.Config("CAAV=" + MPI1.AuthenticationCAVV);
    Tsysecommerce1.Card.ExpMonth = transaction_cardexpmonth;
    Tsysecommerce1.Card.ExpYear = transaction_cardexpyear;
    Tsysecommerce1.CustomerAddress = transaction_customeraddress;
    Tsysecommerce1.CustomerZip = transaction_customerzip;
    Tsysecommerce1.TransactionAmount = transaction_amount;
    Tsysecommerce1.TransactionNumber = "0001" //increment for each transaction
    Tsysecommerce1.Config("XID=" + MPI1.TransactionId);
    Tsysecommerce1.Config("ECI=" + MPI1.AuthenticationECI);
    Tsysecommerce1.Config("CAAV=" + MPI1.AuthenticationCAVV);
E-Payment Integrator

Supporting 3-D Secure with E-Payment Integrator depends on which gateway you are using, because each gateway might expect the TransactionId, AuthenticationECI, and AuthenticationCAVV properties to have different field names. Once you know the field names used by the gateway, you can then call the AddSpecialFields method of the ICharge component to add them to the outgoing request - you will find the special fields required by any supported gateway in the ICharge Gateway Setup and Required Properties section. Prior to calling the method that corresponds to the transaction, simply add each special field. For example:

    USAEPay:
    ICharge1.AddSpecialField("UMxid",MPI1.TransactionId);
    ICharge1.AddSpecialField("UMeci",MPI1.AuthenticationECI);
    ICharge1.AddSpecialField("UMcavv",MPI1.AuthenticationCAVV);
    Paymentech Orbital:
    ICharge1.AddSpecialField("XID", MPI1.TransactionId);icharge1.AddSpecialField("AuthenticationECIInd", MPI1.AuthenticationECI);
    ICharge1.AddSpecialField("CAVV", MPI1.AuthenticationCAVV);
    // If this is a MasterCard instead of a Visa, 
    // use AAV instead of CAVV.
    Authorize.Net:
    ICharge1.AddSpecialField("x_authentication_indicator",
      MPI1.AuthenticationECI);
    ICharge1.AddSpecialField("x_cardholder_authentication_value",
      MPI1.AuthenticationCAVV);

Test and Debug

After you are confident in your solution, you will need to undergo some amount of product integration testing (PIT). You will find a step-by-step explanation of how to complete PIT testing in our PIT Testing overview. MasterCard SecureCode and JCB J/Secure also have test infrastructures for your convenience.

You can use the ICharge component to simplify your testing process: it provides a ResponsePacket property, a DataPacketIn event, and a DataPacketOut event. The ResponsePacket property can be used to access the responses received from the directory server after a call to RequestCardRanges or VerifyEnrollment. It can also be used to access the PARes received from the ACS after calling CheckAuthenticationResponse.

The two events, DataPacketOut and DataPacketIn, are fired when sending/receiving data packets to/from a remote server. You can use the DataPacketOut event to view the unencrypted XML version of the PAReq after a call to GetAuthenticationPacket. Note that in the classic ASP edition, where there are no events, the DataPacketOut and ResponsePacket properties can be used to read the last data sent to and received from the directory server and/or access control server.

To follow best practices to load and store partially completed transactions, you may need to write additional code to secure your database. In a real production environment, another best practice is to log all messages from the components of both E-Payment Integrator and Direct Payment Integrator. You will find more information in the Best Practices for Payment Processing section of the Help documentation.

You can use the test servers used in this tutorial and in the accompanying demo applications. These servers are not complete servers, but basic stubs designed to allow simple code testing; they will respond with hard-coded transaction information using the supplied example values.

Integration with Production Environments

You can use the MPI component to simplify each step of the 3-D Secure process and provide detailed debugging output at each step as you complete PIT testing. The Process Payments section shows how to use the ICharge component to process credit card payments with several major payment gateways; you will find ready-to-build solutions that show how to use this and other critical components for secure payment processing in the demos for E-Payment Integrator and Direct Payment Integrator.


We appreciate your feedback.  If you have any questions, comments, or suggestions about this article please contact our support team at kb@nsoftware.com.