Search code examples
pythonauthorize.netaccept.js

Authorize.net accept.js python E0007 - User authentication failed due to invalid authentication values


Authorize.net

I have a sandbox environment setup and it is working as expected. I am in the process of migrating to the live system, and started with the example code and my own form. The production system is not accepting the authentication credentials.

I did not change the code. I changed from the test credentials to the live credentials through a config file. I’ve changed the transaction key a time or two and received the same results. I am not aware of a way to change the API login ID.

config.py:

    # Authorize.net test credentials
    AUTHORIZENET_JAVASCRIPT_URL = "https://jstest.authorize.net/v1/Accept.js"
    API_LOGIN_ID = "9..."
    PUBLIC_CLIENT_KEY = (
        "7..."
    )
    TRANSACTION_KEY = "6..."

    .
    .
    .

    # Authorize.net production credentials
    AUTHORIZENET_JAVASCRIPT_URL = "https://js.authorize.net/v1/Accept.js"
    API_LOGIN_ID = "8..."
    PUBLIC_CLIENT_KEY = (
        "4..."
    )
    TRANSACTION_KEY = "7..."

The card information is captured and the payment is prepared:

<script type="text/javascript" src="{{ JAVASCRIPT_URL }}" charset="utf-8">
</script>

<div class="container-narrow">
  <div class="panel owl50">
    <div class="justify-center">
      <h1>Payment information</h1>
    </div>
    <form class="owl50" id="paymentForm" method="POST" action="...">
      <input type="hidden" name="dataValue" id="dataValue" />
      <input type="hidden" name="dataDescriptor" id="dataDescriptor" />
      <div class="owl20">
        <div>
          <label for="cardNumber">Card number:</label>
          <input class="form-input" type="text" name="cardNumber" id="cardNumber" placeholder="card number" />
          <p class="text-small text-red" id="cardNumberError"></p>
        </div>
        <div>
          <label for="expMonth">Expiration month:</label>
          <input class="form-input" type="text" name="expMonth" id="expMonth" placeholder="expiration month" />
          <p class="text-small text-red" id="expMonthError"></p>
        </div>
        <div>
          <label for="expYear">Expiration year:</label>
          <input class="form-input" type="text" name="expYear" id="expYear" placeholder="expiration year" />
          <p class="text-small text-red" id="expYearError"></p>
        </div>
        <div>
          <label for="cardCode">CVV code:</label>
          <input class="form-input" type="text" name="cardCode" id="cardCode" placeholder="cvv code" />
          <p class="text-small text-red" id="cardCodeError"></p>
        </div>
      </div>
      <p class="text-red justify-center" id="dataEntryError"></p>
      <div class="owl20">
        <button class="button button-wide button-green" type="button" onclick="sendPaymentDataToAnet()" />
        Make the payment
        </button>
        <!-- <input class="button button-wide button-yellow" type="submit" name="submit" value="Cancel" /> -->
        <a class="button button-wide button-yellow" href="/members/cart">Cancel</a>
      </div>
    </form>
  </div>
</div>

<script type="text/javascript">

  function sendPaymentDataToAnet() {
    // clear the error messages
    document.getElementById("cardNumberError").innerHTML = "";
    document.getElementById("expMonthError").innerHTML = "";
    document.getElementById("expYearError").innerHTML = "";
    document.getElementById("cardCodeError").innerHTML = "";

    var authData = {};
    authData.clientKey = "{{ PUBLIC_CLIENT_KEY }}";
    authData.apiLoginID = "{{ API_LOGIN_ID }}";

    var cardData = {};
    // cardData.cardNumber = document.getElementById("cardNumber").value;
    // strip blanks from the card number
    cardData.cardNumber = document.getElementById("cardNumber").value.split(" ").join("");
    cardData.month = document.getElementById("expMonth").value;
    cardData.year = document.getElementById("expYear").value;
    cardData.cardCode = document.getElementById("cardCode").value;

    var secureData = {};
    secureData.authData = authData;
    secureData.cardData = cardData;

    Accept.dispatchData(secureData, responseHandler);

    function responseHandler(response) {
      cardCode = document.getElementById("cardCode").value;
      // display authorizenet errors and require the CVV
      if (response.messages.resultCode === "Error" ||
        cardCode == "") {
        // set the dataEntryError message for invalid input
        document.getElementById("dataEntryError").innerHTML = "Data entry error.";
        if (cardCode == "") {
          document.getElementById("cardCodeError").innerHTML = "Please provide valid CVV."
        }
        var i = 0;
        while (i < response.messages.message.length) {
          if (response.messages.message[i].code == "E_WC_05") {
            document.getElementById("cardNumberError").innerHTML = response.messages.message[i].text;
          }
          if (response.messages.message[i].code == "E_WC_06") {
            document.getElementById("expMonthError").innerHTML = response.messages.message[i].text;
          }
          if (response.messages.message[i].code == "E_WC_08") {
            document.getElementById("expMonthError").innerHTML = response.messages.message[i].text;
          }
          if (response.messages.message[i].code == "E_WC_07") {
            document.getElementById("expYearError").innerHTML = response.messages.message[i].text;
          }
          if (response.messages.message[i].code == "E_WC_08") {
            document.getElementById("expYearError").innerHTML = response.messages.message[i].text
          }
          if (response.messages.message[i].code == "E_WC_15") {
            document.getElementById("cardCodeError").innerHTML = response.messages.message[i].text;
          }
          console.log(
            response.messages.message[i].code + ": " +
            response.messages.message[i].text
          );
          i = i + 1;
        }
      } else {
        paymentFormUpdate(response.opaqueData);
      }
    }

    function paymentFormUpdate(opaqueData) {
      document.getElementById("dataEntryError").innerHTML = "";
      document.getElementById("dataDescriptor").value = opaqueData.dataDescriptor;
      document.getElementById("dataValue").value = opaqueData.dataValue;

      // If using your own form to collect the sensitive data from the customer,
      // blank out the fields before submitting them to your server.
      document.getElementById("cardNumber").value = "";
      document.getElementById("expMonth").value = "";
      document.getElementById("expYear").value = "";
      document.getElementById("cardCode").value = "";

      document.getElementById("paymentForm").submit();
    }
  }
</script>

I am setting the SDK environment and credentials based on my environment; development or production:

    # Create a merchantAuthenticationType object with authentication details
    merchantAuth = apicontractsv1.merchantAuthenticationType()
    merchantAuth.name = app.config["API_LOGIN_ID"]
    merchantAuth.transactionKey = app.config["TRANSACTION_KEY"]
    print(app.config["JAVASCRIPT_URL"])
    print("API login ID: ", app.config["API_LOGIN_ID"])
    print("Transaction key: ", app.config["TRANSACTION_KEY"])

    .
    .
    .

    # Create the controller and get response
    createtransactioncontroller = createTransactionController(createtransactionrequest)
    # For PRODUCTION use
    createtransactioncontroller.setenvironment(
        app.config["AUTHORIZENET_JAVASCRIPT_URL"]
    )
    createtransactioncontroller.execute()

From the log using the sandbox credentials:

https://jstest.authorize.net/v1/Accept.js
API login ID: 9...
Transaction key: 6...
Successfully created transaction with Transaction ID: ...
Transaction Response Code: 1
Message Code: 1

From the log using the production credentials:

https://js.authorize.net/v1/Accept.js
API login ID: 8...
Transaction key: 7...
Error Code: E00007
Error Message: User authentication failed due to invalid authentication

Solution

  • Could the account being set to Test instead of Live have anything to do with it? There is a toggle somewhere to switch to Live processing from Test. When logged in, Account > Security Settings > Test Mode Burke, I overlooked it this morning, the issue is the endpoint you are sending post requests to. Sandbox and production have different endpoints. If you notice the one you are using above is jstest.authorize but the production one is without the "test" part of that. Hope this helps! js.authorize.net/v1/Accept.js Also, if you are using any server side code with their API, that endpoint also changes in a similar fashion. Sandbox API Endpoint: apitest.authorize.net/xml/v1/request.api Production API Endpoint: api.authorize.net/xml/v1/request.api