Files
2026-08-20 18:39:37 +07:00

234 lines
5.8 KiB
PHP

<?php
//https://manjapro.net/paymentlink/post/winpay_report.php?action=transactions&from=2026-06-01&to=2026-06-5
//https://manjapro.net/paymentlink/post/winpay_report.php?action=balance&accountNo=1747356
//https://manjapro.net/paymentlink/post/winpay_report.php?winpay_report.php?action=statement&accountNo=XXX&token=XXX
require __DIR__ . '/../../config/connect.php';
$partnerId = "bb3736e5-eb14-4e7f-b62d-10db909db794";
$baseUrl = "https://snap.winpay.id";
$privateKeyPath = __DIR__ . "/private_key_prod.pem";
// =========================
// HELPER
// =========================
function getTimestamp()
{
return date("c");
}
// 🔥 FORMAT ISO8601 AMAN
function formatISO8601($date, $end = false)
{
$time = $end ? "23:59:59" : "00:00:00";
return date("Y-m-d\\T{$time}P", strtotime($date));
}
// 🔥 VALIDASI RANGE MAX 1 BULAN
function validateRange($from, $to)
{
$start = strtotime($from);
$end = strtotime($to);
if (($end - $start) > (31 * 24 * 60 * 60)) {
die(json_encode([
"error" => "Range maksimal 1 bulan"
], JSON_PRETTY_PRINT));
}
}
function generateSignature($method, $endpoint, $body, $timestamp, $privateKeyPath, &$debug = [])
{
$hashedBody = strtolower(bin2hex(hash('sha256', $body, true)));
$stringToSign = implode(":", [
$method,
$endpoint,
$hashedBody,
$timestamp
]);
$privateKey = openssl_pkey_get_private(file_get_contents($privateKeyPath));
if (!$privateKey) {
die(json_encode(["error" => "Private key tidak valid"]));
}
openssl_sign($stringToSign, $signature, $privateKey, OPENSSL_ALGO_SHA256);
$signatureBase64 = base64_encode($signature);
// DEBUG
$debug['string_to_sign'] = $stringToSign;
$debug['hashed_body'] = $hashedBody;
$debug['signature'] = $signatureBase64;
return $signatureBase64;
}
// 🔥 CURL DETAIL
function curlPost($url, $headers, $body)
{
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_HEADER => true
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$responseHeader = substr($response, 0, $headerSize);
$responseBody = substr($response, $headerSize);
$error = curl_error($ch);
curl_close($ch);
return [
"http_code" => $httpCode,
"header" => $responseHeader,
"body" => $responseBody,
"error" => $error
];
}
function hitWinpay($method, $endpoint, $body, $baseUrl, $partnerId, $privateKeyPath)
{
$timestamp = getTimestamp();
$externalId = time() . rand(1000, 9999);
$jsonBody = json_encode($body, JSON_UNESCAPED_SLASHES);
$signature = generateSignature(
$method,
$endpoint,
$jsonBody,
$timestamp,
$privateKeyPath
);
$headers = [
"Content-Type: application/json",
"X-TIMESTAMP: $timestamp",
"X-SIGNATURE: $signature",
"X-PARTNER-ID: $partnerId",
"X-EXTERNAL-ID: $externalId",
"CHANNEL-ID: WEB"
];
$res = curlPost($baseUrl . $endpoint, $headers, $jsonBody);
// 🔥 kalau curl error
if (!empty($res['error'])) {
return json_encode([
"status" => false,
"error" => $res['error']
]);
}
// 🔥 return PURE response dari Winpay
return $res['body'];
}
// =========================
// ROUTER
// =========================
$action = $_GET['action'] ?? '';
// =========================
// BALANCE
// =========================
if ($action === 'balance') {
$accountNo = $_GET['accountNo'] ?? '';
$body = [
"partnerReferenceNo" => uniqid(),
"accountNo" => $accountNo,
"balanceTypes" => ["Transaction", "Settlement"]
];
echo hitWinpay("POST", "/v1.0/balance-inquiry", $body, $baseUrl, $partnerId, $privateKeyPath);
exit;
}
// =========================
// TRANSACTIONS
// =========================
if ($action === 'transactions') {
$fromRaw = $_GET['from'] ?? date('Y-m-01');
$toRaw = $_GET['to'] ?? date('Y-m-d');
$from = formatISO8601($fromRaw);
$to = formatISO8601($toRaw, true);
validateRange($from, $to);
$page = $_GET['page'] ?? 1;
$limit = $_GET['limit'] ?? 100;
$body = [
"partnerReferenceNo" => "REF" . time(),
"fromDateTime" => $from,
"toDateTime" => $to,
"pageSize" => (int)$limit,
"pageNumber" => (int)$page
];
echo hitWinpay("POST", "/v1.0/transaction-history-list", $body, $baseUrl, $partnerId, $privateKeyPath);
exit;
}
// =========================
// STATEMENT
// =========================
if ($action === 'statement') {
$accountNo = $_GET['accountNo'] ?? '';
$token = $_GET['token'] ?? '';
$fromRaw = $_GET['from'] ?? date('Y-m-01');
$toRaw = $_GET['to'] ?? date('Y-m-d');
$from = formatISO8601($fromRaw);
$to = formatISO8601($toRaw, true);
validateRange($from, $to);
$page = $_GET['page'] ?? 1;
$limit = $_GET['limit'] ?? 10;
$body = [
"partnerReferenceNo" => "REF" . time(),
"bankCardToken" => $token,
"accountNo" => $accountNo,
"fromDateTime" => $from,
"toDateTime" => $to,
"additionalInfo" => [
"pageSize" => (string)$limit,
"pageNumber" => (string)$page
]
];
echo hitWinpay("POST", "/v1.0/bank-statement", $body, $baseUrl, $partnerId, $privateKeyPath);
exit;
}
// =========================
// DEFAULT
// =========================
echo json_encode([
"status" => false,
"message" => "Invalid action",
"available" => ["balance","transactions","statement"]
], JSON_PRETTY_PRINT);