/** * 自动还款(从个人钱包扣款) * * @param int $uid 用户编号 * @param number $money 最大还款金额 * * @return 实际还款金额 */ public function autoRepay($uid, $money) { if ($money <= 0) { return true; } $billModel = new \Loan\Model\BillModel(); // 获取当前总共欠下的还款金额 $total_need_repay_money = $billModel->autoRepay($uid); $pay_money = min($money, $total_need_repay_money); if ($money <= 0) { return true; } // 为扣款做好准备 $trade_no = date('YmdHis') . str_pad(mt_rand(0, 9999), 4, '0', STR_PAD_LEFT); $pay_id = M('loan_pay_wallet')->add(['trade_no' => $trade_no, 'created' => time(), 'uid' => $uid, 'money' => $pay_money, 'is_paid' => 0, 'is_success' => 0]); // 执行扣款 $userMoneyModel = new \Common\Model\UserMoneyModel(); $ret = $userMoneyModel->pay($userMoneyModel::SOURCE_LOAN, $trade_no, $uid, $pay_money, '兼职换购还款'); if (!$ret) { system_warn('自动还款失败:' . $userMoneyModel->getError()); return $userMoneyModel->getError(); } M('loan_pay_wallet')->where('id=' . $pay_id)->setField('is_paid', 1); // 执行还款 $total_pay_money = $billModel->autoRepay($uid, $pay_money, $trade_no); if (!$ret) { system_warn('自动还款失败:' . $billModel->getError()); return $billModel->getError(); } M('loan_pay_wallet')->where('id=' . $pay_id)->setField('is_success', 1); return true; }
public function repayResult() { // 将请求保存到日志中,便于调试 $content = file_get_contents(array_pop($_FILES)['tmp_name']); $content = mb_convert_encoding($content, 'UTF-8', 'GBK'); $logModel = M('loan_pay_bank_guilin_notify'); $log_where = ['created_date' => date('Y-m-d'), 'type' => 2]; if ($logModel->where($log_where)->count() <= 0) { // 新增记录 $log_id = $logModel->add($log_where + ['created' => time(), 'ip' => get_client_ip(1), 'content' => $content, 'is_success' => 0]); } else { $this->_repayResultError(NULL, '重复扣款请求!'); } $lines = explode("\n", $content); $first_line = array_shift($lines); // 判断数据是否合法 trim($first_line) or $this->_repayResultError($log_where, '内容为空!'); $pos = 0; $total = []; foreach (['num' => 11, 'money' => 16, 'success_num' => 11, 'success_money' => 16, 'failure_num' => 11, 'failure_money' => 16] as $key => $len) { $text = substr($first_line, $pos, $len); $pos += $len; $total[$key] = number_format($text, $len == 11 ? 0 : 2, '.', ''); } // 首行数据验证 if ($total['num'] != $total['success_num'] + $total['failure_num']) { $this->_repayResultError($log_where, '首行总行数校验失败!'); } if (bccomp($total['money'], $total['success_money'] + $total['failure_money'], 2) != 0) { $this->_repayResultError($log_where, '首行总金额校验失败!'); } $line_format = ['pos' => '10,i', 'id' => '40,s', 'bank_id' => '32,s', 'realname' => '128,s', 'pay_type' => '1,i', 'money_total' => '16,f', 'money_principal' => '16,f', 'money_fee' => '16,f', 'money_delay' => '16,f', 'pay_result' => '2,i', 'pay_money' => '16,f', 'bank_log_id' => '20,s', 'pay_date' => '8,s', 'pay_time' => '6,s', 'remark' => '-0,s']; $list = []; $total_success_money = 0; foreach ($lines as $key => $line) { if (empty(trim($line))) { break; } $row = []; $pos = 0; foreach ($line_format as $field => $info) { list($len, $type) = explode(',', $info); if ($field === 'realname') { preg_match('/^.*?\\s+/', substr($line, $pos), $match); $len = strlen($match[0]); } $row[$field] = trim($len > 0 ? substr($line, $pos, $len) : substr($line, $pos)); $pos += $len; if ($type == 'i') { $row[$field] = intval($row[$field]); } elseif ($type == 'f') { $row[$field] = floatval($row[$field]); } } $total_success_money += $row['pay_money']; $list[] = $row; } // 校验数据 if ($total['num'] != count($list)) { $this->_repayResultError($log_where, '细则总行数校验失败!'); } if (bccomp($total['success_money'], $total_success_money, 2) != 0) { $this->_repayResultError($log_where, '细则总金额校验失败!'); } // 对业务进行处理 $error = []; $success = []; $billModel = new \Loan\Model\BillModel(); foreach ($list as $row) { $result = $row['pay_result']; // 处理不成功 if ($result != 0) { // 除了余额不足,一律发邮件警报 $result == 3 or system_warn('检测到异常的代扣状态:' . print_r($row, true)); $error[] = $row['id'] . ':' . $row['remark']; continue; } // 处理成功 $pay_money = $row['pay_money']; if ($pay_money <= 0) { system_warn('检测到异常的代扣金额:' . print_r($row, true)); continue; } list($order_id, $issue) = explode('-', $row['id']); if (!$billModel->repay($order_id, $issue, $pay_money, 2)) { $error[] = $row['id'] . ':' . $billModel->getError(); } else { $success[] = $row['id']; } } // 更新记录 $success = '成功处理账单:' . implode(',', $success ?: ['无']); if ($error) { $logModel->save($log_where + ['remark' => $success . "\r\n处理失败账单:" . implode("\r\n", $error)]); } else { $logModel->save($log_where + ['is_success' => 1, 'remark' => $success]); } die(date('Y-m-d H:i:s ') . 'true'); }
protected function _paySuccess($pay_id, $money, $alipay_trade_no) { // 验证是否重复操作 $payRow = M('loan_pay_alipay')->find($pay_id); if (!$payRow) { return '此交易记录不存在!'; } if ($payRow['is_action'] > 0) { return true; } if (bccomp($money, $payRow['money'], 2) != 0) { return '支付金额与记录不符!'; } if (!M('loan_pay_alipay')->where(['id' => $pay_id, 'is_action' => $payRow['is_action']])->setField('is_action', 1)) { return true; } $orderModel = new \Loan\Model\OrderModel(); $billModel = new \Loan\Model\BillModel(); $order_id = $payRow['order_id']; $month = $payRow['month']; $issue = $payRow['issue']; $money = $payRow['money']; $order = $orderModel->field('status')->where(['id' => $order_id])->field('status')->find(); if (!$order) { return '订单信息不存在!'; } if ($month == 1) { if ($issue == 0) { // 正常支付首付 if ($order['status'] == $orderModel::STATUS_CHECK_SUCCESS) { return true; } if ($orderModel->firstPay($order_id, 1, $alipay_trade_no)) { return true; } else { return $orderModel->getError(); } } else { // 正常支付指定账单 $bill = M('loan_bill')->field('issue,money_total,status')->where(['order_id' => $order_id, 'issue' => $issue])->find(); if (!$bill) { return '找不到此账单信息!'; } // 判断是否已经支付 if ($bill['status'] == 2) { return true; } if ($billModel->repay($order_id, $issue, $money, 1, $alipay_trade_no)) { return true; } else { return $billModel->getError(); } } } elseif ($month < 0) { return '未知month参数:' . $month; } else { if (!$billModel->repayAll($order_id, $month, $money, 1, $alipay_trade_no)) { return $billModel->getError(); } } return true; }