For Laravel 5.0 and above
To get started add the following package to your composer.json
file using this command.
composer require paytm/js-checkout
Note: For Laravel 5.5 and above auto-discovery takes care of below configuration.
When composer installs Laravel Paytm Wallet library successfully, register the Paytm\JsCheckout\PaytmServiceProvider
in your config/app.php
configuration file.
'providers' => [
// Other service providers...
Paytm\JsCheckout\PaytmServiceProvider::class,
],
Also, add the Paytm
facade to the aliases
array in your app
configuration file:
'aliases' => [
// Other aliases
'Paytm' => Paytm\JsCheckout\Facades\Paytm::class,
],
PAYTM_ENVIRONMENT=staging
PAYTM_MERCHANT_ID=YOUR_MERCHANT_ID_HERE
PAYTM_MERCHANT_KEY=YOUR_SECRET_KEY_HERE
PAYTM_MERCHANT_WEBSITE=YOUR_MERCHANT_WEBSITE
PAYTM_CHANNEL=YOUR_CHANNEL_HERE
PAYTM_INDUSTRY_TYPE=YOUR_INDUSTRY_TYPE_HERE
On your config/services.php
add the following configuration
'paytm' => [
'env' => env('PAYTM_ENVIRONMENT'), // values : (staging | production)
'merchant_id' => env('PAYTM_MERCHANT_ID'),
'merchant_key' => env('PAYTM_MERCHANT_KEY'),
'merchant_website' => env('PAYTM_MERCHANT_WEBSITE'),
'channel' => env('PAYTM_CHANNEL'),
'industry_type' => env('PAYTM_INDUSTRY_TYPE'),
],
Note : All the credentials mentioned are provided by Paytm after signing up as merchant.
Our package is compatible with Laravel 7 but same_site setting is changed in default Laravel installation, make sure you change same_site
to null
in config/session.php
or callback won't include cookies and you will be logged out when a payment is completed
<?php
use Illuminate\Support\Str;
return [
/...
'same_site' => null,
];
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Paytm;
class PaytmController extends Controller
{
// display a form for payment
public function initiate()
{
return view('paytm');
}
public function pay(Request $request)
{
$amount = 1; //Amount to be paid
$userData = [
'name' => $request->name, // Name of user
'mobile' => $request->mobile, //Mobile number of user
'email' => $request->email, //Email of user
'fee' => $amount,
'order_id' => rand(1,1000) //Order id
];
$payment = Paytm::with('receive');
$payment->prepare([
'order' => $userData['order_id'],
'user' => 1,
'mobile_number' => $userData['mobile'],
'email' => $userData['email'], // your user email address
'amount' => $amount, // amount will be paid in INR.
'callback_url' => route('status') // callback URL
]);
$response = $payment->receive(); // initiate a new payment
return $response;
}
public function paymentCallback()
{
$transaction = Paytm::with('receive');
$response = $transaction->response();
$order_id = $transaction->getOrderId(); // return a order id
$transaction->getTransactionId(); // return a transaction id
// update the db data as per result from api call
if ($transaction->isSuccessful()) {
return redirect(route('initiate.payment'))->with('message', "Your payment is successfull.");
} else if ($transaction->isFailed()) {
return redirect(route('initiate.payment'))->with('message', "Your payment is failed.");
} else if ($transaction->isOpen()) {
return redirect(route('initiate.payment'))->with('message', "Your payment is processing.");
}
$transaction->getResponseMessage(); //Get Response Message If Available
}
}
<!DOCTYPE html>
<html>
<head>
<title>Payment gateway using Paytm</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<style type="text/css">
#paytm-pg-spinner {margin: 20% auto 0;width: 70px;text-align: center;z-index: 999999;position: relative;}
#paytm-pg-spinner > div {width: 10px;height: 10px;background-color: #012b71;border-radius: 100%;display: inline-block;-webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;animation: sk-bouncedelay 1.4s infinite ease-in-out both;}
#paytm-pg-spinner .bounce1 {-webkit-animation-delay: -0.64s;animation-delay: -0.64s;}
#paytm-pg-spinner .bounce2 {-webkit-animation-delay: -0.48s;animation-delay: -0.48s;}
#paytm-pg-spinner .bounce3 {-webkit-animation-delay: -0.32s;animation-delay: -0.32s;}
#paytm-pg-spinner .bounce4 {-webkit-animation-delay: -0.16s;animation-delay: -0.16s;}
#paytm-pg-spinner .bounce4, #paytm-pg-spinner .bounce5{background-color: #48baf5;}
@-webkit-keyframes sk-bouncedelay {0%, 80%, 100% { -webkit-transform: scale(0) }40% { -webkit-transform: scale(1.0) }}
@keyframes sk-bouncedelay { 0%, 80%, 100% { -webkit-transform: scale(0);transform: scale(0); } 40% {
-webkit-transform: scale(1.0); transform: scale(1.0);}}
.paytm-overlay{position: fixed;top: 0px;opacity: .4;height: 100%;background: #000;}
</style>
<div id="paytm-pg-spinner" class="paytm-pg-loader" style="display: none;">
<div class="bounce1"></div>
<div class="bounce2"></div>
<div class="bounce3"></div>
<div class="bounce4"></div>
<div class="bounce5"></div>
</div>
<div class="paytm-overlay" style="display:none;"></div>
<div class="container" width="500px">
<div class="panel panel-primary" style="margin-top:110px;">
<div class="panel-heading"><h3 class="text-center">Payment gateway using Paytm Laravel JS Checkout</h3></div>
<div class="panel-body">
<form action="{{ route('make.payment') }}" method="POST" enctype="multipart/form-data">
{!! csrf_field() !!}
@if($message = Session::get('message'))
<p>{!! $message !!}</p>
<?php Session::forget('success'); ?>
@endif
<div class="row">
<div class="col-md-12">
<strong>Name:</strong>
<input type="text" name="name" class="form-control name" placeholder="Name" required>
</div>
<div class="col-md-12">
<strong>Mobile No:</strong>
<input type="text" name="mobile" class="form-control mobile" maxlength="10" placeholder="Mobile No." required>
</div>
<div class="col-md-12">
<strong>Email:</strong>
<input type="email" class="form-control email" placeholder="Email" name="email" required>
</div>
<div class="col-md-12" >
<br/>
<div class="btn btn-info">
Term Fee : 1 Rs/-
</div>
</div>
<div class="col-md-12">
<br/>
<button type="submit" class="btn btn-success pay">Paytm</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
@if(env('PAYTM_ENVIRONMENT')=='production')
<script type="application/javascript" crossorigin="anonymous" src="https:\\securegw.paytm.in\merchantpgpui\checkoutjs\merchants\<?php echo env('PAYTM_MERCHANT_ID')?>.js" ></script>
@else
<script type="application/javascript" crossorigin="anonymous" src="https:\\securegw-stage.paytm.in\merchantpgpui\checkoutjs\merchants\<?php echo env('PAYTM_MERCHANT_ID')?>.js" ></script>
@endif
<script type="text/javascript">
//function openJsCheckout(){
$(".pay").click(function(e){
var name = $('.name').val();
var mobile = $('.mobile').val();
var email = $('.email').val();
if(name == "" || mobile == "" || email== "" ){
alert("Please fill all the fields");
return false;
}
e.preventDefault();
$.ajax({
type:'POST',
url:'payment',
data: {
'_token':'{{ csrf_token() }}',
'name': $('.name').val(),
'mobile': $('.mobile').val(),
'email': $('.email').val(),
},
success:function(data) {
$('.paytm-pg-loader').show();
$('.paytm-overlay').show();
if(data.txnToken == ""){
alert(data.message);
$('.paytm-pg-loader').hide();
$('.paytm-overlay').hide();
return false;
}
invokeBlinkCheckoutPopup(data.orderId,data.txnToken,data.amount)
}
});
});
function invokeBlinkCheckoutPopup(orderId,txnToken,amount){
window.Paytm.CheckoutJS.init({
"root": "",
"flow": "DEFAULT",
"data": {
"orderId": orderId,
"token": txnToken,
"tokenType": "TXN_TOKEN",
"amount": amount,
},
handler:{
transactionStatus:function(data){
} ,
notifyMerchant:function notifyMerchant(eventName,data){
if(eventName=="APP_CLOSED")
{
$('.paytm-pg-loader').hide();
$('.paytm-overlay').hide();
//location.reload();
}
console.log("notify merchant about the payment state");
}
}
}).then(function(){
window.Paytm.CheckoutJS.invoke();
});
}
</script>
</body>
</html>
Route::get('/initiate','PaytmController@initiate')->name('initiate.payment');
Route::post('/payment','PaytmController@pay')->name('make.payment');
Route::post('/payment/status', 'PaytmController@paymentCallback')->name('status');
Important: The callback_url
must not be csrf protected Check out here to how to do that