<?php namespace Phpcmf\Model;
class Pay extends \Phpcmf\Model
{
protected $myfield;
protected $payname;
public function __construct(...$params) {
parent::__construct(...$params);
$this->myfield = [
'recharge' => [
'fieldtype' => 'Pay',
'fieldname' => 'pay',
'setting' => [
'option' => [
'payfile' => 'pay.html', 'is_finecms' => 0, ],
]
],
'score' => [
'fieldtype' => 'Pay',
'fieldname' => 'pay',
'setting' => [
'option' => [
'payfile' => 'score.html', 'is_finecms' => 1, ],
]
],
'donation' => [
'fieldtype' => 'Pay',
'fieldname' => 'pay',
'setting' => [
'option' => [
'payfile' => 'donation.html', 'is_finecms' => 1, ],
]
],
'gathering' => [
'fieldtype' => 'Pay',
'fieldname' => 'price',
'setting' => [
'option' => [
'payfile' => 'gathering.html', 'is_finecms' => 1, ],
]
],
];
}
public function get_module_row($dir, $id, $siteid) {
$data = $this->table($siteid.'_'.$dir)->get($id);
if (!$data) {
return dr_return_data(0, dr_lang('打赏内容不存在'));
}
return dr_return_data(1, 'ok', $data);
}
public function get_pay_info($id, $field, $num = 1, $sku = '') {
list($table, $name, $username, $thumb, $url) = $this->_get_table_name(
$field['relatedid'],
$field['relatedname']
);
if (!$table) {
return dr_return_data(0, dr_lang('支付关联表不存在'));
}
$rt = $this->table($table)->get($id);
if (!$rt) {
return dr_return_data(0, dr_lang('支付关联表[%s]内容(#%s)不存在', $table, $id));
} elseif (!isset($rt[$field['fieldname']])) {
return dr_return_data(0, dr_lang('支付关联表的支付字段[%s]不存在于主表', $field['fieldname']));
} elseif (isset($rt[$thumb]) && $rt[$thumb] && !is_numeric($rt[$thumb])) {
$image = dr_string2array($rt[$thumb]);
isset($image['file'][0]) && $image['file'][0] && $rt[$thumb] = $image['file'][0];
}
$title = (string)$rt[$name];
if ($field['fieldtype'] == 'Pays' && isset($rt[$field['fieldname'].'_sku']) && $rt[$field['fieldname'].'_sku']) {
$rt[$field['fieldname'].'_sku'] = dr_string2array($rt[$field['fieldname'].'_sku']);
if (!$sku && $rt[$field['fieldname'].'_sku']) {
return dr_return_data(0, dr_lang('没有选择商品属性'));
} elseif (!isset($rt[$field['fieldname'].'_sku']['value'][$sku]) || !$rt[$field['fieldname'].'_sku']['value'][$sku]) {
#print_r($rt[$field['fieldname'].'_sku']['value']);
return dr_return_data(0, dr_lang('商品(#'.$rt['id'].')属性(#'.$sku.')无效'));
}
$sn = (string)$rt[$field['fieldname'].'_sku']['value'][$sku]['sn'];
$price = (float)$rt[$field['fieldname'].'_sku']['value'][$sku]['price'];
$quantity = (int)$rt[$field['fieldname'].'_sku']['value'][$sku]['quantity'];
list($sku_name, $sku_string) = dr_sku_name($sku, $rt[$field['fieldname'].'_sku'], 1);
} else {
$sn = (string)$rt[$field['fieldname'].'_sn'];
$price = (float)$rt[$field['fieldname']];
$quantity = (int)$rt[$field['fieldname'].'_quantity'];
$sku_name = '';
$sku_string = '';
}
$mid = 'buy-'.$table .'-'. $id .'-'. $field['id'] .'-'. max(1, (int)$num) .'-'. ($sku ? $sku : 'null');
return [
'mid' => $mid,
'num' => $num,
'price' => $price,
'total' => $price * $num,
'table' => $table,
'sn' => $sn,
'quantity' => $quantity,
'sku_name' => $sku_name,
'sku_string' => $sku_string,
'sku_value' => $sku,
'touid' => intval($rt['uid']),
'tousername' => (string)$rt['username'],
'title' => $title,
'thumb' => (string)$rt[$thumb],
'url' => $url ? $url.$id : '',
'data' => $rt,
];
}
public function _get_table_name($relatedid, $relatedname) {
$data = \Phpcmf\Service::C()->get_cache('table-pay-'.SITE_ID, $relatedname.'-'.$relatedid);
if (!$data) {
return [];
}
return [$data['table'], $data['name'], $data['username'], $data['thumb'], $data['url']];
}
public function paystatus($data) {
switch ($data['status']) {
case 0:
return '<a href="javascript:dr_ajaxp_url(\''.ROOT_URL.'index.php?s=api&c=pay&m=ajax&id='.$data['id'].'\');" class="label label-danger"> '.dr_lang('未付款').' </a>';
break;
case 1:
return '<span class="label label-success"> '.dr_lang('已付款').' </span>';
break;
case 2:
return '<span class="label label-warning"> '.dr_lang('汇款中').' </span>';
break;
case 5:
return '<span class="label label-warning"> '.dr_lang('上门付').' </span>';
break;
case 3:
return '<span class="label label-danger"> '.dr_lang('被拒绝').' </span>';
break;
}
}
public function paytype($mark) {
switch ($mark) {
case 'recharge':
return '<span class="label label-default"> '.dr_lang('充值').' </span>';
break;
case 'score':
return '<span class="label label-success"> '.dr_lang(SITE_SCORE).' </span>';
break;
case 'system':
return '<span class="label label-danger"> '.dr_lang('系统').' </span>';
break;
case 'order':
case 'orders':
return '<span class="label label-success"> '.dr_lang('订单').' </span>';
break;
case 'cash':
return '<span class="label label-success"> '.dr_lang('提现').' </span>';
break;
default:
list($rname, $rid, $fid) = explode('-', $mark);
switch ($rname) {
case 'order':
case 'orders':
return '<span class="label label-success"> '.dr_lang('订单').' </span>';
break;
case 'gathering':
return '<span class="label label-danger"> '.dr_lang('收款').' </span>';
break;
case 'buy':
return '<span class="label label-danger"> '.dr_lang('下单').' </span>';
break;
case 'my':
$obj = $this->my_pay_obj($rid);
if (method_exists($obj, 'paytype')) {
return $obj->paytype();
} else {
return '<span class="label label-warning"> '.dr_lang('应用').' </span>';
}
break;
case 'donation':
return '<span class="label label-danger"> '.dr_lang('打赏').' </span>';
break;
default:
/*
$field = \Phpcmf\Service::C()->get_cache('table-field', $fid);
if ($field['relatedname'] == 'module') {
return '<span class="label label-success"> '.dr_lang('模块').' </span>';
} elseif (function_exists('dr_paytype_'.$mark)) {
return call_user_func('dr_paytype_'.$mark);
}*/
return '<span class="label label-warning"> '.dr_lang('其他').' </span>';
break;
}
break;
}
}
public function payname($name) {
switch ($name) {
case 'meet';
return '上门';
break;
case 'remit';
return '汇款';
break;
case 'system';
return '系统';
break;
case 'admin';
return '后台';
break;
case 'finecms';
return '余额';
break;
case 'weixin';
return '微信';
break;
case 'alipay';
return '支付宝';
break;
default;
if (!$this->payname[$name]) {
if (is_file(WEBPATH.'api/pay/'.$name.'/config.php')) {
$this->payname[$name] = require WEBPATH.'api/pay/'.$name.'/config.php';
} else {
return $name;
}
}
if (isset($this->payname[$name]['name']) && $this->payname[$name]['name']) {
return $this->payname[$name]['name'];
}
return $name;
break;
}
}
public function payform($mark, $value = 0, $title = '', $url = '', $remove_div = 0) {
switch ($mark) {
case 'recharge':
$field = $this->myfield[$mark];
break;
case 'score':
$field = $this->myfield[$mark];
break;
default:
list($rname, $rid, $fid, $num, $sku) = explode('-', $mark);
switch ($rname) {
case 'gathering':
$field = $this->myfield[$rname];
$value = ceil($value);
break;
case 'my':
$obj = $this->my_pay_obj($rid);
if (method_exists($obj, 'get_myfield')) {
$field = $obj->get_myfield();
} else {
return dr_lang('自定义类方法get_myfield未定义');
}
if (method_exists($obj, 'pay_before')) {
$rt = $obj->pay_before($fid, $num, $sku, SITE_ID);
if ($rt) {
return $rt;
}
}
if (method_exists($obj, 'get_price')) {
$value = $obj->get_price($fid, $num, $sku, SITE_ID);
} else {
return dr_lang('自定义类方法get_price未定义');
}
break;
case 'donation':
$field = $this->myfield[$rname];
$value = ceil($value);
break;
case 'buy':
$field = \Phpcmf\Service::C()->get_cache('table-field', $num);
if (!$field) {
return dr_lang('支付字段[%s]不存在', $num);
}
break;
default:
return dr_return_data(0, dr_lang('未定义的支付方式'));
break;
}
break;
}
$f = \Phpcmf\Service::L('Field')->get($field['fieldtype']);
$f->remove_div = $remove_div;
$html = $f->input($field, $value, [
'mark' => $mark,
'title' => $title,
'url' => $url,
]);
return $html;
}
public function add_paylog($data) {
$data = [
'site' => SITE_ID,
'mid' => $data['mid'],
'uid' => $data['uid'],
'username' => $data['username'],
'touid' => (int)$data['touid'],
'tousername' => $data['tousername'] ? $data['tousername'] : '',
'title' => $data['title'],
'value' => $data['value'],
'type' => $data['type'],
'url' => !$data['url'] ? '' : dr_url_prefix($data['url']),
'status' => (int)$data['status'],
'result' => $data['result'] ? $data['result'] : '',
'paytime' => $data['paytime'] ? $data['paytime'] : 0,
'inputtime' => SYS_TIME,
];
$rt = $this->table('member_paylog')->insert($data);
$data['id'] = $rt['code'];
$rt['data'] = $data;
return $rt;
}
public function add_money($uid, $value) {
return \Phpcmf\Service::M('member')->add_money($uid, $value);
}
public function paysuccess($mark, $payid) {
list($a, $id) = explode('-', $mark);
$data = $this->table('member_paylog')->get($id);
if (!$data) {
return dr_return_data(0, dr_lang('支付记录不存在'));
} elseif ($data['status'] == 1) {
return dr_return_data(0, dr_lang('此账单已经支付'));
} else {
$user = \Phpcmf\Service::M('Member')->member_info($data['uid']);
list($a, $b, $c, $d, $e, $f) = explode('-', $data['mid']);
if ($data['touid']) {
if ($data['touid'] == $data['uid']) {
if ($data['type'] != 'finecms') {
$this->add_money($data['uid'], $data['value']);
}
} else {
if ($data['type'] == 'finecms') {
$this->add_money($data['uid'], -abs($data['value']));
} else {
if ($user) {
$this->table('member')->update($data['uid'], [
'spend' => max(0, $user['spend'] + abs($data['value'])),
]);
}
}
}
} else {
if ($data['type'] == 'finecms') {
$this->add_money($data['uid'], -abs($data['value']));
} else {
if ($user) {
$this->table('member')->update($data['uid'], [
'spend' => max(0, $user['spend'] + abs($data['value'])),
]);
}
}
}
$this->table('member_paylog')->update($id, [
'status' => 1,
'result' => $payid,
'paytime' => SYS_TIME,
]);
$data['status'] = 1;
$data['result'] = $payid;
$data['paytime'] = SYS_TIME;
$data['url'] = \Phpcmf\Service::L('Router')->member_url('paylog/show', ['id' => $data['id']]);
if ($user) {
$data['phone'] = $user['phone'];
$data['email'] = $user['email'];
\Phpcmf\Service::L('Notice')->send_notice('pay_success', $data);
\Phpcmf\Hooks::trigger('pay_success', $data);
}
switch ($a) {
case 'recharge':
if (dr_is_app('yaoqing')) {
\Phpcmf\Service::M('yq', 'yaoqing')->czfx($data);
}
break;
case 'score':
$value = abs($data['value']) * \Phpcmf\Service::C()->member_cache['pay']['convert'];
\Phpcmf\Service::M('member')->add_score($data['uid'], $value, dr_lang('在线充值'), $data['url']);
break;
case 'donation':
$cid = (int)$c;
$rt = $this->table($d.'_'.$b.'_donation')->insert([
'cid' => $cid,
'uid' => $data['uid'],
'value' => abs($data['value']),
'inputtime' => SYS_TIME
]);
$this->add_money($data['touid'], abs($data['value']));
$this->add_paylog([
'uid' => $data['touid'],
'username' => $data['tousername'],
'touid' => $data['uid'],
'tousername' => $data['username'],
'mid' => $data['mid'],
'title' => $data['title'],
'value' => abs($data['value']),
'type' => $data['type'],
'status' => 1,
'result' => $payid,
'paytime' => SYS_TIME,
'inputtime' => $data['inputtime'],
]);
if ($rt['code']) {
$sum = $this->db->table($d.'_'.$b.'_donation')->selectSum('value')->where('cid', $cid)->get()->getRowArray();
$this->db->table($d.'_'.$b)->where('id', $cid)->set('donation', $sum['value'])->update();
\Phpcmf\Service::L('cache')->clear('module_'.$b.'_show_id_'.$cid);
$data['cid'] = $cid;
$data['mid'] = $b;
$content_model = \Phpcmf\Service::M('Content', $b);
$content_model->_init($b, $d);
$content_model->_content_donation_after($cid, $data);
\Phpcmf\Hooks::trigger('donation_success', $data);
} else {
log_message('error', '打赏付款(#'.$id.')回调失败:'.$rt['msg']);
}
break;
case 'buy':
\Phpcmf\Hooks::trigger('member_buy_after', $data);
break;
case 'order':
\Phpcmf\Service::M('order', 'order')->pay($c, $id);
break;
case 'orders':
$oids = explode(',', $c);
foreach ($oids as $oi) {
\Phpcmf\Service::M('order', 'order')->pay($oi, $id);
}
break;
case 'gathering':
$row = $this->table($c)->get($b);
if (!$row) {
log_message('error', '收款(#'.$id.')回调失败:主题#'.$c.'不存在');
} else {
$row['nums'] = $row['nums'] + 1;
$row['total'] = $row['total'] + abs($data['value']);
$this->table($c)->update($b, [
'total' => $row['total'],
'nums' => $row['nums'],
'updatetime' => SYS_TIME
]);
\Phpcmf\Hooks::trigger('gathering_'.$c.'_success', $row, $data);
}
break;
case 'my':
$obj = $this->my_pay_obj($b);
if (method_exists($obj, 'success')) {
$obj->success($c, $data, $d, $e);
}
break;
}
return dr_return_data(1, dr_lang('支付成功'));
}
}
public function paycall_url($data) {
$url = dr_url_prefix('index.php?s=member&c=paylog&m=show&id='.$data['id'], '', $data['site']);
list($rname, $rid, $fid, $num, $sku) = explode('-', $data['mid']);
switch ($rname) {
case 'my':
$obj = $this->my_pay_obj($rid);
if (method_exists($obj, 'call_url')) {
$row = $obj->call_url($fid, $data);
if ($row) {
$url = $row;
}
}
break;
case 'order':
$url = dr_url_prefix('index.php?s=member&app=order&c=home&m=show&id='.$fid, '', $data['site']);
break;
case 'orders':
$url = dr_url_prefix('index.php?s=member&app=order&c=home&m=index', '', $data['site']);
break;
}
return $url;
}
public function post($post) {
if (strlen($post['money']) > 8) {
return dr_return_data(0, dr_lang('付款金额[%s]不规范', $post['money']));
}
$post['uid'] = intval($post['uid']);
$post['username'] = (string)$post['username'];
$post['money'] = floatval($post['money']);
if ($post['money'] <= 0) {
return dr_return_data(0, dr_lang('付款金额[%s]不规范', $post['money']));
} elseif ((string)$post['money'] == 'INF') {
return dr_return_data(0, dr_lang('付款金额[%s]不规范', $post['money']));
} elseif (!$post['type']) {
return dr_return_data(0, dr_lang('未知支付接口'));
}
$touid = $money = $fid = 0;
$tousername = $title = '';
switch ($post['mark']) {
case 'recharge':
if (!$post['uid']) {
return dr_return_data(0, dr_lang('付款账号不存在'));
}
$title = dr_lang('用户(%s)充值', $post['username']);
$money = $post['money'];
if (\Phpcmf\Service::C()->member_cache['pay']['min'] && $money < \Phpcmf\Service::C()->member_cache['pay']['min']) {
return dr_return_data(0, dr_lang('系统最小充值金额为%s元', \Phpcmf\Service::C()->member_cache['pay']['min']));
}
$touid = $post['uid']; $tousername = $post['username']; if ($post['type'] == 'finecms') {
return dr_return_data(0, dr_lang('充值不能使用余额支付'));
}
break;
case 'score':
if (!$post['uid']) {
return dr_return_data(0, dr_lang('付款账号不存在'));
}
$money = (int)$post['money'];
$title = dr_lang('用户(%s)充值%s:%s', $post['username'], SITE_SCORE, $money);
$touid = 0; $tousername = '';
$money = - $money / \Phpcmf\Service::C()->member_cache['pay']['convert'];
break;
default:
list($rname, $rid, $fid, $num, $sku, $ff) = explode('-', $post['mark']);
switch ($rname) {
case 'gathering':
$field = $this->myfield[$rname];
$row = $this->table($fid)->get($rid);
if (!$row) {
return dr_return_data(0, dr_lang('收款主题不存在'));
}
$money = floatval($row['price'] > 0 ? $row['price'] : $post['money']);
if ($money <= 0) {
return dr_return_data(0, dr_lang('金额[%s]不规范', $money));
}
$title = $row['title'];
$money = -$money;
$touid = 0; $tousername = ''; break;
case 'my':
$obj = $this->my_pay_obj($rid);
if (method_exists($obj, 'get_row')) {
$row = $obj->get_row($fid, $num, $sku, SITE_ID);
if (!$row) {
return dr_return_data(0, dr_lang('主题不存在'));
}
} else {
return dr_return_data(0, dr_lang('类方法[get_row]未定义'));
}
$money = floatval($row['price']);
if ($money <= 0) {
return dr_return_data(0, dr_lang('金额[%s]不规范', $money));
}
$title = $row['title'];
$money = -$money;
$touid = (int)$row['sell_uid']; $tousername = (string)$row['sell_username']; break;
case 'donation':
$field = $this->myfield[$rname];
$money = (float)$post['money'];
if ($money <= 0) {
return dr_return_data(0, dr_lang('金额[%s]不规范', $money));
}
$rt = $this->get_module_row($rid, $fid, $num);
if (!$rt['code']) {
return dr_return_data(0, $rt['msg']);
}
$min = floatval(\Phpcmf\Service::C()->member_cache['pay']['smin']);
if ($min > 0 && $money < $min) {
return dr_return_data(0, dr_lang('打赏金额不能低于%s元', $min));
}
$touid = $rt['data']['uid'];
$tousername = $rt['data']['author'];
$title = $post['title'];
$money = -$money;
if ($this->uid == $touid) {
return dr_return_data(0, dr_lang('不能对自己打赏'));
}
break;
case 'order':
$title = dr_lang('订单编号:%s', $post['sn']);
$money = -(float)$post['money'];
$touid = 0; $tousername = ''; break;
case 'orders':
$title = dr_lang('订单编号:%s', $post['sn']);
$money = -(float)$post['money'];
$touid = 0; $tousername = ''; break;
case 'buy':
$field = \Phpcmf\Service::C()->get_cache('table-field', $num);
if (!$field) {
return dr_return_data(0, dr_lang('支付字段[%s]不存在', $num));
}
$rt = $this->get_pay_info($fid, $field, $sku, $ff);
if ($rt['total'] <= 0) {
return dr_return_data(0, dr_lang('金额[%s]不规范', $rt['total']));
} elseif ($rt['mid'] != $post['mark']) {
return dr_return_data(0, dr_lang('支付信息验证失败'));
}
$touid = $rt['touid'];
$tousername = $rt['tousername'];
$title = $rt['title'];
$money = -(float)$rt['total'];
if ($this->uid == $touid) {
return dr_return_data(0, dr_lang('不能对自己付款'));
}
break;
default:
return dr_return_data(0, dr_lang('未定义的支付方式'));
break;
}
break;
}
$apifile = ROOTPATH.'api/pay/'.$post['type'].'/pay.php';
if (!is_file($apifile)) {
return dr_return_data(0, dr_lang('支付接口文件(%s)不存在', $post['type']));
}
return $this->add_paylog([
'uid' => $post['uid'],
'username' => $post['username'],
'touid' => $touid,
'tousername' => $tousername,
'mid' => $post['mark'],
'title' => $title,
'value' => $money,
'type' => $post['type'],
'status' => 0,
'url' => $post['url'],
'result' => '',
'paytime' => 0,
'inputtime' => SYS_TIME,
]);
}
public function dopay($apifile, $data) {
$id = $data['id']; $sn = $pid = str_replace('-', '', \Phpcmf\Service::C()->member_cache['pay']['prefix']).date('YmdHis', $data['inputtime']).'-'.$id;
$config = \Phpcmf\Service::C()->member_cache['payapi'][$data['type']];
$return = [];
$data['value'] = abs($data['value']);
require $apifile;
return $return;
}
public function cache() {
$cache = [];
\Phpcmf\Service::L('cache')->set_file('pay', $cache);
return;
}
public function my_pay_obj($name) {
list($app, $class) = explode('_', $name);
$classFile = dr_get_app_dir($app).'Models/'.ucfirst($class).'.php';
if (!is_file($classFile)) {
return;
}
return \Phpcmf\Service::M($class, $app);
}
public function clear_paylog() {
$this->db->table('member_paylog')->where('status', 0)->where('inputtime <'.(SYS_TIME - 3600*24*3))->delete();
}
}