<%@page import="java.util.Enumeration"%>
<%@page import="java.security.MessageDigest"%>
<%@page import="java.security.NoSuchAlgorithmException"%>
<%@page import="java.util.zip.Checksum"%>
<%@page import="java.text.DateFormat"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.util.Date"%>
<%@page import="java.security.MessageDigest"%>
<%@page import="org.json.JSONObject"%>
<%@page import="javax.crypto.spec.IvParameterSpec"%>
<%@page import="javax.crypto.spec.SecretKeySpec"%>
<%@page import="javax.crypto.Cipher"%>
<%@page import="java.util.Base64"%>
<%@page import="java.nio.charset.StandardCharsets"%>
<%@page import="java.security.MessageDigest"%>
<%@page import="java.util.zip.CRC32"%>

<%@page contentType="text/html" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8">
	<title>Airpay Payment Gateway</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="description" content="">
	<meta name="author" content="">
	<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,700;1,600&family=Roboto:wght@300;400;700&display=swap"
		rel="stylesheet">
	<link type="text/css" rel="stylesheet" href="style.css">
</head>
<style>
    table {
        border-collapse: collapse;
        width: 50%;
    }
    th, td {
        text-align: left;
        padding: 8px;
    }
    .tdfail {
        color: red;
    }
    .tdsuccess {
        color: green;
    }
</style>
<body>
    <div class="wrapper">
        <div class="contentbody">
            <div class="lside">
                <div class="lsidewrap">
                    <div class="logo"><img src="airpay-text-wh.svg"></div>
                    <div class="coverimg"><img src="coverimg.png"></div>
                </div>
            </div>
            <div class="rside">
                <div class="formwrap container-fluid">

<%! 
    // Decrypt function must be declared in a declaration block
    public String decrypt(String requestData, String secretKey) throws Exception {
        // Extract the initialization vector (IV) and encrypted data
        byte[] iv = requestData.substring(0, 16).getBytes(StandardCharsets.UTF_8);
        String encryptedData = requestData.substring(16);

        // Prepare the IV and the secret key
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");

        // Initialize the cipher for AES-256-CBC decryption
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);

        // Decode the Base64-encoded string and decrypt it
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));

        // Convert decrypted bytes to a string
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }
%>

<%
    String Username = application.getInitParameter("UserName");
    String Password = application.getInitParameter("Password");

    String sErrorMSG = "";
    String mercid = application.getInitParameter("MercId");
    String combinedString = Username + "~:~" + Password;

    // Compute MD5 hash
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(combinedString.getBytes());
    byte[] digest = md.digest();

    // Convert the byte array to a hexadecimal string
    StringBuilder sb = new StringBuilder();
    for (byte b : digest) {
        sb.append(String.format("%02x", b & 0xff));
    }
    String secretKey = sb.toString();
    String response_data = request.getParameter("response");

    // Decrypt the response data
    String decryptdata = decrypt(response_data, secretKey);
    if (decryptdata == null || decryptdata.isEmpty()) {
        sErrorMSG = "Invalid response";
    } else {
        JSONObject decodedJson = new JSONObject(decryptdata);
        JSONObject dataObject = decodedJson.getJSONObject("data");

        String transid = dataObject.getString("orderid");
        String apTransactionID = dataObject.getString("ap_transactionid");
        String amount = dataObject.getString("amount");             
        String transtatus = "";
        try {
            transtatus = dataObject.getString("transaction_status"); 
        } catch (org.json.JSONException e) {
            transtatus = String.valueOf(dataObject.get("transaction_status")); 
        }
        
        String message = "";
        if ("402".equals(transtatus)) {
            message = "TRANSACTION CANCELLED";
        }
        else {
            message = dataObject.getString("message");
        }
        String customvar = dataObject.optString("custom_var", "");

        // Secure hash is a long, handle it appropriately
        long securehash = dataObject.getLong("ap_securehash");

        // Instead of isEmpty, check if the values are null or empty
        if (transid == null || transid.isEmpty() || 
            apTransactionID == null || apTransactionID.isEmpty() || 
            amount == null || amount.isEmpty() || 
            transtatus == null || transtatus.isEmpty()) {
            sErrorMSG = "<tr><td>Variable(s) " + (transid.isEmpty() ? "TRANSACTIONID " : "") + 
                        (apTransactionID.isEmpty() ? "APTRANSACTIONID " : "") + 
                        (amount.isEmpty() ? "AMOUNT " : "") + 
                        (transtatus.isEmpty() ? "TRANSACTIONSTATUS " : "") +  
                        "is/are empty.</td></tr>";
        } else {
            String AP_SECUREHASH_data = transid + ":" + apTransactionID + ":" + amount + ":" + transtatus + ":" + message + ":" + mercid + ":" + Username;
            String customer_vpa = "";
            if (request.getParameter("CHMOD") != null && request.getParameter("CHMOD").equalsIgnoreCase("upi") && application.getInitParameter("KitVersion").equalsIgnoreCase("V3")) {
                customer_vpa = ":" + request.getParameter("CUSTOMERVPA");
            }

            AP_SECUREHASH_data += customer_vpa;

            // Compute CRC32 hash and convert to unsigned integer
            CRC32 crc32 = new CRC32();
            crc32.update(AP_SECUREHASH_data.getBytes());
            long merchant_secure_hash = crc32.getValue();
            String merchantSecureHashString = String.valueOf(merchant_secure_hash);

            // Compare the hashes and append an error message if they don't match
            if (securehash != merchant_secure_hash) {
                sErrorMSG = "SECURE HASH MISMATCH";
            }
        }

        // Display the transaction details based on the transaction status
        int transactionStatus = Integer.parseInt(transtatus);

        if (transactionStatus == 200) {
%>
        <table>
            <tr><td class="tdsuccess"><b>SUCCESS TRANSACTION</b></td></tr>
        </table>
        <table>
            <tr><td><b>Variable Name</b></td><td><b>Value</b></td></tr>
            <tr><td>TRANSACTIONID:</td><td> <%= transid %></td></tr>
            <tr><td>APTRANSACTIONID:</td><td> <%= apTransactionID %></td></tr>
            <tr><td>AMOUNT:</td><td> <%= amount %></td></tr>
            <tr><td>TRANSACTIONSTATUS:</td><td> <%= transtatus %></td></tr>
            <tr><td>MESSAGE:</td><td> <%= message %></td></tr>
            <tr><td>CUSTOMVAR:</td><td> <%= customvar %></td></tr>
        </table>
        <!-- Process Successful transaction -->
<%
        } else {
%>
        <table>
            <tr><td class="tdfail"><b>FAILED TRANSACTION</b></td></tr>
        </table>
        <table>
            <tr><td><b>Variable Name</b></td><td><b>Value</b></td></tr>
            <tr><td>TRANSACTIONID:</td><td> <%= transid %></td></tr>
            <tr><td>APTRANSACTIONID:</td><td> <%= apTransactionID %></td></tr>
            <tr><td>AMOUNT:</td><td> <%= amount %></td></tr>
            <tr><td>TRANSACTIONSTATUS:</td><td> <%= transtatus %></td></tr>
            <tr><td>MESSAGE:</td><td> <%= message %></td></tr>
            <tr><td>CUSTOMVAR:</td><td> <%= customvar %></td></tr>
        </table>
        <!-- Process Failed transaction -->
<%
        }
    }
%>

                </div>
            </div>
        </div>
    </div>
</body>
</html>
