Fonepay Integration In Laravel

Tamrakar Shreyaa
4 min readJan 27, 2023

Install Laravel Project

Run the command to induct fresh Laravel project.

composer create-project laravel/laravel fonepay

Create fresh database in your mysql and set .env file

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:jrqlrLJkYrHmVI+t3YLFVcmVtunx1YTCHwJjFT+aC8I=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=fonepay
DB_USERNAME=root
DB_PASSWORD=password

BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=database
SESSION_LIFETIME=120

MEMCACHED_HOST=127.0.0.1

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_HOST=
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1

VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

Create Migration

php artisan make:model Fonepay -m

Now In the Migration file,

<?php

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

class CreateFonepayTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('fonepay', function (Blueprint $table) {
$table->id();
$table->string('PRN')->nullable();
$table->string('UID')->nullable();
$table->string('BID')->nullable();
$table->string('amount')->nullable();
$table->boolean('status');

$table->timestamps();
});
}

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

Next,this command use to in your terminal then this setup create to in your database.

php artisan migrate

The complete code in Fonepay Model is given below.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;


class Fonepay extends Model
{
protected $table = 'fonepay';

protected $fillable = [
'PRN', 'UID', 'BID', 'status','amount'
];


public static function _create($params)
{



$fonepay = new self();
$fonepay->PRN = $params['PRN'];
$fonepay->UID = $params['UID'];
$fonepay->BID = $params['BID'];
$fonepay->amount = $params['PAMT'];
$fonepay->status = '2';
$fonepay->save();



}
public static function _check($requestData)
{

$fonepay = [
'PID' => 'NBQM',
'PRN' => $requestData['PRN'],
'BID' => $requestData['BID'],
'UID' => $requestData['UID'],
'AMT' => $requestData['PAMT']
];

$sharedSecretKey='paste your secret key here';
$fonepay['DV'] = hash_hmac('sha512', $fonepay['PID'].','.$fonepay['AMT'].','.$fonepay['PRN'].','.$fonepay['BID'].','.$fonepay['UID'], $sharedSecretKey);
$fonepay_config='https://dev-clientapi.fonepay.com/api/merchantRequest/verificationMerchant';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $fonepay_config.'?'.http_build_query($fonepay));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = [ "response" => simplexml_load_string(curl_exec($ch)), "status" => curl_getinfo($ch, CURLINFO_HTTP_CODE) ];

curl_close($ch);

return $response;
}


}

Now let’s makes our required routes in routes/web.php

Route::prefix('order')->name('order.')->group( function () {

$ctr = OrderController::class;
Route::get('/test', $ctr.'@test')->name('test');

Route::post('save', $ctr.'@save')->name('save');

Route::get('fonepay/verify', $ctr.'@fonepay_verify')->name('fonepay.verify');


});

Now Let’s create our OrderController by running the following command.

<?php

namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Fonepay;
use Illuminate\Http\Request;
use App\Models\Order;
use Exception;
use Illuminate\Support\Str;
class OrderController extends Controller
{


public function test()
{

$currency_code = 'NPR';
return view('payment',compact('currency_code'));
}


public function save(Request $request)
{
try
{



$fonepay = [
'MD' => 'P',
'PID' => 'NBQM',
'PRN' => uniqid(),
'AMT' => $request->total,
'CRN' => 'NPR',
'DT' => date('m/d/Y'),
'R1' => 'test',
'R2' => 'N/A',
'RU' => route('order.fonepay.verify'),
'request_url' => 'https://dev-clientapi.fonepay.com/api/merchantRequest',
];

$fonepay['DV'] = hash_hmac('sha512', $fonepay['PID'].','.$fonepay['MD'].','.$fonepay['PRN'].','.$fonepay['AMT'].','.$fonepay['CRN'].','.$fonepay['DT'].','.$fonepay['R1'].','.$fonepay['R2'].','.$fonepay['RU'], 'paste your secret key here');

return view('fonepay', compact('fonepay'));



dd([ 'status' => 'failed', 'msg' => 'Your Payment failed' ]);
}
catch (Exception $e)
{
dd(['status' => 'failed', 'msg' => 'Something went Wrong, Try Again' ]);
}
}

public function fonepay_verify(Request $request)
{
try
{
$prn = $request->PRN;
$bid = $request->BID ?? '';
$uid = $request->UID;
$pamt = $request->P_AMT;

$requestData = [
'PRN' => $prn,
'BID' => $bid,
'UID' => $uid,
'PAMT'=> $pamt
];


$result = Fonepay::_check($requestData);
Fonepay::_create($requestData);
if ($result['status'] == 200 && $result['response']->success == 'true') {
dd('success');
}else{
dd('fail');
}
}
catch (Exception $e)
{
dd(['status' => 'failed', 'msg' => 'Something went Wrong, Try Again' ]);
}
}
}

Now let’s see the complete code for our View page —payment.blade.php file

<html>
<head>
<title>checkout</title>
</head>
<body>
<h1>Checkout</h1>
<form action="{{ route('order.save') }}" method="POST" id="checkout-form">
@csrf
<input type="hidden" name="currency_code" value="{{ $currency_code }}">
<div style="margin-bottom: 10px;">
Total Amount : RS <input type="number" value="1" name="total" placeholder="total" id="total-amount">
</div>
<div style="margin-bottom: 10px;">

<label>
<input type="radio" name="payment_type" value="fonepay" checked> Pay with Fonepay
</label>

</div>
<div>
<button type="submit" id="payment-button">PAY</button>
</div>
</form>


</body>
</html>

Complete code for our View page —fonepay.blade.php file

<form action="{{ $fonepay['request_url'] }}" id="fonepay-payment-request" method="GET"> 
<input type="hidden" name="PID" value="{{ $fonepay['PID'] }}">
<input type="hidden" name="MD" value="{{ $fonepay['MD'] }}">
<input type="hidden" name="AMT" value="{{ $fonepay['AMT'] }}">
<input type="hidden" name="CRN" value="{{ $fonepay['CRN'] }}">
<input type="hidden" name="DT" value="{{ $fonepay['DT'] }}">
<input type="hidden" name="R1" value="{{ $fonepay['R1'] }}">
<input type="hidden" name="R2" value="{{ $fonepay['R2'] }}">
<input type="hidden" name="DV" value="{{ $fonepay['DV'] }}">
<input type="hidden" name="RU" value="{{ $fonepay['RU'] }}">
<input type="hidden" name="PRN" value="{{ $fonepay['PRN'] }}">
</form>

<script type="text/javascript">
document.getElementById('fonepay-payment-request').submit();
</script>

Output :

--

--

Tamrakar Shreyaa

Laravel | PHP | API | AJAX | jQuery | Laravel vue | Livewire | LAMP stack | CI CD