function done_transaction($oid, $vpnid) { $ret = order_dopayment($oid); if ($ret === false) { pay_error(CANTFINISH); die; } /// 支付成功,开通服务并显示成功信息 $sql = "SELECT * FROM service WHERE id IN (SELECT serviceid FROM `order` WHERE id={$oid})"; $res = db_query($sql); if ($res === false) { pay_error(_("Can not find service correlate to order.id={$oid}, payment token={$token}")); die; } $service = db_fetch_array($res); /// 查找对应的 VPN 帐号 $vpnid = (int) $vpnid; $vpns = db_quick_fetch('vpnaccount', "WHERE id={$vpnid}"); if (count($vpns) <= 0) { vpn_log("No vpnid {$vpnid} found for order {$oid}"); return false; } $vpn = $vpns[0]; /// 下面的代码和 account_new.php 中的代码一致 /// 3. 账户余额足够,开通帐号 vpn_renew($vpn['username'], $service['duration'], $service['radiusgroup']); /// 4. 发货(在 raidus 中设置帐号),并扣款 order_delivery($oid); return true; }
function pass_save() { global $smarty; $user = user_isonline(); $oldpass = @$_POST['oldpass']; $pass = @$_POST['loginpass']; $pass2 = @$_POST['loginpass2']; if ($pass == '') { pass_main(_('Please enter new password')); return false; } if ($pass != $pass2) { pass_main(_('New password does not match')); return false; } if (user_encrypt($oldpass) != $user['loginpass']) { pass_main(_('Current password is not correct')); return false; } $ret = user_passwd($user['id'], $pass); if ($ret !== true) { vpn_log($ret); pass_main(_("<p>{$ret}</p>" . '<p>There is an error occur, please contact us for help if you need.</p>')); return false; } $smarty->assign('tip_title', _('Successed')); $smarty->assign('tip_msg', _('Login password successfully changed')); $smarty->assign('redirect_url', 'account.php'); $smarty->display('tip.html'); }
function account_pay($name, $pass, $serviceid) { global $smarty; $user = user_isonline(); /// 如果账户余额足够,则直接扣款并继续操作;如果余额不足则显示付款页面,并在付款后继续操作 $amt = vpn_afford($serviceid, $user['email']); $services = db_quick_fetch('service', "WHERE id={$serviceid}"); if (count($services) <= 0) { vpn_log("Error: No such service id: {$serviceid}"); } $service = $services[0]; /// 创建订单 $order = null; if ($amt < 0) { $order = order_new($serviceid, abs($amt)); } else { $order = order_new($serviceid); } if ($order === false) { vpn_log("Can not create order({$serviceid}, {$amt})"); $smarty->assign('tip_title', _('An error occur')); $smarty->assign('tip_msg', _('Can not create order, please contact us for help')); $smarty->display('tip.html'); die; } /// 向 order 表中增加 VPN 帐号信息 $qname = addslashes($name); $vpns = db_quick_fetch('vpnaccount', "WHERE username='******'"); if (count($vpns) <= 0) { vpn_log("No VPN username `{$name}' in vpnaccount table"); } db_quick_update('order', "WHERE id={$order['orderid']}", array('vpnid' => $vpns[0]['id'])); if ($amt < 0) { /// 余额不足时,显示付款页面,并在付款成功后继续开通帐号操作 //$smarty->assign('amount', abs($amt)); //$smarty->assign('service', $service); $url = "order_preview.php?id={$order['orderid']}"; header("Location: {$url}"); $smarty->assign('redirect_url', $url); $smarty->assign('tip_title', _('Redirect')); $smarty->assign('tip_msg', _('Redirecting...')); $smarty->display('tip.html'); die; } /// 3. 账户余额足够,开通帐号 //print_r($name); //print_r($service); vpn_renew($name, $service['duration'], $service['radiusgroup']); /// 4. 发货(扣款) order_delivery($order['orderid']); $smarty->assign('tip_title', _('Success')); $smarty->assign('tip_msg', _('Thank you for purchase, now you can go to My Account page to view you VPN account')); $smarty->assign('redirect_url', 'account.php'); $smarty->display('tip.html'); }
/** * 发货操作,将订单标记为已发货,并从用户账户中扣除货款 */ function order_delivery($orderid) { $orderid = (int) $orderid; $orders = db_quick_fetch('order', "WHERE id={$orderid}"); if (count($orders) <= 0) { vpn_log("No such order id {$orderid}"); return false; } $order = $orders[0]; $services = db_quick_fetch('service', "WHERE id IN (SELECT serviceid FROM `order` WHERE id={$order['id']})"); if (count($services) <= 0) { vpn_log("No service correlate to order #{$order['id']}"); return false; } /// FIXME: 这里应该增加失败回滚操作 $sql1 = "UPDATE `order` SET delivered=1 WHERE id={$orderid}"; $sql2 = "UPDATE account SET balance=balance-{$services[0]['price']} WHERE id={$order['uid']}"; db_query($sql1); db_query($sql2); db_quick_update('order', "WHERE id={$orderid} AND ISNULL(paidtime)", array('paidtime' => time())); return true; }
/** * 为 $uid 用户生成一个邀请码 * * 从 INVITECODE_MINLEN 长度开始生成邀请码,如果生成的邀请码已经存在了,则生成一个更长的邀请码,直到得到在数据库中不存在的邀请码为止 * * @return 成功返回验证码,失败返回 false */ function invite_generate($uid) { $uid = (int) $uid; $code = ''; if ($uid == 0) { vpn_log('Invalid argument: $uid == 0'); return false; } /// 没人会使用 99 位长度的验证码吧 for ($len = INVITECODE_MINLEN; $len < 99; $len++) { $code = invite_randstr($len); $res = db_quick_fetch('invite', "WHERE code='{$code}'"); if (count($res) == 0) { break; } } if ($len >= 99) { vpn_log("Invite code out of length: {$len}"); return false; } /// FIXME: 要不要检查用户是否存在捏? $ts = time(); $qcode = addslashes($code); $sql = "INSERT INTO invite (code, uid, ctime, utime) VALUES ('{$qcode}', {$uid}, {$ts}, NULL)"; db_query($sql); return $code; }
$services = db_quick_fetch('service', "WHERE id IN (SELECT serviceid FROM (SELECT DISTINCT serviceid FROM `order` WHERE NOT ISNULL(paidtime) AND vpnid={$account['id']} ORDER BY id DESC LIMIT 1) AS t)"); if (count($services) <= 0) { vpn_log("Could not find correlate service id for vpnaccount id {$account['id']}"); renew_error(_('Can not renew, please contact us for help')); die; } $service = $services[0]; $amt = vpn_afford($service['id'], $user['email']); /// 开始支付过程 if ($amt <= 0) { $order = order_new($service['id'], -$amt); } else { $order = order_new($service['id']); } if ($order === false) { vpn_log("Can not get order via order_new('{$service['id']}')"); renew_error(_('Can not renew, please contact us for help')); die; } /// 创建订单是不会设置 VPNID 的,所以需要手动设置 order_setvpnid($order['orderid'], $aid); if ($amt < 0) { /// 余额不足时,显示付款页面,并在付款成功后继续开通帐号操作 //$smarty->assign('amount', abs($amt)); //$smarty->assign('service', $service); $url = "order_preview.php?id={$order['orderid']}"; header("Location: {$url}"); $smarty->assign('redirect_url', $url); $smarty->assign('tip_title', _('Redirect')); $smarty->assign('tip_msg', _('Redirecting...')); $smarty->display('tip.html');
/** * 发送一个 PayPal NVP 请求,并获取返回结果 * @param array Name Value Pair * @return array 返回的结果,N 已经转换成小写 */ function paypal_nvp_request($nvp) { $getstr = '?'; $getstr .= 'signature=' . urlencode(PAYPAL_APISIGN); $getstr .= '&user='******'&pwd=' . urlencode(PAYPAL_APIPASS); $getstr .= '&version=84.0'; foreach ($nvp as $k => $v) { $getstr .= '&' . urlencode($k) . '=' . urlencode($v); } $ch = curl_init(PAYPAL_APIURL . $getstr); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); vpn_log('Request PayPal ==> ' . PAYPAL_APIURL . $getstr); $ret = curl_exec($ch); if ($ret === false) { vpn_log('curl_exec() fail: ' . curl_error()); return false; } $arr = paypal_getstr2array($ret); return $arr; }
/** * 计算用户现有账户是否足以支付此项服务,并返回如果购买了此项服务后账户的净余额 * * @return 足够支付返回非负数,不够支付返回负数 */ function vpn_afford($serviceid, $email) { $serviceid = (int) $serviceid; $res = db_quick_fetch('service', "WHERE id={$serviceid}"); if (count($res) <= 0) { vpn_log("No such service id {$serviceid}"); return false; } $user = user_get($email); if ($user == false) { vpn_log("No such user `{$email}'"); return false; } return $user['balance'] + $user['credit'] - $res[0]['price']; }
/** * 设置用户在线 */ function user_online($email) { $sid = md5(VPNNS . (time(NULL) + rand()) . rand()); $user = user_get($email); if ($user === false) { vpn_log("Fail set user {$email} online"); return false; } cache_set("sid_{$sid}", $user, USER_SESSIONTIME); setcookie(VPNNS . 'sid', $sid, 0); return true; }