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]; } $balance = round((float)$row['money'] + $amount, 2); Db::name('user')->where('id', $userId)->update([ 'money' => $balance, '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]; } }