I am trying to implement the HitPay payment gateway.
I can successfully get the response from the payment request.
I am also able to complete the payment.
However, after the payment is made, I need to store the transaction details such as: Transaction ID, Transaction Status, and other relevant details.
For some reason, this part is not working as expected.
I have tried many approaches, but I am unable to identify the issue.
Here is the documentation.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>HitPay Checkout Drop-in Test Page</title>
</head>
<body>
<script src="https://hit-pay.com/hitpay.js"></script>
<script>
// Callback for successful payment
function onSuccess(data) {
console.log('onSuccess called:', data);
// Verify if valid data is received
if (!data) {
console.error('No data received in onSuccess');
const el = document.createElement('p');
el.innerHTML = 'Payment Success, but no data received.';
document.body.appendChild(el);
return;
}
// Display a success message
const el = document.createElement('p');
el.innerHTML = 'Payment Success';
document.body.appendChild(el);
// Send payment details to backend for storage
fetch('store_payment_details.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // Sending received data
})
.then((response) => response.json())
.then((response) => {
console.log('Payment details stored successfully:', response);
})
.catch((error) => {
console.error('Error storing payment details:', error);
});
}
// Callback when payment is closed
function onClose(data) {
console.log('onClose called:', data);
const el = document.createElement('p');
el.innerHTML = 'Payment Closed';
document.body.appendChild(el);
}
// Callback for errors
function onError(error) {
console.error('onError called:', error);
const el = document.createElement('p');
el.innerHTML = 'Error: ' + (error.message || error);
document.body.appendChild(el);
}
// Function to initiate payment
function onClick() {
const carttotalValue = 1; // Dynamic total value (e.g., 100 for testing)
const paymentData = {
amount: carttotalValue, // Ensure amount matches cart total
currency: 'SGD',
email: '[email protected]',
phone: '1111',
order_id: '123',
};
// Make AJAX request to backend to create the payment request
fetch('hitpay_payment_request.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(paymentData), // Send dynamic data
})
.then((response) => response.json())
.then((response) => {
const data = response.data;
console.log("data=",data);
if (data && data.id) {
// Initialize HitPay only once
if (!window.HitPay.inited) {
window.HitPay.init(
'https://securecheckout.hit-pay.com/payment-request/@curvv-tech-private-limited',
{
domain: 'hit-pay.com',
apiDomain: 'hit-pay.com',
},
{
onClose: onClose,
onSuccess: onSuccess,
onError: onError,
}
);
}
// Trigger the payment gateway toggle with the provided payment_url
window.HitPay.toggle({
paymentRequest: data.id, // Dynamic payment ID
amount: carttotalValue,
name: 'Anbu',
phone: '93500239',
});
} else {
// Handle error if no payment URL is received
console.error('Error: Payment URL not received');
}
})
.catch((error) => {
console.error('AJAX Error:', error);
});
}
</script>
<button onclick="onClick()">Pay</button>
</body>
</html>
hitpay_payment_request.php:
<?php
//hitpay_payment_request.php
header("Content-Type: application/json");
header("X-Content-Type-Options: nosniff");
$data = json_decode(file_get_contents('php://input'), true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo json_encode(["error" => "Invalid JSON payload"]);
exit;
}
// Sanitize input
$amount = filter_var($data['amount'] ?? 0, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
$currency = filter_var($data['currency'] ?? 'SGD', FILTER_SANITIZE_STRING);
$email = filter_var($data['email'] ?? '[email protected]', FILTER_VALIDATE_EMAIL);
$phone = filter_var($data['phone'] ?? '00000000', FILTER_SANITIZE_STRING);
$order_id = filter_var($data['order_id'] ?? 'ORD123456', FILTER_SANITIZE_STRING);
$requestData = [
"amount" => $amount,
"currency" => $currency,
"email" => $email,
"phone" => $phone,
"reference_number" => $order_id,
"redirect_url" => "https://domain.sg/hit-pay/hitpay_payment_success.php",
"webhook" => "https://domain.sg/hit-pay/hitpay_payment_details.php",
];
$apiKey = 'my_api_key';
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.hit-pay.com/v1/payment-requests",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode($requestData),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-BUSINESS-API-KEY: $apiKey"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
error_log("cURL Error: $err");
http_response_code(500);
echo json_encode(["error" => "cURL Error: $err"]);
} else {
$responseData = json_decode($response, true);
error_log("API Response: " . $response);
if (isset($responseData['id'])) {
echo json_encode(["data" => $responseData]);
} else {
http_response_code(500);
echo json_encode(["error" => "Invalid response from HitPay API"]);
}
}
?>
response getting:
{
"data": {
"id": "9de0c639-c986-4743-a1ae-70b998068536",
"name": null,
"email": "[email protected]",
"phone": "1111",
"amount": "1.00",
"currency": "SGD",
"is_currency_editable": false,
"status": "pending",
"purpose": null,
"reference_number": "123",
"payment_methods": [
"card",
"paynow_online"
],
"url": "https://securecheckout.hit-pay.com/payment-request/@curvv-tech-private-limited/9de0c639-c986-4743-a1ae-70b998068536/checkout",
"redirect_url": "https://domain.sg/hit-pay/hitpay_payment_success.php",
"webhook": "https://domain.sg/hit-pay/hitpay_payment_details.php",
"send_sms": false,
"send_email": false,
"sms_status": "pending",
"email_status": "pending",
"allow_repeated_payments": false,
"expiry_date": null,
"address": null,
"line_items": null,
"executor_id": null,
"created_at": "2025-01-03T14:53:59",
"updated_at": "2025-01-03T14:53:59",
"staff_id": null,
"business_location_id": null
}
}
hitpay_payment_details.php:
<?php
// hitpay_payment_deatils.php
header("Content-Type: application/json");
header("X-Content-Type-Options: nosniff");
// Include database connection
include '../rest_api/config.php';
$data = json_decode(file_get_contents("php://input"), true);
if (isset($data['payment_id'], $data['order_id'], $data['payment_status'], $data['payment_gross'], $data['currency_code'], $data['datetime'])) {
$payment_id = $data['payment_id'];
$order_id = $data['order_id'];
$payment_status = $data['payment_status'];
$payment_gross = $data['payment_gross'];
$currency_code = $data['currency_code'];
$datetime = $data['datetime'];
$stmt = $conn->prepare("INSERT INTO payments (payment_id, item_number, txn_id, payment_gross, currency_code, payment_status, datetime, is_active) VALUES (?, ?, ?, ?, ?, ?, ?, 1)");
$stmt->bind_param("sssssss", $payment_id, $order_id, $payment_id, $payment_gross, $currency_code, $payment_status, $datetime);
if ($stmt->execute()) {
echo json_encode(["status" => "success", "message" => "Payment details inserted successfully."]);
} else {
echo json_encode(["status" => "error", "message" => "Failed to insert payment details."]);
}
$stmt->close();
} else {
echo json_encode(["status" => "error", "message" => "Invalid input data."]);
}
?>
hitpay_payment_success.php
<?php
//hitpay_payment_success
// Database connection
include '../rest_api/config.php';
// Get query parameters
$order_id = $_GET['order_id'] ?? null; // Retrieve order_id
$paymentRequestId = $_GET['payment_request_id'] ?? null;
$status = $_GET['status'] ?? null;
$userIp = $_SERVER['REMOTE_ADDR'];
if ($paymentRequestId && $status && $order_id) {
// Insert into database
$stmt = $conn->prepare("INSERT INTO payment_redirect_logs (order_id, payment_request_id, status, user_ip) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssss", $order_id, $paymentRequestId, $status, $userIp);
$stmt->execute();
$stmt->close();
echo $status === 'completed' ? "<h1>Payment Successful</h1>" : "<h1>Payment Failed</h1>";
} else {
echo "<h1>Invalid Request</h1>";
}
?>