<?php
namespace common\pay\huayin;

class PayUtils
{
    /**
     *功能：华银个人网银支付接口
     *版本：3.0
     *日期：2017-06-30
     *说明：
     *以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,
     *并非一定要使用该代码。该代码仅供学习和研究华银接口使用，仅为提供一个参考。
     * @param array $data
     * @param $merchant_private_key
     * @return string
     */
    public static function makeSign($data, $merchant_private_key)
    {
        ///////////////////////////  初始化接口参数  //////////////////////////////
        /**
         * 接口参数请参考华银网银支付文档，除了sign参数，其他参数都要在这里初始化
         */

        /////////////////////////////   参数组装  /////////////////////////////////
        /**
         * 除了sign_type参数，其他非空参数都要参与组装，组装顺序是按照a~z的顺序，下划线"_"优先于字母
         */
        $signStr = "";
        ksort($data);
        foreach ($data as $key => $value) {
            if ($key == "sign" || $key == "sign_type" || $value === null || $value === "") {
                continue;
            }
            $value = strval($value);
            $signStr .= "{$key}={$value}&";
        }
        $signStr = rtrim($signStr, '&');

        /////////////////////////////   获取sign值（RSA-S加密）  /////////////////////////////////
        if (strpos($merchant_private_key, "file://") === false) {
            if (strpos($merchant_private_key, "-----BEGIN PRIVATE KEY-----") === false) {
                $merchant_private_key_lines = [];
                $merchant_private_key_lines[] = "-----BEGIN PRIVATE KEY-----";
                for ($index = 0, $len = strlen($merchant_private_key); $index < $len; $index += 64) {
                    $merchant_private_key_lines[] = substr($merchant_private_key, $index, 64);
                }
                $merchant_private_key_lines[] = "-----END PRIVATE KEY-----";
                $merchant_private_key = implode("\n", $merchant_private_key_lines);
            }
        }
        $merchant_private_key = openssl_get_privatekey($merchant_private_key);
        openssl_sign($signStr, $sign_info, $merchant_private_key, OPENSSL_ALGO_MD5);
        $sign = base64_encode($sign_info);
        return $sign;
    }

    /**
     *功能：华银个人网银支付异步通知接口
     *版本：3.0
     *日期：2017-06-30
     *说明：
     *以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,
     *并非一定要使用该代码。该代码仅供学习和研究华银接口使用，仅为提供一个参考。
     */
    public static function checkSign($data, $dinpay_public_key)
    {
        //////////////////////////	接收华银返回通知数据  /////////////////////////////////
        /**
         * 获取订单支付成功之后，华银通知服务器以post方式返回来的订单通知数据，参数详情请看接口文档,
         */

        /////////////////////////////   参数组装  /////////////////////////////////
        /**
         * 除了sign_type dinpaySign参数，其他非空参数都要参与组装，组装顺序是按照a~z的顺序，下划线"_"优先于字母
         */
        $dinpaySign = isset($data["sign"]) ? base64_decode($data["sign"]) : "";
        if (isset($data['order_amount'])) {
            $data['order_amount'] = number_format($data['order_amount'], 2, '.', '');
        }
        $signStr = "";
        ksort($data);
        foreach ($data as $key => $value) {
            if ($key == "sign" || $key == "sign_type" || $value === null || $value === "") {
                continue;
            }
            $value = strval($value);
            $signStr .= "{$key}={$value}&";
        }
        $signStr = rtrim($signStr, '&');

        /////////////////////////////   RSA-S验证  /////////////////////////////////
        if (strpos($dinpay_public_key, "file://") === false) {
            if (strpos($dinpay_public_key, "-----BEGIN PUBLIC KEY-----") === false) {
                $dinpay_public_key_lines = [];
                $dinpay_public_key_lines[] = "-----BEGIN PUBLIC KEY-----";
                for ($index = 0, $len = strlen($dinpay_public_key); $index < $len; $index += 64) {
                    $dinpay_public_key_lines[] = substr($dinpay_public_key, $index, 64);
                }
                $dinpay_public_key_lines[] = "-----END PUBLIC KEY-----";
                $dinpay_public_key = implode("\n", $dinpay_public_key_lines);
            }
        }
        $dinpay_public_key = openssl_get_publickey($dinpay_public_key);
        $flag = openssl_verify($signStr, $dinpaySign, $dinpay_public_key, OPENSSL_ALGO_MD5);
        ///////////////////////////   响应“SUCCESS” /////////////////////////////
        if ($flag) {
            return true;
        } else {
            return false;
        }
    }
}