How to implement phonepe in laravel?
This guide provides a step-by-step process on how to integrate the phonepe payment gateway into a PHP or a Laravel application without using any package, I prefer to use laravel but this process will work in PHP aswell
You dont need a an account for testing phonpe payment gateway, PhonePe test credentials are public, But if you wish for live / production keys for real payments then you need to login / register on phonepe business solutions
Test Credentials :
Merchant ID : PGTESTPAYUAT Salt Key : 099eb0cd-02cf-4e2a-8aca-3e6c6aff0399
Test Card :
Card : 4111 1111 1111 1111 Expiry: 12/25 (any future date) CVV: 111 OTP : 123456
To create a controller use the command below.
php artisan make:controller PaymentController
Now we will create a payment form so you can ask user for the detials and conformation you need, Then we will process the payment and then in callback we will confirm the payment and Check if its a success or not, So lets create some routes in web.php
//PAYMENT FORM
Route::get('payment-form', [\App\Http\Controllers\PaymentController::class, 'index'])->name('payment-form');
//PAYMENT ROUTE
Route::post('pay-with-phonepe', [\App\Http\Controllers\PaymentController::class, 'payWithPhonePe'])->name('pay-with-phonepe');
//CALLBACK ROUTE
Route::get('phonepe-callback', [\App\Http\Controllers\PaymentController::class, 'callback'])->name('phonepe-callback');
Now create a function named index in PaymentController.php
public function index()
{
return view('phonepe.payment-form');
}
Now create a payment form,
resources/views/phonepe/payment-form.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>PhonePe Payment Gateway</title>
<!-- BOOTSTRAP -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<!-- Styles -->
<style>
body {
background: #f7f7f7;
}
.form-box {
max-width: 500px;
margin: auto;
padding: 50px;
background: #ffffff;
border: 10px solid #f2f2f2;
margin-top: 100px;
}
h1, p {
text-align: center;
}
input, textarea {
width: 100%;
}
</style>
</head>
<body>
<div class="form-box">
<h1>Pay with PhonePe</h1>
<form action="{{ route('pay-with-phonepe') }}" method="post" style="text-align: center;margin-top: 50px;">
@csrf
<button type="submit" class="btn btn-primary">Pay $19</button>
</form>
</div>
</body>
</html>
Now because PhonePe payment callback will be in post method and there will be no csrf token passed from PhonePe side, So we need to exclude csrf verification for phonepe callback url, To do that we need to add callback url in a middleware located in app/Http/Middleware/VerifyCsrfToken.php
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
protected $except = [
'phonepe-callback'
];
}
Now create a function named payWithPhonePe in PaymentController.php
public function payWithPhonePe()
{
$redirect_url = route('phonepe-callback');
$saltKey = '099eb0cd-02cf-4e2a-8aca-3e6c6aff0399';
$merchantId = 'PGTESTPAYUAT';
$amount = 19 * 100;
$testMode = true;
$merchantUserId = time();
if($testMode)
{
$chUrl = 'https://api-preprod.phonepe.com/apis/pg-sandbox/pg/v1/pay';
}
else
{
$chUrl = 'https://api.phonepe.com/apis/hermes';
}
$paymentData = array(
'merchantId' => $merchantId,
'merchantTransactionId' => time().rand(1,1000),
"merchantUserId"=> $merchantUserId,
'amount' => $amount,
'redirectUrl' => $redirect_url,
'redirectMode' => "POST",
'callbackUrl' => $redirect_url,
"merchantOrderId" => time(),
"paymentInstrument" => array(
"type"=> "PAY_PAGE",
),
);
$jsonencode = json_encode($paymentData);
$payloadMain = base64_encode($jsonencode);
$salt_index = 1;
$payload = $payloadMain . "/pg/v1/pay" . $saltKey;
$sha256 = hash("sha256", $payload);
$final_x_header = $sha256 . '###' . $salt_index;
$request = json_encode(array('request'=>$payloadMain));
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $chUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $request,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-VERIFY: " . $final_x_header,
"accept: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err)
{
//HANDLE YOUR ERROR MESSAGE HERE
dd('ERROR : ' . $err);
}
else
{
$res = json_decode($response);
if (isset($res->success) && $res->success == '1')
{
$payUrl = $res->data->instrumentResponse->redirectInfo->url;
//REDIRECT TO PHONEPE HOSTED CHECKOUT PAGE
return redirect($payUrl);
}
else
{
//HANDLE YOUR ERROR MESSAGE HERE
dd('ERROR : ' . $res);
}
}
}
PhonePe Checkout Page
Now create a function named callback in PaymentController.php, In this function we will receive code, merchantId, transactionId, amount, providerReferenceId, checksum and more
Note : You will receive data in POST Method
public function callback(Request $request)
{
if($request->code == 'PAYMENT_SUCCESS')
{
$phonepe_transaction_id = $request->transactionId;
//Transaction completed, You can add transaction details into database
}
else
{
//HANDLE YOUR ERROR MESSAGE HERE
dd('ERROR : ' .$request->code. ', Please Try Again Later.');
}
}
Related Posts
How to get Razorpay API Keys?
How to implement shift4 payment gateway in laravel?
How to implement coingate payment gateway in laravel?
How to implement razorpay refund in laravel?
How to implement razorpay in laravel?
How to get API Keys of Shift4 Payment Gateway?
How to get API Keys of Square Payment Gateway?
How to implement square payment gateway in laravel?
How to get API Keys of Coingate Payment Gateway?
How to Implement PayU in Laravel?