/** * 提交支付信息的接口. * * @param array 提交信息的数组 * * @return mixed false or null * //TODO it_b_pay 超时时间传递 \需商户申请开通 * //TODO token 支付宝快捷登陆令牌 \需商户申请开通 */ public function dopay($params, &$msg) { $mer_id = $this->getConf('mer_id', __CLASS__); $mer_key = $this->getConf('mer_key', __CLASS__); if (base_mobiledetect::is_mobile() && $this->getConf('compatible_wap', __CLASS__) == 'true') { $this->add_field('service', 'alipay.wap.create.direct.pay.by.user'); } else { $this->add_field('service', 'create_direct_pay_by_user'); } $this->add_field('out_trade_no', $params['bill_id']); //支付单据ID $this->add_field('partner', $mer_id); $this->add_field('seller_id', $mer_id); $this->add_field('payment_type', 1); $this->add_field('total_fee', number_format($params['money'], 2, '.', '')); $this->add_field('return_url', $this->callback_url); $this->add_field('notify_url', $this->notify_url); $this->add_field('subject', $params['subject'] ? $params['subject'] : $params['order_id']); $this->add_field('_input_charset', 'utf-8'); $this->add_field('sign', $this->_get_mac($mer_key)); $this->add_field('sign_type', 'MD5'); if ($this->is_fields_valiad()) { // Generate html and send payment. //echo "<textarea>";//DEBUG //echo __CLASS__; //echo 'id:'.$mer_id; //echo 'key:'.$mer_key; echo $this->get_html(); //echo "</textarea>";//DEBUG exit; } else { $msg = '支付数据签名失败!'; return false; } }
public function handle($request, Clousure $next) { $wapIsOpen = app::get('sysconf')->getConf('sysconf_setting.wap_isopen'); if (base_mobiledetect::isMobile() && $_COOKIE['browse'] != 'pc' && $wapIsOpen) { return redirect::route('topm'); } return $next($request); }
/** * 提交支付信息的接口. * * @param array 提交信息的数组 * * @return mixed false or null */ public function dopay($params, &$msg) { $appid = trim($this->getConf('appid', __CLASS__)); // 公众号ID $mch_id = trim($this->getConf('mch_id', __CLASS__)); //商户号 $mch_key = trim($this->getConf('mch_key', __CLASS__)); //商户API秘钥 $post_data = array('appid' => $appid, 'mch_id' => $mch_id, 'nonce_str' => $this->getNonceStr(), 'body' => $params['subject'] ? $params['subject'] : '支付订单#' . $params['order_id'], 'out_trade_no' => $params['bill_id'], 'total_fee' => $params['money'] * 100, 'spbill_create_ip' => $params['ip'], 'notify_url' => $this->notify_url, 'trade_type' => 'JSAPI', 'openid' => $params['payer_account']); $is_mobile = base_mobiledetect::is_mobile(); $in_wechat = base_mobiledetect::is_wechat(); if (!$is_mobile || !$in_wechat) { //不在微信内,请求微信支付时,进行二维码展示支付 $post_data['trade_type'] = 'NATIVE'; $post_data['product_id'] = $post_data['out_trade_no']; unset($post_data['openid']); } foreach ($post_data as $key => $value) { $this->add_field($key, $value); } $sign = $this->_get_mac($mch_key); $this->add_field('sign', $sign); $res_arr = $this->unifiedorder(); $render = app::get('wechat')->render(); $render->pagedata['total_fee'] = $params['money']; $render->pagedata['order_id'] = $params['order_id']; $render->pagedata['bill_id'] = $params['bill_id']; $render->pagedata['is_mobile'] = $is_mobile ? 'true' : 'false'; $render->pagedata['in_wechat'] = $in_wechat ? 'true' : 'false'; $controller_ins = vmc::singleton(($is_mobile ? 'mobile' : 'site') . '_controller'); if ($res_arr['return_code'] != 'SUCCESS') { $controller_ins->splash('error', '', '调用微信支付失败!' . $res_arr['return_msg']); } elseif ($res_arr['result_code'] != 'SUCCESS') { $controller_ins->splash('error', '', '调用微信支付失败!' . $res_arr['err_code_des']); } if ($res_arr['trade_type'] == 'JSAPI') { //微信内支付 $jsapi_arr = array('appId' => $appid, 'timeStamp' => (string) time(), 'nonceStr' => $this->getNonceStr(), 'package' => 'prepay_id=' . $res_arr['prepay_id'], 'signType' => 'MD5'); $jsapi_arr['paySign'] = $this->_get_mac($mch_key, $jsapi_arr); $render->pagedata['jsapi_object'] = json_encode($jsapi_arr); echo $render->fetch('wxpay/jsapi.html'); exit; } elseif ($res_arr['trade_type'] == 'NATIVE') { //微信外产生二维付款码 $render->pagedata['code_url'] = $res_arr['code_url']; echo $render->fetch('wxpay/qrcode.html'); exit; } }
/** * 同步跳转处理. * * @see /applications/toauth/lib/api.php * @params array - 所有第三方回调参数,包括POST和GET */ public function callback(&$params) { $code = $params['code']; $forward = $params['state']; //最终转向目标 //获得token $token = $this->get_token($code, $error_msg); if ($error_msg) { die($error_msg); } //获得微信用户open资料 $userinfo = $this->get_userinfo($token['access_token'], $token['openid'], $error_msg); if ($error_msg) { die($error_msg); } $cur_time = time(); /* * 会员SDF */ $member_sdf = array('avatar' => $userinfo['avatar_large'], 'profile' => array('name' => urldecode($userinfo['screen_name']), 'gender' => $userinfo['gender'] == 'm' ? '1' : '0'), 'addon' => serialize($userinfo), 'pam_account' => array('openid' => $userinfo['openid'], 'login_account' => 'wb_' . substr(md5($userinfo['openid']), -5), 'login_type' => $this->login_type, 'login_password' => md5($cur_time), 'password_account' => $userinfo['openid'], 'createtime' => $cur_time), 'regtime' => $cur_time, 'source' => 'api', 'reg_ip' => base_request::get_remote_addr()); //call abstract method $member_id = $this->dologin($member_sdf, $error_msg); if ($member_id) { if (!$forward) { $app = base_mobiledetect::is_mobile() ? 'mobile' : 'site'; $forward = app::get($app)->router(array('app' => $app, 'ctl' => 'index', 'full' => 1)); } header('Location: ' . $forward); } else { die($error_msg); } }
static function boot() { set_error_handler(array('kernel', 'exception_error_handler')); try { if (!self::register_autoload()) { require dirname(__FILE__) . '/autoload.php'; } require ROOT_DIR . '/config/mapper.php'; if (self::is_online()) { require ROOT_DIR . '/config/config.php'; } @(include APP_DIR . '/base/defined.php'); date_default_timezone_set(defined('DEFAULT_TIMEZONE') ? 'Etc/GMT' . (DEFAULT_TIMEZONE >= 0 ? DEFAULT_TIMEZONE * -1 : '+' . DEFAULT_TIMEZONE * -1) : 'UTC'); self::$url_app_map = $urlmap; foreach (self::$url_app_map as $flag => $value) { self::$app_url_map[$value['app']] = $flag; } if (get_magic_quotes_gpc()) { self::strip_magic_quotes($_GET); self::strip_magic_quotes($_POST); } $pathinfo = self::request()->get_path_info(); $jump = false; if (isset($pathinfo[1])) { if ($p = strpos($pathinfo, '/', 2)) { $part = substr($pathinfo, 0, $p); } else { $part = $pathinfo; $jump = true; } } else { $part = '/'; } if ($part == '/api') { return kernel::single('base_rpc_service')->process($pathinfo); } elseif ($part == '/openapi') { return kernel::single('base_rpc_service')->process($pathinfo); } elseif ($part == '/app-doc') { //cachemgr::init(); return kernel::single('base_misc_doc')->display($pathinfo); } if (isset(self::$url_app_map[$part])) { if ($jump) { $request_uri = self::request()->get_request_uri(); $urlinfo = parse_url($request_uri); $query = $urlinfo['query'] ? '?' . $urlinfo['query'] : ''; header('Location: ' . $urlinfo['path'] . '/' . $query); exit; } else { $app = self::$url_app_map[$part]['app']; $prefix_len = strlen($part) + 1; kernel::set_lang(self::$url_app_map[$part]['lang']); } } else { $app = self::$url_app_map['/']['app']; $prefix_len = 1; kernel::set_lang(self::$url_app_map['/']['lang']); } if (!$app) { readfile(ROOT_DIR . '/app/base/readme.html'); exit; } if (!self::is_online()) { if (file_exists(APP_DIR . '/setup/app.xml')) { if ($app != 'setup') { //todo:进入安装check setcookie('LOCAL_SETUP_URL', app::get('setup')->base_url(1), 0, '/'); header('Location: ' . kernel::base_url() . '/app/setup/check.php'); exit; } } else { echo '<h1>System is Offline, install please.</h1>'; exit; } } // 检查是否手机端 if (base_mobiledetect::is_mobile()) { base_mobiledetect::select_terminator($part, $_GET['ignore_ua_check'], self::$url_app_map); } if (isset($pathinfo[$prefix_len])) { $path = substr($pathinfo, $prefix_len); } else { $path = ''; } //init cachemgr if ($app == 'setup') { cachemgr::init(false); } else { cachemgr::init(); cacheobject::init(); } //get app router self::$__router = app::get($app)->router(); self::$__router->dispatch($path); } catch (Exception $e) { base_errorpage::exception_handler($e); } }
/** * 准备跳转到支付平台. * * @param mixed $order_id 订单编号 * @param $recursive 递归调用标记 */ public function dopayment($order_id, $recursive = false) { $redirect = $this->gen_url(array('app' => 'b2c', 'ctl' => 'mobile_member', 'act' => 'orders')); $obj_bill = vmc::singleton('ectools_bill'); $mdl_bills = app::get('ectools')->model('bills'); $order = $this->app->model('orders')->dump($order_id); if ($order['pay_status'] == '1' || $order['pay_status'] == '2') { $this->splash('success', $redirect, '已支付'); } if (in_array($order['pay_app'], array('cod', 'offline'))) { $this->splash('error', $redirect, '不是在线支付方式'); } if ($this->app->member_id != $order['member_id']) { $this->splash('error', $redirect, '非法操作'); } //未交互过的账单复用 $bill_sdf = array('order_id' => $order['order_id'], 'bill_type' => 'payment', 'pay_mode' => 'online', 'pay_object' => 'order', 'money' => $order['order_total'] - $order['payed'], 'member_id' => $order['member_id'], 'status' => 'ready', 'pay_app_id' => $order['pay_app'], 'pay_fee' => $order['cost_payment'], 'memo' => $order['memo']); $exist_bill = $mdl_bills->getRow('*', $bill_sdf); //一天内重复利用原支付单据 if ($exist_bill && !empty($exist_bill['bill_id']) && $exist_bill['createtime'] + 86400 > time()) { $bill_sdf = array_merge($exist_bill, $bill_sdf); } else { $bill_sdf['bill_id'] = $mdl_bills->apply_id($bill_sdf); } $bill_sdf['return_url'] = $this->gen_url(array('app' => 'b2c', 'ctl' => 'mobile_checkout', 'act' => 'payresult', 'args' => array($bill_sdf['bill_id']))); //微信内支付时,需要静默授权,以获得用户openid if (base_mobiledetect::is_wechat() && $order['pay_app'] == 'wxpay' && empty($bill_sdf['payer_account'])) { $wxpay_setting = unserialize(app::get('ectools')->getConf('wechat_payment_applications_wxpay')); $wxpay_appid = $wxpay_setting['appid']; $wxpay_appsecret = $wxpay_setting['appsecret']; $auth_code = $_GET['code']; $auth_state = $_GET['state']; if (!$recursive) { $oauth_redirect = $this->gen_url(array('app' => 'b2c', 'ctl' => 'mobile_checkout', 'act' => 'dopayment', 'args' => array($order_id, 'recursive'), 'full' => 1)); $oauth_redirect = urlencode($oauth_redirect); $oauth_action = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$wxpay_appid}&redirect_uri={$oauth_redirect}&response_type=code&scope=snsapi_base&state={$order_id}#wechat_redirect"; logger::debug('微信snsapi_base URL:' . $oauth_action); $this->redirect($oauth_action); //静默授权 } elseif ($recursive && $auth_code && $auth_state == $order_id) { //把微信用户openid 记录到支付单据中 $auth_token = vmc::singleton('base_httpclient')->get("https://api.weixin.qq.com/sns/oauth2/access_token?appid={$wxpay_appid}&secret={$wxpay_appsecret}&code={$auth_code}&grant_type=authorization_code"); $auth_token = json_decode($auth_token, 1); if (!$auth_token['openid']) { logger::warning('微信静默授权失败!' . var_export($auth_token, 1)); $this->splash('error', $redirect, '暂无法进行微信内支付。'); } $bill_sdf['payer_account'] = $auth_token['openid']; } else { logger::warning('微信静默授权失败!order_id:' . $order_id . '|' . var_export($_GET, 1)); } } try { if (!$obj_bill->generate($bill_sdf, $msg)) { $this->splash('error', $redirect, $msg); } } catch (Exception $e) { $this->splash('error', $redirect, $e->getMessage()); } $get_way_params = $bill_sdf; if (!vmc::singleton('ectools_payment_api')->redirect_getway($get_way_params, $msg)) { $this->splash('error', $redirect, $msg); } //here we go to the platform }
/** * 会员登录session \cookie */ protected function bind_member($member_id, &$msg) { //must in http vmc::singleton('b2c_user_object')->set_member_session($member_id); $frontpage_class = base_mobiledetect::is_mobile() ? 'b2c_mfrontpage' : 'b2c_frontpage'; vmc::singleton($frontpage_class)->bind_member($member_id); //TODO return $member_id; }
function login($auth, &$usrdata) { $config = $this->config; $appid = $config['app_id']['value']; $appsecret = $config['app_secret']['value']; $code = $_REQUEST['code']; $state = $_REQUEST['state']; $token_url = "https://graph.qq.com/oauth2.0/token"; $query = array('grant_type' => 'authorization_code', 'client_id' => $appid, 'client_secret' => $appsecret, 'code' => $code, 'redirect_uri' => $this->redirect_uri); $objHttp = kernel::single('base_httpclient'); $response = $objHttp->post($token_url, $query); parse_str($response, $response_arr); $access_token = $response_arr['access_token']; if (!$access_token) { $msg = "授权失败"; return false; } $graph_url = "https://graph.qq.com/oauth2.0/me?access_token={$access_token}"; $qq_open = $objHttp->get($graph_url); if (strpos($qq_open, "callback") !== false) { $lpos = strpos($qq_open, "("); $rpos = strrpos($qq_open, ")"); $qq_open = substr($qq_open, $lpos + 1, $rpos - $lpos - 1); } $qq_open = json_decode($qq_open, 1); $qq_openid = $qq_open['openid']; if (!$qq_openid) { $msg = "获取授权用户信息失败"; return false; } $graph_url2 = "https://graph.qq.com/user/get_user_info?access_token={$access_token}&oauth_consumer_key={$appid}&openid={$qq_openid}&format=json"; $qq_user_info = $objHttp->get($graph_url2); $qq_user_info_arr = json_decode($qq_user_info, 1); $qq_user_info_arr['nickname'] = urldecode($qq_user_info_arr['nickname']); $usrdata['login_name'] = 'QQ_' . substr($qq_openid, 5, 10); //老用户简化登陆 $account = app::get('pam')->model('account'); $_account = $account->getRow('*', array('account_type' => pam_account::get_account_type('b2c'), 'login_name' => $usrdata['login_name'], 'disabled' => 'false')); if ($_account && $_account['account_id']) { $_SESSION['account']['login_name'] = $usrdata['login_name']; $_SESSION['account'][pam_account::get_account_type('b2c')] = $_account['account_id']; kernel::single('b2c_frontpage')->bind_member_new($_account); } else { $account_id = $this->save_login_data($usrdata['login_name'], $qq_user_info); if ($account_id) { $_SESSION['account']['login_name'] = $usrdata['login_name']; $_SESSION['account'][pam_account::get_account_type('b2c')] = $account_id; $memberinfo = array('name' => $qq_user_info_arr['nickname'], 'trust_name' => $qq_user_info_arr['nickname'] . '-' . $qq_openid, 'email' => $qq_openid . '@open-qq.com', 'addr' => ''); if (!$this->update_member($memberinfo)) { $usrdata['log_data'] = "登录失败"; unset($usrdata['login_name']); kernel::single('site_controller')->splash('error', false, "登录失败!请稍后重试。"); } } else { $usrdata['log_data'] = "登录失败"; unset($usrdata['login_name']); kernel::single('site_controller')->splash('error', false, "登录失败!请稍后重试。"); } } if ($state) { $url = base64_decode($state); } else { if (base_mobiledetect::is_mobile()) { $url = app::get('site')->router()->gen_url(array('app' => 'b2c', 'ctl' => 'wap_member', 'act' => 'index')); } else { $url = app::get('site')->router()->gen_url(array('app' => 'b2c', 'ctl' => 'site_member', 'act' => 'index')); } } if (false && !base_mobiledetect::is_mobile() && $memberinfo['state'] < 1) { $url = app::get('site')->router()->gen_url(array('app' => 'b2c', 'ctl' => 'site_passport', 'act' => 'upstate_with_mobile', 'args01' => $url)); kernel::single('site_controller')->splash('success', $url, "登录成功,请设置手机登录"); } if ($_REQUEST['is_app']) { echo json_encode(array('status' => 'success', 'member_id' => $account_id)); exit; } kernel::single('b2c_frontpage')->redirect($url); }
/** * 同步跳转处理. * * @see /applications/toauth/lib/api.php * @params array - 所有第三方回调参数,包括POST和GET */ public function callback(&$params) { $code = $params['code']; $forward = $params['state']; //最终转向目标 //获得token $token = $this->get_token($code, $error_msg); if ($error_msg) { die($error_msg); } //获得微信用户open资料 $userinfo = $this->get_userinfo($token['access_token'], $token['openid'], $error_msg); if ($error_msg) { header('Content-type: text/html; charset=utf-8'); die($error_msg); } $cur_time = time(); /* * 会员SDF */ $member_sdf = array('avatar' => $userinfo['headimgurl'], 'contact' => array('name' => $userinfo['nickname'], 'addr' => $userinfo['country'] . $userinfo['city'] . $userinfo['province']), 'profile' => array('gender' => $userinfo['sex'] == '1' ? '1' : '0'), 'addon' => serialize($userinfo), 'pam_account' => array('openid' => $userinfo['openid'], 'login_account' => 'wx_' . substr(md5($userinfo['openid']), -5), 'login_type' => $this->login_type, 'login_password' => md5($cur_time), 'password_account' => $userinfo['openid'], 'createtime' => $cur_time), 'regtime' => $cur_time, 'source' => 'api', 'reg_ip' => base_request::get_remote_addr()); //call abstract method $member_id = $this->dologin($member_sdf, $error_msg); if ($member_id) { if (!$forward) { $app = base_mobiledetect::is_mobile() ? 'mobile' : 'site'; $forward = app::get($app)->router(array('app' => $app, 'ctl' => 'index', 'full' => 1)); } if ($params['qrlp']) { $forward .= '?mid=' . $member_id . '&enc_str=' . $params['qrlp']; } header('Location: ' . $forward); } else { header('Content-type: text/html; charset=utf-8'); die($error_msg); } }