Accept Credit Card Payment using Authorize.Net Payment Gateway in PHP

Do you want to integrate a credit card payment option on your website? If yes, then Authorize.Net is a good choice for you. Founded in 1996, this is one of the popular payment gateways on the Internet.

For an online store, credit cards are widely used to accept payment. Customers prefer to pay through credit cards to buy online products. In your store, you must give the option for credit card payment. In this article, I show you how to integrate the Authorize.Net payment gateway which will allow you to receive credit card payments.

Whenever we are adding payment gateways, we must first test the transactions on the sandbox mode. Once the test payments are working correctly, you can go for the live version.

To get started with Authorize.Net, first, create a sandbox account. Upon account creation, copy the login id and transaction key. You can get these API keys from Account->API Credentials & Keys. Please refer to the screenshot below.

Authorize.Net API Keys

On the next page, you will get your ‘API Login ID’. Create a transaction key from the ‘Create New Key(s)’ section as shown in the below screenshot.

Authorize.Net API Login ID and Transaction Key

Similarly, under Account->Manage Public Client Key, you will get the public client key. This key will require during the integration of “Opaque Data”.

Using Authorize.Net APIs you can charge the cards in 2 ways.

  • API Authorize/Purchase (Credit Card): In this case, you will send credit card details on the server side for authorization.
  • API Authorize/Purchase (Opaque Data): Here, instead of sending card details we send tokenised card references.

We are going to see both options for charging a payment. The user can pick up either of the options in their application.

Accept Credit Card Payments using Authorize.Net

In order to integrate Authorize.Net, we will use the Omnipay library which provides a clean and easy way for payment integration. Install the Omnipay library to your project using the command:

composer require league/omnipay:^3

It will install the Omnipay library. Additionally, we are required to install the Omnipay package for Authorize.Net. This package allows us to capture payment through the Authorize.Net payment gateway. Read more about this package in their documentation. Run the command below to install this package:

composer require "academe/omnipay-authorizenetapi: ~3.0"

We are ready with supported libraries. Now, let’s create a simple form to enter the amount and card details. I am creating an index.php file and adding the below HTML in it.

<form action="charge.php" method="post">
    <input type="text" name="amount" placeholder="Enter Amount" />
    <input type="text" name="cc_number" placeholder="Card Number" />
    <input type="text" name="expiry_month" placeholder="Month" />
    <input type="text" name="expiry_year" placeholder="Year" />
    <input type="text" name="cvv" placeholder="CVV" />
    <input type="submit" name="submit" value="Submit" />
</form>

When accepting online payments, we must store the transaction details in the database. So, to store the transaction information create a ‘payments’ table in the database using the below query.

CREATE TABLE `payments` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `transaction_id` varchar(255) NOT NULL,
 `amount` float(10,2) NOT NULL,
 `currency` varchar(255) NOT NULL,
 `payment_status` varchar(255) NOT NULL,
 `captured_at` datetime NOT NULL DEFAULT current_timestamp(),
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

API Authorize/Purchase (Credit Card)

You have copied the API keys of your Authorize.Net account in the previous steps. It’s time to add these keys to the PHP code. Store these credentials in the config.php file. I am also adding the database connection to this file.

config.php

<?php
require_once "vendor/autoload.php";
 
// Connect with the database
$db = new mysqli('localhost', 'MYSQL_DB_USERNAME', 'MYSQL_DB_PASSWORD', 'MYSQL_DB_NAME');
 
if ($db->connect_errno) {
    die("Connect failed: ". $db->connect_error);
}
 
$gateway = Omnipay\Omnipay::create('AuthorizeNetApi_Api');
$gateway->setAuthName('PASTE_ANET_API_LOGIN_ID');
$gateway->setTransactionKey('PASTE_ANET_TRANSACTION_KEY');
$gateway->setTestMode(true); //comment this line when move to 'live'

Replace the placeholders with the actual values. As we are testing the payments on the sandbox, I passed true to the method setTestMode. When you are ready to move on to production, remove/comment this line.

In the form we have created above, I set charge.php as the action URL. It means the actual code which captures the credit card payment will go inside this file.

charge.php

<?php
require_once "config.php";
 
if (isset($_POST['submit'])) {
 
    try {
        $creditCard = new Omnipay\Common\CreditCard([
            'number' => $_POST['cc_number'],
            'expiryMonth' => $_POST['expiry_month'],
            'expiryYear' => $_POST['expiry_year'],
            'cvv' => $_POST['cvv'],
        ]);
 
        // Generate a unique merchant site transaction ID.
        $transactionId = rand(100000000, 999999999);
 
        $response = $gateway->authorize([
            'amount' => $_POST['amount'],
            'currency' => 'USD',
            'transactionId' => $transactionId,
            'card' => $creditCard,
        ])->send();
 
        if($response->isSuccessful()) {
 
            // Captured from the authorization response.
            $transactionReference = $response->getTransactionReference();
 
            $response = $gateway->capture([
                'amount' => $_POST['amount'],
                'currency' => 'USD',
                'transactionReference' => $transactionReference,
                ])->send();
 
            $transaction_id = $response->getTransactionReference();
            $amount = $_POST['amount'];
 
            // Insert transaction data into the database
            $isPaymentExist = $db->query("SELECT * FROM payments WHERE transaction_id = '".$transaction_id."'");
 
            if($isPaymentExist->num_rows == 0) {
                $insert = $db->query("INSERT INTO payments(transaction_id, amount, currency, payment_status) VALUES('$transaction_id', '$amount', 'USD', 'Captured')");
            }
 
            echo "Your payment transaction id: ". $transaction_id;
        } else {
            // not successful
            echo $response->getMessage();
        }
    } catch(Exception $e) {
        echo $e->getMessage();
    }
}

You can now go ahead and test a payment. Get these test credit card numbers for testing the payment. On the successful response, you should get your transaction id.

The owner can see the transactions on the Authorize.Net dashboard. You will find transactions under the ‘Unsettled transactions’. Authorize.Net later settles the transaction on its own and notifies you by email.

Transaction

API Authorize/Purchase (Opaque Data)

Let’s see now how to complete a card payment using “Opaque Data”. We will add 2 hidden fields to the HTML form. Authorize.Net generates values of these hidden fields. These tokenised values of a card then send to the server side instead of actual credit card details. The library will authorize these values against the APIs and complete the transaction.

index.php

<form id="paymentForm" method="POST" action="charge.php">
    <p><input type="text" name="amount" placeholder="Enter Amount" /></p>
    <p><input type="text" id="cardNumber" placeholder="cardNumber"/></p>
    <p><input type="text" id="expMonth" placeholder="expMonth"/></p>
    <p><input type="text" id="expYear" placeholder="expYear"/></p>
    <p><input type="text" id="cardCode" placeholder="cardCode"/></p>
    <input type="hidden" name="opaqueDataValue" id="opaqueDataValue" />
    <input type="hidden" name="opaqueDataDescriptor" id="opaqueDataDescriptor" />
    <button type="button" onclick="sendPaymentDataToAnet()">Pay Now</button>
</form>

Notice we have not added names to the card detail elements. As a result, these values will not be submitted to the site. As we have to generate values for opaque data(hidden fields), include accept.js after the payment form. This JS file is different for both sandbox and production.

  • Sandbox: https://jstest.authorize.net/v1/Accept.js
  • Production: https://js.authorize.net/v1/Accept.js

We should first test the payment on the sandbox so include the sandbox file path. Next at the click of a button, we have to grab card details and generate the opaque data as follows.

<script type="text/javascript" src="https://jstest.authorize.net/v1/Accept.js" charset="utf-8"></script>
<script type="text/javascript">
function sendPaymentDataToAnet() {
    // Set up authorisation to access the gateway.
    var authData = {};
        authData.clientKey = "PUBLIC_CLIENT_KEY";
        authData.apiLoginID = "API_LOGIN_ID";

    var cardData = {};
        cardData.cardNumber = document.getElementById("cardNumber").value;
        cardData.month = document.getElementById("expMonth").value;
        cardData.year = document.getElementById("expYear").value;
        cardData.cardCode = document.getElementById("cardCode").value;

    // Now send the card data to the gateway for tokenisation.
    // The responseHandler function will handle the response.
    var secureData = {};
        secureData.authData = authData;
        secureData.cardData = cardData;
        Accept.dispatchData(secureData, responseHandler);
}

function responseHandler(response) {
    if (response.messages.resultCode === "Error") {
        var i = 0;
        while (i < response.messages.message.length) {
            console.log(
                response.messages.message[i].code + ": " +
                response.messages.message[i].text
            );
            i = i + 1;
        }
    } else {
        paymentFormUpdate(response.opaqueData);
    }
}

function paymentFormUpdate(opaqueData) {
    document.getElementById("opaqueDataDescriptor").value = opaqueData.dataDescriptor;
    document.getElementById("opaqueDataValue").value = opaqueData.dataValue;
    document.getElementById("paymentForm").submit();
}
</script>

Make sure you have replaced the placeholders with your credentials. The above JavaScript code populates the opaque data hidden form items and finally submits the form. On the server side, we have to capture 2 fields – opaqueDataDescriptor and opaqueDataValue.

Note: If your form is not submitted then check out the errors in the browser console.

The charge.php will have the following code.

<?php
require_once "config.php";
  
if (isset($_POST['opaqueDataDescriptor']) && !empty($_POST['opaqueDataDescriptor'])) {
  
    try {
        // Generate a unique merchant site transaction ID.
        $transactionId = rand(100000000, 999999999);
  
        $response = $gateway->authorize([
            'amount' => $_POST['amount'],
            'currency' => 'USD',
            'transactionId' => $transactionId,
            'opaqueDataDescriptor' => $_POST['opaqueDataDescriptor'],
            'opaqueDataValue' => $_POST['opaqueDataValue'],
        ])->send();
  
        if($response->isSuccessful()) {
  
            // Captured from the authorization response.
            $transactionReference = $response->getTransactionReference();
  
            $response = $gateway->capture([
                'amount' => $_POST['amount'],
                'currency' => 'USD',
                'transactionReference' => $transactionReference,
                ])->send();
  
            $transaction_id = $response->getTransactionReference();
            $amount = $_POST['amount'];
  
            // Insert transaction data into the database
            $isPaymentExist = $db->query("SELECT * FROM payments WHERE transaction_id = '".$transaction_id."'");
  
            if($isPaymentExist->num_rows == 0) {
                $insert = $db->query("INSERT INTO payments(transaction_id, amount, currency, payment_status) VALUES('$transaction_id', '$amount', 'USD', 'Captured')");
            }
  
            echo "Your payment transaction id: ". $transaction_id;
        } else {
            // not successful
            echo $response->getMessage();
        }
    } catch(Exception $e) {
        echo $e->getMessage();
    }
}

I hope you understand how to accept credit card payments using the Authorize.Net payment gateway. Please share your thoughts or suggestions in the comment section below.

Related Articles

If you liked this article, then please subscribe to our YouTube Channel for video tutorials.

1 thought on “Accept Credit Card Payment using Authorize.Net Payment Gateway in PHP

  1. Hello,
    I want to send and receive my booking_id to update booking table, so i tried by refId but that field is not working.

    When i run your code and print_r response then refId is coming blank.

    Can you plz tell me how to resolve this

    Urgent issue

Leave a Reply

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