Authorize.net Payment Gateway Integration with Laravel

By | October 28, 2019

This tutorial is about Authorize.net Payment Gateway Integration – Laravel 5.x you will get the step by step with screenshot all the steps to integrate this in your project.

Authorize.net Payment Gateway Integration with Laravel

Authorize.net:- Authorize.Net is a United States-based payment gateway service provider, permitting merchants to simply accept credit card and electronic check payments through their website and over an Internet protocol connection.

Follow the below steps to integrate Authorize.net easily on the Laravel website.

Step 1. Install laravel application.

The initial step to begin

Please refer article for this > [How to install Laravel 5.X] for how to install Laravel

Step 2. Create account in Authorize.net and generate Login_Id and Transaction_Key

Go to https://developer.authorize.net/hello_world/sandbox/ and signup with basic details step by step.

Authorize.net Payment Gateway Integration with Laravel

Find Login_ID and Transaction_Key from Authorize.net account as per the below screenshot.

Authorize.net Payment Gateway Integration with Laravel
Click on mentioned link to navigate to right page for detail
Authorize.net Payment Gateway Integration with Laravel
Here you will get login id and transaction key by following step which mentioned with red arrows.

Step 3. copy the credentials in .env file

You need to add these parameters in your .env file and you will find this file in your root directory.

MERCHANT_LOGIN_ID=authorize.net_login_id
MERCHANT_TRANSACTION_KEY=authorize.net_transaction_key

Note: For security, reason adds those credentials only in .env file.

Step 4. Install Authorize.net package via composer

You need to run the below command for the install package in your terminal.
This command will update all the dependency of the package according to your version if you needed any in your project setup.

$ composer require "authorizenet/authorizenet"

Step 5. Create migration file and insert code below

This code is to generate a database table to store transaction information.

<?php
// path: database/migrations/payment_logs.php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class PaymentLogs extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('payment_logs', function (Blueprint $table) {
            $table->increments('id');
            $table->float('amount',8,2);
            $table->string('name_on_card')->nullable();            
            $table->string('response_code')->nullable();            
            $table->string('transaction_id')->nullable();            
            $table->string('auth_id')->nullable();            
            $table->string('message_code')->nullable();            
            $table->integer('quantity');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('payment_logs');
    }
}

Now run the migration to generate the table. do not forget to create a database first.

$ php artisan migrate

Step 6. Create Route and Controller with actions and view

Create MVC files

Now, we are going to run the below command to generate a controller file.

$ php artisan make:controller PaymentController

This generated file should look like this below code.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use net\authorize\api\contract\v1 as AnetAPI;
use net\authorize\api\controller as AnetController;

class PaymentController extends Controller {

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct() {
        //$this->middleware('auth'); // later enable it when needed user login while payment
    }

    // start page form after start
    public function pay() {
        return view('pay');
    }

    public function handleonlinepay(Request $request) {
        $input = $request->input();
        
        /* Create a merchantAuthenticationType object with authentication details
          retrieved from the constants file */
        $merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
        $merchantAuthentication->setName(env('MERCHANT_LOGIN_ID'));
        $merchantAuthentication->setTransactionKey(env('MERCHANT_TRANSACTION_KEY'));

        // Set the transaction's refId
        $refId = 'ref' . time();
        $cardNumber = preg_replace('/\s+/', '', $input['cardNumber']);
        
        // Create the payment data for a credit card
        $creditCard = new AnetAPI\CreditCardType();
        $creditCard->setCardNumber($cardNumber);
        $creditCard->setExpirationDate($input['expiration-year'] . "-" .$input['expiration-month']);
        $creditCard->setCardCode($input['cvv']);

        // Add the payment data to a paymentType object
        $paymentOne = new AnetAPI\PaymentType();
        $paymentOne->setCreditCard($creditCard);

        // Create a TransactionRequestType object and add the previous objects to it
        $transactionRequestType = new AnetAPI\TransactionRequestType();
        $transactionRequestType->setTransactionType("authCaptureTransaction");
        $transactionRequestType->setAmount($input['amount']);
        $transactionRequestType->setPayment($paymentOne);

        // Assemble the complete transaction request
        $requests = new AnetAPI\CreateTransactionRequest();
        $requests->setMerchantAuthentication($merchantAuthentication);
        $requests->setRefId($refId);
        $requests->setTransactionRequest($transactionRequestType);

        // Create the controller and get the response
        $controller = new AnetController\CreateTransactionController($requests);
        $response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::SANDBOX);

        if ($response != null) {
            // Check to see if the API request was successfully received and acted upon
            if ($response->getMessages()->getResultCode() == "Ok") {
                // Since the API request was successful, look for a transaction response
                // and parse it to display the results of authorizing the card
                $tresponse = $response->getTransactionResponse();

                if ($tresponse != null && $tresponse->getMessages() != null) {
//                    echo " Successfully created transaction with Transaction ID: " . $tresponse->getTransId() . "\n";
//                    echo " Transaction Response Code: " . $tresponse->getResponseCode() . "\n";
//                    echo " Message Code: " . $tresponse->getMessages()[0]->getCode() . "\n";
//                    echo " Auth Code: " . $tresponse->getAuthCode() . "\n";
//                    echo " Description: " . $tresponse->getMessages()[0]->getDescription() . "\n";
                    $message_text = $tresponse->getMessages()[0]->getDescription().", Transaction ID: " . $tresponse->getTransId();
                    $msg_type = "success_msg";    
                    
                    \App\PaymentLogs::create([                                         
                        'amount' => $input['amount'],
                        'response_code' => $tresponse->getResponseCode(),
                        'transaction_id' => $tresponse->getTransId(),
                        'auth_id' => $tresponse->getAuthCode(),
                        'message_code' => $tresponse->getMessages()[0]->getCode(),
                        'name_on_card' => trim($input['owner']),
                        'quantity'=>1
                    ]);
                } else {
                    $message_text = 'There were some issue with the payment. Please try again later.';
                    $msg_type = "error_msg";                                    

                    if ($tresponse->getErrors() != null) {
                        $message_text = $tresponse->getErrors()[0]->getErrorText();
                        $msg_type = "error_msg";                                    
                    }
                }
                // Or, print errors if the API request wasn't successful
            } else {
                $message_text = 'There were some issue with the payment. Please try again later.';
                $msg_type = "error_msg";                                    

                $tresponse = $response->getTransactionResponse();

                if ($tresponse != null && $tresponse->getErrors() != null) {
                    $message_text = $tresponse->getErrors()[0]->getErrorText();
                    $msg_type = "error_msg";                    
                } else {
                    $message_text = $response->getMessages()->getMessage()[0]->getText();
                    $msg_type = "error_msg";
                }                
            }
        } else {
            $message_text = "No response returned";
            $msg_type = "error_msg";
        }
        return back()->with($msg_type, $message_text);
    }

}

Make sure you include authorize.net at namespace

use net\authorize\api\controller as AnetController;

Now create a model as per the below path with code.

<?php
// Path: app/PaymentLogs.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class PaymentLogs extends Model
{
     /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'payment_logs';
    
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'amount','response_code','transaction_id', 'auth_id','quantity','message_code','name_on_card'
    ];
        
}

Now create a view file with mentioned path

Path: resources/views/pay.blade.php

@extends('layouts.app')

@section('content')

@php
    $months = array(1 => 'Jan', 2 => 'Feb', 3 => 'Mar', 4 => 'Apr', 5 => 'May', 6 => 'Jun', 7 => 'Jul', 8 => 'Aug', 9 => 'Sep', 10 => 'Oct', 11 => 'Nov', 12 => 'Dec');
@endphp
<!-- Company Overview section START -->
<section class="container-fluid inner-Page" >
    <div class="card-panel">
        <div class="media wow fadeInUp" data-wow-duration="1s"> 
            <div class="companyIcon">
            </div>
            <div class="media-body">
                
                <div class="container">
                    @if(session('success_msg'))
                    <div class="alert alert-success fade in alert-dismissible show">                
                        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                         <span aria-hidden="true" style="font-size:20px">×</span>
                        </button>
                        {{ session('success_msg') }}
                    </div>
                    @endif
                    @if(session('error_msg'))
                    <div class="alert alert-danger fade in alert-dismissible show">
                        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                          <span aria-hidden="true" style="font-size:20px">×</span>
                        </button>    
                        {{ session('error_msg') }}
                    </div>
                    @endif
                    <div class="row">
                        <div class="col-md-6">
                            <h1>Payment</h1>
                        </div>                       
                    </div>    
                    <div class="row">                        
                        <div class="col-xs-12 col-md-6" style="background: lightgreen; border-radius: 5px; padding: 10px;">
                            <div class="panel panel-primary">                                       
                                <div class="creditCardForm">                                    
                                    <div class="payment">
                                        <form id="payment-card-info" method="post" action="{{ route('dopay.online') }}">
                                            @csrf
                                            <div class="row">
                                                <div class="form-group owner col-md-8">
                                                    <label for="owner">Owner</label>
                                                    <input type="text" class="form-control" id="owner" name="owner" value="{{ old('owner') }}" required>
                                                    <span id="owner-error" class="error text-red">Please enter owner name</span>
                                                </div>
                                                <div class="form-group CVV col-md-4">
                                                    <label for="cvv">CVV</label>
                                                    <input type="number" class="form-control" id="cvv" name="cvv" value="{{ old('cvv') }}" required>
                                                    <span id="cvv-error" class="error text-red">Please enter cvv</span>
                                                </div>
                                            </div>    
                                            <div class="row">
                                                <div class="form-group col-md-8" id="card-number-field">
                                                    <label for="cardNumber">Card Number</label>
                                                    <input type="text" class="form-control" id="cardNumber" name="cardNumber" value="{{ old('cardNumber') }}" required>
                                                    <span id="card-error" class="error text-red">Please enter valid card number</span>
                                                </div>
                                                <div class="form-group col-md-4" >
                                                    <label for="amount">Amount</label>
                                                    <input type="number" class="form-control" id="amount" name="amount" min="1" value="{{ old('amount') }}" required>
                                                    <span id="amount-error" class="error text-red">Please enter amount</span>
                                                </div>
                                            </div>    
                                            <div class="row">
                                                <div class="form-group col-md-6" id="expiration-date">
                                                    <label>Expiration Date</label><br/>
                                                    <select class="form-control" id="expiration-month" name="expiration-month" style="float: left; width: 100px; margin-right: 10px;">
                                                        @foreach($months as $k=>$v)
                                                            <option value="{{ $k }}" {{ old('expiration-month') == $k ? 'selected' : '' }}>{{ $v }}</option>                                                        
                                                        @endforeach
                                                    </select>  
                                                    <select class="form-control" id="expiration-year" name="expiration-year"  style="float: left; width: 100px;">
                                                        
                                                        @for($i = date('Y'); $i <= (date('Y') + 15); $i++)
                                                        <option value="{{ $i }}">{{ $i }}</option>            
                                                        @endfor
                                                    </select>
                                                </div>                                                
                                                <div class="form-group col-md-6" id="credit_cards" style="margin-top: 22px;">
                                                    <img src="{{ asset('images/visa.jpg') }}" id="visa">
                                                    <img src="{{ asset('images/mastercard.jpg') }}" id="mastercard">
                                                    <img src="{{ asset('images/amex.jpg') }}" id="amex">
                                                </div>
                                            </div>
                                            
                                            <br/>
                                            <div class="form-group" id="pay-now">
                                                <button type="submit" class="btn btn-success themeButton" id="confirm-purchase">Confirm Payment</button>
                                            </div>
                                        </form>
                                    </div>
                                </div>                                
                            </div>
                        </div>   
                        <div class="col-md-1"></div>
                        <div class="col-md-5" style="background: lightblue; border-radius: 5px; padding: 10px;">
                            <h3>Sample Data</h3>
                            <table class="table table-bordered">
                                <tbody>
                                <tr>
                                    <th>
                                        Owner
                                    </th>
                                    <td>
                                        Simon
                                    </td>
                                </tr>
                                <tr>
                                    <th>
                                        CVV
                                    </th>
                                    <td>
                                        123
                                    </td>
                                </tr>
                                <tr>
                                    <th>
                                        Card Number
                                    </th>
                                    <td>
                                        4111 1111 1111 1111
                                    </td>
                                </tr>
                                <tr>
                                    <th>
                                        Amount
                                    </th>
                                    <td>
                                        99
                                    </td>
                                </tr>
                                <tr>
                                    <th>
                                        Expiration Date
                                    </th>
                                    <td>
                                        {{date('M')."-".(date('Y')+2)}}
                                    </td>
                                </tr>
                                </tbody>
                            </table>
                        </div>         
                    </div>
                </div>
            </div>

        </div>
    </div> 
    <div class="clearfix"></div>
</section>        
@endsection

Now add a route in routes/web.php

Route::get('/pay','PaymentController@pay')->name('pay');
Route::post('/dopay/online', 'PaymentController@handleonlinepay')->name('dopay.online');

Final Step 7. Run demo

You just need to serve the laravel now

At this stage, we are almost done with the integration and now we will un Laravel application using below command.

$ php artisan serve

Now in the browser manually type below URL

http://127.0.0.1/pay

To run the above URL and it will display the result like the below screenshot.

Run demo will look like this screenshot which clone using git source

After filling all the information of the card detail click on submit it will return with success / fail message. the success response will look like below with Transaction ID

copy this transaction id and follow the next step to confirm the transaction.

Check below screen to and search transaction to confirm

Make sure you will select ‘unsettled’ from the dropdown menu because initially, the transaction will insert as an unsettled mode
The report will look like this for unsettled transactions.

You are done now you have successfully integrated Authorize.net Payment Gateway Integration – Laravel 5.x.

Please check the below Github link to get the whole source code.

9 thoughts on “Authorize.net Payment Gateway Integration with Laravel

  1. google

    I think this is one of the most important info for me.
    And i’m glad reading your article. But wanna remark on few general things, The web site style is perfect, the articles
    is really nice : D. Good job, cheers

    Reply
  2. abdullah ahmed

    i have got the error 419 page exipred when I clicked on pay
    any help

    Reply
  3. hammad mahmood

    error_msg User authentication failed due to invalid authentication values. Please go back to Payment and put correct information
    when i put it on live this error occurred how should i get rid of this plz help

    Reply
    1. CodesCompanion

      Please check your merchant LoginID and transactionKey Or generate a new one.

      Reply
  4. Zafar Abbas

    i have got the error.

    The element ‘createTransactionRequest’ in namespace ‘AnetApi/xml/v1/schema/AnetApiSchema.xsd’ has invalid child element ‘clientId’ in namespace ‘AnetApi/xml/v1/schema/AnetApiSchema.xsd’. List of possible elements expected: ‘merchantAuthentication’ in namespace ‘AnetApi/xml/v1/schema/AnetApiSchema.xsd’.

    Reply
    1. CodesCompanion

      Try to check the credentials of env(‘MERCHANT_LOGIN_ID’) and env(‘MERCHANT_TRANSACTION_KEY’) and set the proper values to setName() and setTransactionKey().

      Here,

      $merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
      $merchantAuthentication->setName(env(‘MERCHANT_LOGIN_ID’));
      $merchantAuthentication->setTransactionKey(env(‘MERCHANT_TRANSACTION_KEY’));

      Reply

Leave a Reply

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