Files
BESCMS/dayrui/App/Pay/Models/Pay.php
T

1095 lines
41 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php namespace Phpcmf\Model\Pay;
// 支付类
// 支付状态 status 0未付款 1付款成功 2转账中 3转账被拒绝
class Pay extends \Phpcmf\Model
{
protected $myfield;
protected $payname;
// 初始化
public function __construct() {
parent::__construct();
$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_pay_type($is_finecms = 0) {
$pay_type = [];
$is_finecms && $pay_type['finecms'] = \Phpcmf\Service::R(ROOTPATH.'api/pay/finecms/config.php');
if (\Phpcmf\Service::C()->member_cache['payapi']) {
foreach (\Phpcmf\Service::C()->member_cache['payapi'] as $name => $t) {
if (!is_file(ROOTPATH.'api/pay/'.$name.'/config.php')) {
continue; // 排除是否存在配置文件
}
$pay_type[$name] = \Phpcmf\Service::R(ROOTPATH.'api/pay/'.$name.'/config.php');
}
}
if ($is_finecms) {
if (!$this->uid) {
unset($pay_type['finecms']);
} elseif ($this->member['money'] < 0.01) {
unset($pay_type['finecms']);
}
}
if (IS_DEV && !$pay_type) {
log_message('debug', '系统没有开启支付接口,无法获取到支付方式');
}
return $pay_type;
}
// 获取打赏模块内容
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_price_value($data, $field, $sku = '') {
if ($sku && $sku != 'null' && isset($data[$field.'_sku']) && is_array($data[$field.'_sku'])) {
return (float)$data[$field.'_sku']['value'][$sku]['price'];
}
return (float)$data[$field];
}
// 获取支付价格和内容
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];
}
if (isset($rt[$field['fieldname'].'_sku']) && $rt[$field['fieldname'].'_sku']) {
$rt[$field['fieldname'].'_sku'] = dr_string2array($rt[$field['fieldname'].'_sku']);
}
$obj = \Phpcmf\Service::L('field')->get($field['fieldtype']);
if (isset($rt[$field['fieldname'].'_sku']) && $rt[$field['fieldname'].'_sku']
&& $obj && method_exists($obj, 'get_pay_info')) {
$rs = $obj->get_pay_info($rt, $field, $sku);
if (!$rs['code']) {
return $rs;
}
list($sn, $quantity, $sku_name, $sku_string) = $rs['data'];
} elseif ($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'];
$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'];
$quantity = (int)$rt[$field['fieldname'].'_quantity'];
$sku_name = $sku_string = '';
}
// 获取价格
$price = $this->get_price_value($rt, $field['fieldname'], $sku);
// buy-表名-主键id-字段id-数量-sku
$mid = 'buy-'.$table .'-'. $id .'-'. $field['id'] .'-'. max(1, (int)$num) .'-'. ($sku ? $sku : 'null');
return [
'sn' => $sn,
'mid' => $mid,
'num' => $num,
'price' => $price,
'price_sku' => isset($rt[$field['fieldname'].'_sku']) ? $rt[$field['fieldname'].'_sku'] : '',
'total' => $price * $num,
'table' => $table,
'quantity' => $quantity,
'sku_name' => $sku_name,
'sku_string' => $sku_string,
'sku_value' => $sku,
'touid' => intval($rt['uid']),
'tousername' => (string)$rt['username'],
'title' => (string)$rt[$name],
'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(\''.PAY_URL.'index.php?s=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 'system':
return '<span class="label label-danger"> '.dr_lang('系统').' </span>';
break;
// 用户组
case 'group':
return '<span class="label label-default"> '.dr_lang('会员').' </span>';
break;
// 用户组
case 'level':
return '<span class="label label-default"> '.dr_lang('等级').' </span>';
break;
// 订单
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 (!$obj) {
return '<span class="label label-danger"> '.dr_lang('未知').' </span>';
} elseif (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;
}
}
/**
* 支付表单调用
* mark 表名-主键id-字段id
* value 支付金额
* title 支付说明
* */
public function payform($mark, $value = 0, $title = '', $url = '', $remove_div = 0, $tpl = '') {
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 (!$obj) {
return dr_lang('自定义支付对象类文件不存在');
}
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 '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('未定义的支付方式[%s]', $rname));
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,
'tpl' => $tpl,
]);
return $html;
}
// 增加流水记录
public function add_paylog($data) {
$data = [
'site' => SITE_ID,
'mid' => $data['mid'],
'uid' => $data['uid'],
'touid' => (int)$data['touid'],
'title' => $data['title'],
'value' => $data['value'],
'type' => dr_safe_replace($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,
'money' => 0,
'inputtime' => SYS_TIME,
];
if ($data['uid']) {
$user = $this->table('member')->get($data['uid']);
$user && $data['money'] = $user['money'];
}
$rt = $this->table('member_paylog')->insert($data);
$data['id'] = $rt['code'];
$rt['data'] = $data;
return $rt;
}
// 给账户充值money
public function add_money($uid, $value) {
return \Phpcmf\Service::M('member')->add_money($uid, $value);
}
// 通过支付流水号获取id号
public function get_pay_id($mark) {
if (strpos($mark, 'fc-') === 0) {
return intval(substr($mark, 3));
}
return (int)substr($mark, strlen(\Phpcmf\Service::C()->member_cache['pay']['prefix'].date('YmdHis', SYS_TIME))+2);
}
// 生成支付流水id号
public function get_pay_sn($data) {
return trim((string)\Phpcmf\Service::C()->member_cache['pay']['prefix']).date('YmdHis', SYS_TIME).'00'.$data['id'];
}
// 充值成功的返回
public function paysuccess($mark, $payid) {
// 找流水id
$id = $this->get_pay_id($mark);
if (!$id) {
return dr_return_data(0, dr_lang('没有获取到支付ID号'));
}
$data = $this->table('member_paylog')->get($id);
if (!$data) {
return dr_return_data(0, dr_lang('支付记录不存在'));
} elseif ($data['status'] == 1) {
return dr_return_data($id, dr_lang('此账单已经支付'));
} else {
// 分析订单来源
$user = \Phpcmf\Service::M()->table('member')->get($data['uid']);
list($a, $b, $c, $d, $e, $f) = explode('-', $data['mid']);
// 付款到账号余额中 // touid为空表示系统收款直接扣
if ($data['touid']) {
if ($data['touid'] == $data['uid']) {
// 表示为自己充值
if ($data['type'] != 'finecms') {
// 充值必须判断type不是余额付款模式
$this->add_money($data['uid'], $data['value']);
$user['money']+= $data['value'];
}
} else {
// 扣除自己的钱
if ($data['type'] == 'finecms') {
// 判断type是余额付款模式,才进行扣款
$this->add_money($data['uid'], -abs($data['value']));
$user['money']-= abs($data['value']);
} else {
// 记录消费
if ($user) {
$this->table('member')->update($data['uid'], [
'spend' => max(0, (float)$user['spend'] + abs($data['value'])),
]);
}
}
}
} else {
// 扣除自己的钱 touid为空表示系统收款直接扣
if ($data['type'] == 'finecms') {
// 判断type是余额付款模式,才进行扣款
$this->add_money($data['uid'], -abs($data['value']));
$user['money']-= abs($data['value']);
} else {
// 记录消费
if ($user) {
$this->table('member')->update($data['uid'], [
'spend' => max(0, (float)$user['spend'] + abs($data['value'])),
]);
}
}
}
// 备份使用
$data['result_data'] = $result = $data['result'];
// 支付成功
$save = [
'status' => 1,
'result' => $payid,
'paytime' => SYS_TIME,
];
if ($payid == 0 && $payid == (int)$data['value']) {
// 表示0元支付设置为余额方式
$save['type'] = 'finecms';
}
if ($user) {
$save['money'] = $user['money'];
}
$this->table('member_paylog')->update($id, $save);
$data['status'] = 1;
$data['result'] = $payid;
$data['paytime'] = SYS_TIME;
$data['url'] = \Phpcmf\Service::L('Router')->member_url('pay/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':
// 在线充值
break;
case 'group':
// 用户组
\Phpcmf\Service::M('member')->notice(
$data['uid'],
2,
$data['title'],
\Phpcmf\Service::L('Router')->member_url('pay/paylog/show', ['id'=>$data['id']])
);
$result = dr_string2array($result);
\Phpcmf\Service::M('member')->apply_group($d, $user, $b, $c, abs($data['value']), $result);
break;
case 'level':
// 用户组等级升级
// 提醒通知
\Phpcmf\Service::M('member')->notice(
$data['uid'],
2,
$data['title'],
\Phpcmf\Service::L('Router')->member_url('pay/paylog/show', ['id'=>$data['id']])
);
\Phpcmf\Service::M('member')->update_level($data['uid'], $b, $c);
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 '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'] = (int)$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($id, dr_lang('支付成功'));
}
}
// 支付退款
// $data 为 member_paylog 流水记录
// 成功后不改动原流水,另增一条正数退款流水(mid = {原mid}-refund
public function payrefund($data) {
if (!$data || empty($data['id'])) {
return dr_return_data(0, dr_lang('支付记录不存在'));
} elseif ((int)$data['status'] != 1) {
return dr_return_data(0, dr_lang('此账单未支付,无法退款'));
}
$origin_mid = trim((string)$data['mid']);
if ($origin_mid === '') {
return dr_return_data(0, dr_lang('原支付标记无效,无法退款'));
}
// 避免对退款流水再次退款
if (substr($origin_mid, -7) === '-refund') {
return dr_return_data(0, dr_lang('该流水为退款记录,无法再次退款'));
}
$refund_mid = $origin_mid.'-refund';
$exists = $this->table('member_paylog')->where('mid', $refund_mid)->where('status', 1)->getRow();
if ($exists) {
return dr_return_data(0, dr_lang('该流水已退款,请勿重复操作'));
}
$type = (string)$data['type'];
$money = abs($data['value']);
list($a, $b, $c, $d, $e, $f) = explode('-', (string)$data['mid']);
$return = [];
// 按支付方式执行渠道退款
if ($type == 'finecms') {
// 账号余额支付:退回余额
if ($data['uid']) {
$rt = $this->add_money($data['uid'], $money);
if (!$rt['code']) {
return $rt;
}
}
} else {
// 在线支付(如 alipay):调用对应退款接口
$apifile = ROOTPATH.'api/pay/'.$type.'/refund.php';
if (!is_file($apifile)) {
return dr_return_data(0, dr_lang('退款失败,接口未定义'));
}
$config = [];
if (isset(\Phpcmf\Service::C()->member_cache['payapi'][$type])) {
$config = \Phpcmf\Service::C()->member_cache['payapi'][$type];
}
require $apifile;
if (!$return || !isset($return['code'])) {
return dr_return_data(0, dr_lang('退款失败,接口未定义'));
} elseif (!$return['code']) {
return $return;
}
}
// 在线充值退款:充值进账需扣回余额(业务订单退款由调用方自行处理状态)
if ($a == 'recharge' && $type != 'finecms' && $data['uid'] && $data['touid'] == $data['uid']) {
$rt = $this->add_money($data['uid'], -$money);
if (!$rt['code']) {
return $rt;
}
}
// 新增退款流水(正数),不修改原支付流水
$title = isset($data['title']) && $data['title']
? (dr_lang('退款').''.$data['title'])
: dr_lang('退款');
$result = dr_lang('原流水号:%s', $data['id']);
if (!empty($return) && is_array($return) && !empty($return['data'])) {
// 渠道返回信息可选写入
if (!empty($return['data']['trade_no'])) {
$result .= ' / '.$return['data']['trade_no'];
} elseif (!empty($return['data']['out_request_no'])) {
$result .= ' / '.$return['data']['out_request_no'];
}
} elseif (!empty($data['result'])) {
$result .= ' / '.$data['result'];
}
$rt = $this->add_paylog([
'mid' => $refund_mid,
'uid' => (int)$data['uid'],
'touid' => 0,
'title' => $title,
'value' => $money,
'type' => $type,
'url' => isset($data['url']) ? $data['url'] : '',
'status' => 1,
'result' => $result,
'paytime' => SYS_TIME,
]);
if (!$rt['code']) {
return dr_return_data(0, $rt['msg'] ?: dr_lang('退款流水写入失败'));
}
$data['refund_id'] = $rt['code'];
\Phpcmf\Hooks::trigger('pay_refund', $data);
return dr_return_data($rt['code'], dr_lang('退款成功'), [
'pay_id' => $data['id'],
'refund_id' => $rt['code'],
]);
}
// 支付成功的回调url
public function paycall_url($data) {
// 默认地址
$url = dr_url_prefix('index.php?s=member&app=pay&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;
case 'gathering':
// 来自收款
$row = $this->table($fid)->get($rid);
if ($row && $row['url']) {
$url = $row['url'];
}
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(number_format($post['money'], 2, '.', ''));
$post['mark'] = dr_safe_filename($post['mark']);
$post['type'] = dr_safe_filename($post['type']);
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 = '';
// 挂钩点 提交之前
\Phpcmf\Hooks::trigger('pay_post_before', $post);
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('充值不能使用余额支付'));
} elseif (floatval($post['money']) <= 0) {
return dr_return_data(0, dr_lang('金额不规范'));
}
break;
// 金币充值
case 'score':
if (!$post['uid']) {
return dr_return_data(0, dr_lang('付款账号不存在'));
}
$money = (int)$post['money'];
if (\Phpcmf\Service::C()->member_cache['pay']['score_min'] && $money < \Phpcmf\Service::C()->member_cache['pay']['score_min']) {
return dr_return_data(0, dr_lang('系统最小充值%s为%s', SITE_SCORE, \Phpcmf\Service::C()->member_cache['pay']['score_min']));
} elseif ($money == 0) {
return dr_return_data(0, dr_lang('金额不规范'));
}
$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 'group':
// 来自用户组
$money = (float)$post['money'];
if ($money <= 0) {
return dr_return_data(0, dr_lang('金额[%s]不规范', $money));
}
$title = $post['title'];
$money = -$money;
$touid = 0; // 收款方为统系
$tousername = ''; // 收款方为统系
break;
case 'level':
// 来自用户组等级
$money = (float)$post['money'];
if ($money <= 0) {
return dr_return_data(0, dr_lang('金额[%s]不规范', $money));
}
$title = $post['title'];
$money = -$money;
$touid = 0; // 收款方为统系
$tousername = ''; // 收款方为统系
break;
case 'gathering':
// 来自收款
$row = $this->table(dr_safe_replace($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, 'pay_after')) {
$rt = $obj->pay_after($fid, $num, $sku, SITE_ID);
if ($rt) {
return dr_return_data(0, $rt);
}
}
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]未定义'));
}
if (method_exists($obj, 'save_result')) {
$rt = $obj->save_result($fid, $num, $sku, SITE_ID);
if ($rt) {
$post['result'] = $rt;
}
}
$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 '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':
// 快速下单 buy-1_book-992-185-1-null" $rname-$rid-$fid- $num-$sku- $ff
$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('未定义的支付方式[%s]', $rname));
break;
}
break;
}
// 判断接口
$apifile = ROOTPATH.'api/pay/'.$post['type'].'/pay.php';
if (!is_file($apifile)) {
return dr_return_data(0, IS_DEV ? dr_lang('支付接口文件(%s)不存在', $post['type']) : dr_lang('支付接口文件不存在'));
}
// 增加流水记录
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' => (string)$post['result'],
'paytime' => 0,
'inputtime' => SYS_TIME,
]);
}
// 调用支付接口
public function dopay($apifile, $data) {
$id = $data['id']; // 支付记录的id
// 生成唯一支付id 接口使用
$sn = $pid = $this->get_pay_sn($data);
// 接口配置参数
$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)) {
CI_DEBUG && log_message('debug', '支付对象('.$name.')类文件('.$classFile.')不存在');
return;
}
return \Phpcmf\Service::M($class, $app);
}
// 清除3天未付款的流水
public function clear_paylog() {
$this->db->table('member_paylog')->where('status', 0)->where('inputtime <'.(SYS_TIME - 3600*24*3))->delete();
}
}