QuickPay Integration in Laravel PHP

Amna Iqbal
4 min readJun 1, 2024

Hello Guys! I recently implement QuickPay payment integration in Laravel Php. So my backend is in Laravel , and frontend app is in flutter. So, I was looking for some tutorial or anything but couldn’t find it.. So, here it is for someone who are trying to find it’s integration.

First of all , you have to made a merchant account on Quickpay. Set it up and turn on the test mode, so you can test without losing money.

Then in your Laravel project you have to run.

composer require quickpay/quickpay-php

I made the code according to me, Like I want to provide the link of the payment window each time the function is called.

 public function payment(Request $request)
{
// Get QuickPay API key from environment variable
$apiKey = env('QUICKPAY_API_KEY');
if (!$apiKey) {
return response()->json(['error' => 'API key is missing.'], 500);
}

// Log the API key to ensure it's being retrieved correctly (for debugging, remove in production)
\Log::info('Using QuickPay API key: ' . $apiKey);

try {
// Get the payment details from the request if applicable
// Adjust the amount as per your requirement, assuming the smallest currency unit
$amount = $request->input('amount', 0); // Default to 0 if not provided
$currency = 'DKK';
$order_id = uniqid(); // Generate a unique order ID

// Create a cURL instance for creating the payment
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.quickpay.net/payments',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_HTTPHEADER => [
'Accept-Version: v10',
'Accept: application/json',
'Authorization: Basic ' . base64_encode(':' . $apiKey)
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'order_id' => $order_id,
'currency' => $currency
])
]);

// Execute the request
$paymentResponseData = curl_exec($ch);
if (curl_errno($ch)) {
throw new \Exception(curl_error($ch), curl_errno($ch));
}

// Get the response status code
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($responseCode !== 200 && $responseCode !== 201) {
return response()->json(['error' => 'Failed to create payment.'], $responseCode);
}

// Decode the payment response
$paymentResponse = json_decode($paymentResponseData, true);

// Log the payment response to understand its structure
\Log::info('Payment response', ['response' => $paymentResponse]);

// Extract the payment ID
$paymentId = $paymentResponse['id'] ?? null;
if (!$paymentId) {
return response()->json(['error' => 'Payment ID not found in response.'], 500);
}

// Generate the continue URL with the payment ID
$continueUrl = url('/') . '?paymentId=' . $paymentId;

// Create a cURL instance for generating the payment link
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.quickpay.net/payments/' . $paymentId . '/link',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_HTTPHEADER => [
'Accept-Version: v10',
'Accept: application/json',
'Authorization: Basic ' . base64_encode(':' . $apiKey)
],
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => http_build_query([
'amount' => $amount,
'continue_url' => $continueUrl,
'cancel_url' => url('/payment_cancel')
])
]);

// Execute the request
$linkResponseData = curl_exec($ch);
if (curl_errno($ch)) {
throw new \Exception(curl_error($ch), curl_errno($ch));
}

// Get the response status code
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($responseCode !== 200 && $responseCode !== 201) {
return response()->json(['error' => 'Failed to generate payment link.'], $responseCode);
}

// Decode the link response
$linkResponse = json_decode($linkResponseData, true);

// Log the link response to understand its structure
\Log::info('Link response', ['response' => $linkResponse]);

// Extract the payment link URL
$paymentLinkUrl = $linkResponse['url'] ?? null;
if (!$paymentLinkUrl) {
return response()->json(['error' => 'Payment link URL not found in response.'], 500);
}

// Return the payment link URL in the response
return response()->json(['payment_link' => $paymentLinkUrl]);
} catch (\Exception $e) {
\Log::error('Exception in payment', ['message' => $e->getMessage()]);
return response()->json(['error' => $e->getMessage()], 500);
}
}

This is the code for creating payment link each time. The api key, which you will get from the Integration tab in quickpay merchant dashboard.

here’s we on continue url , is getting the payment_id of the payment that is made by that link. Using that id we will get the info of the payment.
Here’s the function for that :

public function getPaymentDetails($paymentId, $X, $Y)
{
$apiKey = env('QUICKPAY_API_KEY');
if (!$apiKey) {
return response()->json(['error' => 'API key is missing.'], 500);
}

$ch = curl_init();
try {
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.quickpay.net/payments/' . $paymentId,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_HTTPHEADER => [
'Accept-Version: v10',
'Accept: application/json',
'Authorization: Basic ' . base64_encode(':' . $apiKey)
],
CURLOPT_CUSTOMREQUEST => 'GET'
]);

$paymentDetailsData = curl_exec($ch);
if (curl_errno($ch)) {
throw new \Exception(curl_error($ch), curl_errno($ch));
}

$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($responseCode !== 200) {
throw new \Exception("Failed to retrieve payment details. HTTP status code: " . $responseCode);
}

$paymentDetails = json_decode($paymentDetailsData, true);

// Log the full payment details for debugging
\Log::info('Payment details response', ['response' => $paymentDetails]);

// Example check assuming payment details are not nested under 'payment_details'
if (!isset($paymentDetails['ulid'])) {
throw new \Exception('Necessary payment details keys not found in response');
}

// Extract relevant data
$paymentData = [
'payment_id' => $paymentDetails['id'],
'X' => $X,
'Y' => $Y,
'currency' => $paymentDetails['currency'],
'card_type' => $paymentDetails['metadata']['brand'],
'card_last_no' => $paymentDetails['metadata']['last4'],
'amount' => $paymentDetails['link']['amount'] // Assuming this is correct
];

$newPayment = new Payment($paymentData);
if (!$newPayment->save()) {
throw new \Exception('Failed to save new payment');
}

\Log::info('New payment saved successfully', ['payment_id' => $newPayment->payment_id]);
return response()->json([
'success' => true,
'data' => $newPayment
]);

} catch (\Exception $e) {
\Log::error('Exception in getPaymentDetails', ['message' => $e->getMessage()]);
return response()->json(['error' => $e->getMessage()], 500);
} finally {
curl_close($ch); // Ensure cURL resource is always freed
}
}

I am doing some extra thing, Like extracting some information which is totally useable, and is not threat to anyone’s card, and saving it to my database , so user can see the details of the payment.

I hope this is helpful if you are looking for some information on Quickpay, integration.

--

--

Amna Iqbal

Computer Engineer | Android Developer | Web Developer