<?php

/**
 * 开启支付
 */

/**
 * 产生 招商银行一网通 商户校验码
 * @param  [type]  $strKey          [商户密钥]
 * @param  [type]  $strDate         [订单日期]
 * @param  [type]  $strBranchID     [开户分行号]
 * @param  [type]  $strCono         [商户号]
 * @param  [type]  $strBillNo       [订单号]
 * @param  [type]  $strAmount       [订单金额]
 * @param  [type]  $strMerchantPara [商户自定义参数]
 * @param  [type]  $strMerchantUrl  [商户接受通知的URL]
 * @param  [type]  $strPayerID      [付款方用户标识。用来唯一标识商户的一个用户。长度限制为40字节以内。]
 * @param  [type]  $strPayeeID      [收款方的用户标识。生成规则同上。不要求商户提供用户的注册名称，但需要保证一个用户对应一个UserID。]
 * @param  [type]  $strClientIP     [商户取得的客户端IP，如果有多个IP用逗号','分隔。长度限制为64字节。]
 * @param  integer $strGoodsType [商品类型编码，长度限制为8字节。]
 * @param  string $strReserved [保留字段，长度限制为1024字节。]
 * @return [type]                   [商户校验码]
 */
function genMerchantCode($param)
{
    $str = '';
    if (!empty($param['strClientIP'])) {
        $str .= '<$ClientIP$>' . $param['strClientIP'] . '</$ClientIP$>';
    }
    if (!empty($param['strGoodsType'])) {
        $str .= '<$GoodsType$>' . $param['strGoodsType'] . '</$GoodsType$>';
    }
    if (!empty($param['strReserved'])) {
        $str .= '<$Reserved$>' . $param['strReserved'] . '</$Reserved$>';
    }

    $rnd = mt_rand();
    $str = $rnd . '|' . $param['strPayerID'] . '<$CmbSplitter$>' . $param['strPayeeID'] . $str;
    $rc4Key = md5($param['strKey']);
    $rc4Key = pack('H*', $rc4Key);
    $rc4Val = openssl_encrypt($str, "RC4", $rc4Key, true);
    $rc4Val = base64_encode($rc4Val);
    $rc4Val = str_replace('+', '*', $rc4Val);

    $sha1Val = $param['strKey'] . $rc4Val . $param['strDate'] . $param['strBranchID'] . $param['strCono'] . $param['strBillNo'] . $param['strAmount'] . $param['strMerchantPara'] . $param['strMerchantUrl'];
    $sha1Val = sha1($sha1Val);
    // $sha1Val = bin2hex($sha1Val);

    return "|{$rc4Val}|{$sha1Val}";
}

$time = time();
$date = date('Ymd', $time);
$bill_no = mt_rand(1000000000, 9999999999);
$payprice = "0.01";
$user_id = 1234;

$config['mch_mo'] = 'P0021553';
$config['branch_id'] = '0021';
$config['co_no'] = '000100';
$config['str_key'] = '';
$config['pay_url'] = 'http://61.144.248.29:801/netpayment/BaseHttp.dll?PrePayEUserP';
$config['result_url'] = 'http://127.0.0.1/pay/cmb-result';
$config['sign_url'] = 'http://127.0.0.1/pay/cmb-sign';

//商户校验码 数据
$seq = $date . $bill_no;
$param = [
    'strKey' => $config['str_key'],
    'strDate' => $date,
    'strBranchID' => $config['branch_id'],
    'strCono' => $config['co_no'],
    'strBillNo' => $bill_no,
    'strAmount' => $payprice,
    'strMerchantPara' => "oid={$id}",
    'strMerchantUrl' => $config['result_url'],
    'strPayerID' => (string) $user_id,
    'strPayeeID' => '',
    'strClientIP' => '127.0.0.1',
    'strGoodsType' => '54011600',
    'strReserved' => join('', [
        '<Protocol>',
        '<PNo>' . $user_id . '</PNo>',
        '<TS>' . date('YmdHis', $time) . '</TS>',
        '<MchNo>' . $config['mch_mo'] . '</MchNo>',
        '<Seq>' . $seq . '</Seq>',
        '<URL>' . $config['sign_url'] . '</URL>',
        '<Para>' . "id={$id}|seq={$$seq}" . '</Para>',
        '</Protocol>',
    ]),
];

//提交 数据
$data = [
    'BranchID' => $config['branch_id'],
    'CoNo' => $config['co_no'],
    'BillNo' => $bill_no,
    'Amount' => $payprice,
    'Date' => $date,
    'ExpireTimeSpan' => '30',
    'MerchantUrl' => $config['result_url'],
    'MerchantPara' => "oid={$id}",
    'MerchantCode' => genMerchantCode($param),
    'MerchantRetUrl' => "http://127.0.0.1/success",
    'MerchantRetPara' => "id={$id}|price={$payprice}",
];

echo "<pre>";
var_dump($param, $data);
echo "<\pre>";

echo '正在努力跳转到一网通支付哦~';
echo "<form action='{$config['pay_url']}' method='post' name='fm'>";
foreach ($data as $k => $v) {
    echo "<input type='hidden' name='" . htmlentities($k) . "' value='" . htmlentities($v) . "'/>";
}
echo "<input type='submit' value='付款'/>";
echo "</form>";
echo <<<END
<script language="JavaScript">
//    document.fm.submit();
</script>
END;

die();

/**
 * 签约回调验签部分
 */

//测试环境公钥
$pub_key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZs4l8Ez3F4MG0kF7RRSL+pn8MmxVE3nfdXzjx6d3rH8IfDbNvNRLS0X0b5iJnPyFO8sbbUo1Im4zX0M8XA0xnnviGyn5E6occiyUXJRgokphWb5BwaYdVhnLldctdimHoJTk3NFEQFav3guygR54i3tymrDc8lWtuG8EczVu8FwIDAQAB';

//post 接收过来的数据
$post = [
    'RequestData' => '{\"NTBNBR\":\"P0021553\",\"TRSCOD\":\"BKQY\",\"DATLEN\":\"630\",\"COMMID\":\"406Y608120000067xANANMDRHCZNFUCMKJHNOMR\",\"BUSDAT\":\"PHhtbD48Y3VzdF9hcmdubz4yNjU5NDwvY3VzdF9hcmdubz48cmVzcGNvZD5DTUJNQjk5PC9yZXNwY29kPjxyZXNwbXNnPuetvue9suWNj+iuruaIkOWKnzwvcmVzcG1zZz48bm90aWNlcGFyYT5vaWQ9MjQzNjA1fHNlcT0yMDE2MDgxMjI2NTk0PC9ub3RpY2VwYXJhPjxjdXN0X25vLz48Y3VzdF9waWR0eT4xPC9jdXN0X3BpZHR5PjxjdXN0X29wZW5fZF9wYXk+TjwvY3VzdF9vcGVuX2RfcGF5PjxjdXN0X3BpZF92PjQwOTQ4ODUyNTUzMDI1NDU2NzA0MDE3NTQ3MjA3NTwvY3VzdF9waWRfdj48L3htbD4=\",\"SIGTIM\":\"201608121126080505\",\"SIGDAT\":\"zipaFy/o9+0JoHvgWGHJz7ZYFHVP4Sb34GMeyZf9P4nHGZcG2W01iMwbXwm5honNprdXmx4M8qhRe9oj0D97QEZSsZvcwJNQwXO7Q6Hp7GMRiFVAOHIdThC0NpZNNirkPsIiopYbQ8XjRq8PkVZQVeD9UgMghFuYMcKlCpqUuT8=\"}',
];
var_dump($pub_key, $post);
$post['RequestData'] = str_replace('\"', '"', $post['RequestData']);
$post = json_decode($post['RequestData'], true);
var_dump($post);

//参加验签的参数信息
$accept_param = [
    'NTBNBR' => '',
    'TRSCOD' => '',
    'COMMID' => '',
    'SIGTIM' => '',
    'BUSDAT' => '',
];

//检查参数
$accept_str = '';

foreach ($accept_param as $k => $v) {
    if (empty($post[$k])) {
        continue;
    }
    if (!empty($accept_str)) {
        $accept_str .= '&';
    }
    $accept_str .= "{$k}={$post[$k]}";
}

var_dump($accept_param);
var_dump($accept_str);

//解析数据
$bus_dat = base64_decode(str_replace(' ', '+', $post['BUSDAT']));
var_dump($bus_dat);

$sig_dat = base64_decode(str_replace(' ', '+', $post['SIGDAT']));
var_dump($sig_dat);

$bus_arr = \app\common\Tools::FromXml($bus_dat);
var_dump($bus_arr);

//处理证书
$pem = chunk_split($pub_key, 64, "\n");
var_dump($pem);

$pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n";
var_dump($pem);

$pkid = openssl_pkey_get_public($pem);
var_dump($pkid);
if (empty($pkid)) {
    die('获取 pkey 失败');
}

//验证
var_dump($accept_str, $sig_dat, $pkid);
$ok = openssl_verify($accept_str, $sig_dat, $pkid, OPENSSL_ALGO_SHA1);
var_dump($ok);
die();

/**
 * 支付回调验签
 */
//拿到 key
$pub_key = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALuUIwMGhvbpCwYzKCMzvSMQiLAAj5y74cN09N1TXVONPWhvLWkuzEPSd1ogPJLWiVyEG7gEIBT3zTlCV+NMou0CAwEAAQ==';

//get获取的字串
$str = 'Succeed=Y&CoNo=000100&BillNo=2071005883&Amount=0.01&Date=20160811&MerchantPara=oid=243582&Msg=00210001002016081116281199300000000010&Signature=186|9|124|76|8|135|219|250|199|223|100|218|66|244|45|229|248|81|173|49|133|94|32|70|103|198|164|70|164|234|152|123|21|156|91|44|8|163|226|214|244|249|186|64|170|138|147|241|106|120|211|214|41|69|127|223|165|13|131|49|75|59|187|30|';

$flag = '&signature=';
$index = stripos($str, $flag);
if ($index === false) {
    return false;
}

$params = substr($str, 0, $index);
$signAsc = substr($str, $index + strlen($flag));
$signAsc = explode("|", $signAsc);
$sign = '';
foreach ($signAsc as $v) {
    if ($v ==='') {
        continue;
    }
    $sign .= chr($v);
}

$pk = chunk_split($pub_key, 64, "\n");
$pk = "-----BEGIN PUBLIC KEY-----\n{$pk}-----END PUBLIC KEY-----\n";

$pkid = openssl_pkey_get_public($pk);

// var_dump($pkFile, $pkBase64, $sign, $pk, $pkid);

$ok = openssl_verify($params, $sign, $pkid, OPENSSL_ALGO_SHA1);
openssl_free_key($pkid);

//结果
var_dump($ok);
