文件
fenleixinxi/application/api/controller/Order.php
MiAn cb12bf5fc8 feat: 新增地址选择插件及订阅消息等多项功能优化
- 新增地址选择插件,支持地图位置选择并返回地址和经纬度
- 新增微信订阅消息发送功能,支持审核结果、提现通知等场景
- 新增订单支付状态查询、提现收款人姓名保存等接口
- 新增服务区域管理,支持按省市区划分并同步到信息发布
- 新增资金流水和营收报表导出功能
- 新增可用优惠券查询、订单退款拆分处理等功能
- 优化后台角标显示、首页数据统计、UI配置下发等
- 修复订单支付并发问题、地区管理逻辑等
2026-10-22 17:14:56 +08:00

111 行
4.5 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace app\api\controller;
use think\Db;
/**
* 用户端 · 订单(Module-ORDER)
* 路由:
* POST /api/v1/order/recharge 余额充值下单
*
* 说明:充值金额一律由客户端传入后**服务端再次校验**(>0 且 ≤100000),并按 round(...,2) 归一;
* **交易只允许微信支付**:订单落 status=pending,前端调 POST /pay/prepay 调起收银台,
* 支付成功后由 /pay/notify 复用 creditRecharge() 入账(幂等由回调侧 status=paid 保证)。
*
* 【为什么不允许 payType=balance】「用余额充值余额」在本模型里没有任何收款方:余额只会 +amount、
* 不会扣减,等于给用户凭空增发余额(可用余额去买会员/付费发布/解锁联系方式,直接造成资损)。
* v1.1.0 初版曾把它当作「余额即时到账」的演示通道,**已移除**;给用户加余额只应来自
* ① 微信支付回调 creditRecharge(),② 后台「会员管理 → 余额充值」(`fc/userext/recharge`)。
*/
class Order extends V1
{
/**
* POST /api/v1/order/recharge {amount,payType}
* → {orderNo,amount,status:'pending',payType:'wxpay'}
* 规则:金额 >0 且 ≤100000 → 否则 fail('充值金额不合法');
* payType=balance → fail('余额充值仅支持微信支付')(资损防护,见类注释);
* payType 非 wxpay → fail('支付方式不支持')。
*/
public function recharge()
{
$user = $this->auth();
$amount = round((float)$this->input('amount', 0), 2);
if ($amount <= 0 || $amount > 100000) {
$this->fail('充值金额不合法');
}
$payType = (string)$this->input('payType', '');
// 余额「充值」= 用余额给余额加钱(无收款方、余额不扣减)→ 直接拒绝,防资损
if ($payType === 'balance') {
$this->fail('余额充值仅支持微信支付');
}
if ($payType !== 'wxpay') {
$this->fail('支付方式不支持');
}
$now = time();
$orderNo = $this->orderNo('RC');
Db::name('fc_order')->insert([
'order_no' => $orderNo,
'user_id' => $user['id'],
'type' => 'recharge',
'title' => '余额充值',
'amount' => $amount,
'pay_type' => 'wxpay',
'status' => 'pending',
'paytime' => null,
'related_id' => 0,
'createtime' => $now,
'updatetime' => $now,
]);
// 入账只在「微信支付回调 /pay/notify」里发生(Order::creditRecharge),本接口不触碰 fa_user.money
$this->ok([
'orderNo' => $orderNo,
'amount' => $amount,
'status' => 'pending',
'payType' => 'wxpay',
]);
}
/**
* 充值入账(**可复用**:微信支付回调 /pay/notify 入账时调用)
* 动作:fa_user.money 加款 + fc_finance_flow 资金流水 + fc_message 站内信。
* 幂等:调用方需保证「订单未入账」(回调侧以 fc_order.status=paid 做幂等判定)。
* 注意:**不要**在充值下单接口里调用它 —— 未真实收款就加余额属于凭空增发(资损)。
* @param array $order fc_order 行
* @return array{balance:float,amount:float}
*/
public function creditRecharge(array $order)
{
$userId = (int)$order['user_id'];
$amount = round((float)(isset($order['amount']) ? $order['amount'] : 0), 2);
$orderId = (int)(isset($order['id']) ? $order['id'] : 0);
$now = time();
$row = Db::name('user')->where('id', $userId)->find();
if (!$row) {
return ['balance' => 0, 'amount' => $amount];
}
// 原子自增:并发回调/重复入账时不会丢更新(幂等由订单状态保证)
Db::name('user')->where('id', $userId)->setInc('money', $amount);
$balance = round((float)Db::name('user')->where('id', $userId)->value('money'), 2);
Db::name('user')->where('id', $userId)->update(['updatetime' => $now]);
$this->flow('income', '余额充值', $amount, $balance, $orderId, '余额充值');
$this->notify(
$userId,
'system',
'充值成功',
'您已成功充值 ' . number_format($amount, 2) . ' 元,当前余额 ' . number_format($balance, 2) . ' 元。'
);
return ['balance' => $balance, 'amount' => $amount];
}
}