From 4a9d2dd258f50a2cc955d85e7cdd780ff998b898 Mon Sep 17 00:00:00 2001 From: lqmac Date: Sun, 2 Jun 2024 21:01:37 +0800 Subject: [PATCH] 1 --- app/api/service/cashier/Payment.php | 8 +- app/command/ProfitSharing.php | 272 ++++++++++-------- app/common/library/payment/gateway/Driver.php | 4 + .../library/payment/gateway/driver/Wechat.php | 32 ++- .../payment/gateway/driver/wechat/V3.php | 96 +++++++ 5 files changed, 292 insertions(+), 120 deletions(-) diff --git a/app/api/service/cashier/Payment.php b/app/api/service/cashier/Payment.php index 17b51f9c..9d5e0fc1 100644 --- a/app/api/service/cashier/Payment.php +++ b/app/api/service/cashier/Payment.php @@ -123,8 +123,9 @@ class Payment extends BaseService $this->orderInfo = OrderModel::getDetail($this->orderId); // 订单支付事件 $this->orderPayEvent(); + // 构建第三方支付请求的参数 - $payment = $this->unifiedorder($extra,$this->orderInfo['merchantId']); + $payment = $this->unifiedorder($extra,$this->orderInfo->merchant_id); // 记录第三方交易信息 $this->recordPaymentTrade($payment); // 返回结果 @@ -146,8 +147,11 @@ class Payment extends BaseService if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { return false; } + //新增获取商户的支付配置问题 + $trade = PaymentTradeModel::where('out_trade_no', $outTradeNo)->find(); + $orderInfo = OrderModel::where('trade_id', $trade['trade_id'] ?? 0)->field('merchant_id')->find(); // 获取支付方式的配置信息 - $options = $this->getPaymentConfig(); + $options = $this->getPaymentConfig($orderInfo['merchant_id'] ?? 0); // 构建支付模块 $Payment = PaymentFacade::store($this->method)->setOptions($options, $this->client); // 执行第三方支付查询API diff --git a/app/command/ProfitSharing.php b/app/command/ProfitSharing.php index 64856645..94a8cef3 100644 --- a/app/command/ProfitSharing.php +++ b/app/command/ProfitSharing.php @@ -18,7 +18,8 @@ use app\common\model\PaymentTemplate; use app\common\model\Payment; use app\common\model\PaymentTrade; use app\common\model\wxapp\Setting; - +use app\common\enum\Client as ClientEnum; +use app\common\library\payment\Facade as PaymentFacade; // /www/server/php/74/bin/php /server/wwwroot/yanzong/think test class ProfitSharing extends Command @@ -48,129 +49,166 @@ class ProfitSharing extends Command } var_dump($stores); foreach ($stores as $store) { - $where = []; - //查询已完成的订单,并且未分账的订单 - $where[] = ['order_status','=', 30]; - $where[] = ['pay_status','=', 20]; - $where[] = ['is_refund','=', 10]; - $where[] = ['is_delete','=', 0]; - $where[] = ['profitsharing_status','=', 0]; - $where[] = ['store_id','=', $store['store_id']]; - $where[] = ['merchant_id','>', 0]; - $orders = Order::where($where) - ->field('order_id,total_price,order_price,pay_price,pay_method,cost_price,merchant_id,store_id,order_status,pay_status,delivery_status,receipt_status,delivery_type,delivery_time,create_time') - ->select(); - // var_dump($orders->toArray()); - // exit(); - if ($orders->isEmpty()) { - echo $store['store_id']."没有已完成的订单要分账".PHP_EOL; - continue; - } - //微信支付订单抽佣给平台、余额支付抽佣给平台,把订单金额记录到商户账上 - foreach ($orders as $order) { - //余额支付 - if ($order->pay_method == PaymentMethodEnum::BALANCE) { - //增加商户支付详情 - $model = \app\store\model\Merchant::detail($order->merchant_id, $order->store_id); - $precent = 1; - if ($model['commission_ratio'] > 0) { - $precent = (1 - $model['commission_ratio'] / 1000); - } - $precentPrice = round($precent * $order->pay_price, 2); - (new merchantPayModel())->addDetail($order, $precentPrice); + try { + $where = []; + //查询已完成的订单,并且未分账的订单 + $where[] = ['order_status','=', 30]; + $where[] = ['pay_status','=', 20]; + $where[] = ['is_refund','=', 10]; + $where[] = ['is_delete','=', 0]; + $where[] = ['profitsharing_status','=', 0]; + $where[] = ['store_id','=', $store['store_id']]; + $where[] = ['merchant_id','>', 0]; + $orders = Order::where($where) + ->field('order_id,total_price,order_price,pay_price,pay_method,cost_price,merchant_id,store_id,order_status,pay_status,delivery_status,receipt_status,delivery_type,delivery_time,create_time,trade_id') + ->select(); + // var_dump($orders->toArray()); + // exit(); + if ($orders->isEmpty()) { + echo $store['store_id']."没有已完成的订单要分账".PHP_EOL; + continue; + } + //微信支付订单抽佣给平台、余额支付抽佣给平台,把订单金额记录到商户账上 + foreach ($orders as $order) { + //余额支付 + if ($order->pay_method == PaymentMethodEnum::BALANCE) { + //增加商户支付详情 + $model = \app\store\model\Merchant::detail($order->merchant_id, $order->store_id); + $precent = 1; + if ($model['commission_ratio'] > 0) { + $precent = (1 - $model['commission_ratio'] / 1000); + } + $precentPrice = round($precent * $order->pay_price, 2); + (new merchantPayModel())->addDetail($order, $precentPrice); - //累计商户余额支付金额 - merchantModel::setIncTotal($order->merchant_id, $precentPrice); + //累计商户余额支付金额 + merchantModel::setIncTotal($order->merchant_id, $precentPrice); - //更新 - $ret = Order::where('order_id',$order->order_id)->update(['profitsharing_status' => 2, 'profitsharing_time' => time()]); - echo "余额支付分账成功".PHP_EOL; - var_dump($ret); - } elseif($order->pay_method == PaymentMethodEnum::WECHAT){//微信支付 - //商户微信支付配置 - $payment = Payment::where('store_id', $order->store_id)->where('merchant_id', $order->merchant_id)->where('method',PaymentMethodEnum::WECHAT)->where('is_enable', 1)->find(); - if (!$payment) { - echo $store['store_id']."微信支付方式没有配置".PHP_EOL; - continue; - } - $payment_template = PaymentTemplate::where('template_id', $payment->template_id)->where('is_delete', 1)->find(); - if (!$payment_template) { - echo $store['store_id'].$payment->template_id."微信支付模版没有配置".PHP_EOL; - continue; - } - $wechat_config = $payment_template['config'] ? json_decode($payment_template['config'], true) : []; - if (!$wechat_config) { - echo $store['store_id'].$payment->template_id."微信支付模版没有配置11".PHP_EOL; - continue; - } - $wechat_config = $wechat_config['wechat']['normal'] ?? []; - //小程序配置 - $mini = Setting::where('store_id', $order->store_id)->find(); - if (!$mini) { - echo $store['store_id']."小程序配置没有".PHP_EOL; - continue; - } - $mini_config = $mini['values'] ? json_decode($mini['config'], true) : []; - if (!$mini_config) { - echo $store['store_id'].$payment->template_id."微信支付模版没有配置11".PHP_EOL; - continue; - } - //分账 - $config = [ - 'app_id' => $mini_config['app_id'], - "secret" => $mini_config['app_secret'], - 'mch_id' => $wechat_config['mchId'], - 'key' => $wechat_config['apiKey'], - 'cert_path' => PaymentTemplateModel::realPathCertFile(PaymentMethodEnum::WECHAT, $wechat_config['apiclientCert'], $order->store_id), - 'key_path' => PaymentTemplateModel::realPathCertFile(PaymentMethodEnum::WECHAT, $wechat_config['apiclientKey'], $order->store_id), - 'notify_url' => '', - ]; - $payment = Factory::payment($config); - - //平台微信支付配置信息 - $platform_payment = Payment::where('store_id', $order->store_id)->where('merchant_id', 0)->where('method',PaymentMethodEnum::WECHAT)->where('is_enable', 1)->find(); - if (!$platform_payment) { - echo $store['store_id']."微信支付方式没有配置".PHP_EOL; - continue; - } - $platform_payment_template = PaymentTemplate::where('template_id', $platform_payment->template_id)->where('is_delete', 1)->find(); - if (!$platform_payment_template) { - echo $store['store_id'].$platform_payment->template_id."微信支付模版没有配置".PHP_EOL; - continue; - } - $platform_wechat_config = $platform_payment_template['config'] ? json_decode($payment_template['config'], true) : []; - if (!$platform_wechat_config) { - echo $store['store_id'].$platform_payment->template_id."微信支付模版没有配置11".PHP_EOL; - continue; - } - $platform_wechat_config = $platform_wechat_config['wechat']['normal'] ?? []; + //更新 + $ret = Order::where('order_id',$order->order_id)->update(['profitsharing_status' => 2, 'profitsharing_time' => time()]); + echo "余额支付分账成功".PHP_EOL; + var_dump($ret); + } elseif($order->pay_method == PaymentMethodEnum::WECHAT){//微信支付 + //商户微信支付配置 + $payment = Payment::where('store_id', $order->store_id)->where('merchant_id', $order->merchant_id)->where('method',PaymentMethodEnum::WECHAT)->where('is_enable', 1)->find(); + if (!$payment) { + echo $store['store_id']."微信支付方式没有配置".PHP_EOL; + continue; + } + $payment_template = PaymentTemplate::where('template_id', $payment->template_id)->where('is_delete', 0)->find(); + if (!$payment_template) { + echo $store['store_id']." ".$payment->template_id."微信支付模版没有配置".PHP_EOL; + continue; + } + $wechat_config = $payment_template['config'] ?? []; + if (!$wechat_config) { + echo $store['store_id'].$payment->template_id."微信支付模版没有配置11".PHP_EOL; + continue; + } + $wechat_config = $wechat_config['wechat']['normal'] ?? []; + //小程序配置 + $mini = Setting::where('store_id', $order->store_id)->find(); + if (!$mini) { + echo $store['store_id']."小程序配置没有".PHP_EOL; + continue; + } + $mini_config = $mini['values'] ?? []; + if (!$mini_config) { + echo $store['store_id'].$payment->template_id."微信支付模版没有配置11".PHP_EOL; + continue; + } + $PaymentModel = new Payment; + $templateInfo = $PaymentModel->getPaymentInfo(PaymentMethodEnum::WECHAT, ClientEnum::MP_WEIXIN, $order->store_id, $order->merchant_id); + // var_dump($templateInfo); + // exit(); + $options = $templateInfo['template']['config'][PaymentMethodEnum::WECHAT]; + + $payment = PaymentFacade::store(PaymentMethodEnum::WECHAT)->setOptions($options, ClientEnum::MP_WEIXIN); + var_dump($payment); + + //平台微信支付配置信息 + $platform_payment = Payment::where('store_id', $order->store_id)->where('merchant_id', 0)->where('method',PaymentMethodEnum::WECHAT)->where('is_enable', 1)->find(); + if (!$platform_payment) { + echo $store['store_id']."微信支付方式没有配置".PHP_EOL; + continue; + } + $platform_payment_template = PaymentTemplate::where('template_id', $platform_payment->template_id)->where('is_delete', 0)->find(); + if (!$platform_payment_template) { + echo $store['store_id'].$platform_payment->template_id."微信支付模版没有配置".PHP_EOL; + continue; + } + $platform_wechat_config = $platform_payment_template['config'] ?? []; + if (!$platform_wechat_config) { + echo $store['store_id'].$platform_payment->template_id."微信支付模版没有配置11".PHP_EOL; + continue; + } + $platform_wechat_config = $platform_wechat_config['wechat']['normal'] ?? []; + + var_dump($order->trade_id); + $payment_trade = PaymentTrade::where('trade_id', $order->trade_id)->field('trade_no')->find(); + if (!$payment_trade) { + echo $store['store_id'].$platform_payment->template_id."没有交易流水号".PHP_EOL; + continue; + } + $model = \app\store\model\Merchant::detail($order->merchant_id, $order->store_id); + + if ($model['commission_ratio'] <= 0) { + echo $order->merchant_id."当前商户无需抽佣".PHP_EOL; + continue; + } + $precent = $model['commission_ratio'] / 1000; + $precentPrice = round($precent * $order->pay_price * 100, 2); + var_dump($precentPrice); + $precentPrice = 100; + if ($precentPrice <= 0) { + echo $order->order_id.":当前订单抽佣金额小于等于0".$precentPrice.PHP_EOL; + continue; + } + var_dump($payment); + $ret = $payment->addReceiver("MERCHANT_ID", $platform_wechat_config['mchId'], "乔善英", "HEADQUARTER"); + exit(); + $transaction_id = $payment_trade->trade_no; + $out_trade_no = "PS".date("YmdHis").mt_rand(1000,9999); + $receivers = [ + [ + "type" => "MERCHANT_ID", + "account" => $platform_wechat_config['mchId'], + "amount" => $precentPrice, + "description" => "分到商户" + ] + ]; + - $payment_trade = PaymentTrade::where('trade_id', $order->trade_id)->field('trade_no')->find(); - if (!$payment_trade) { - echo $store['store_id'].$platform_payment->template_id."没有交易流水号".PHP_EOL; - continue; + //var_dump($receiver); + //var_dump($ret); + var_dump($receivers); + //$sharing = $payment->profit_sharing->share($transaction_id, $out_trade_no, $receivers); + $sharing = $payment->profitsharing($transaction_id, $out_trade_no, $receivers); + var_dump($sharing); + exit; + if ($sharing['return_code'] != "SUCCESS") { + echo $order->order_id.":".$sharing['return_msg'].PHP_EOL; + continue; + } + if ($sharing['result_code'] != "SUCCESS") { + echo $order->order_id.":".$sharing['err_code_des'].PHP_EOL; + continue; + } + var_dump($sharing); + var_dump($sharing->return_code); + var_dump($sharing->result_code); + exit(); + //更新 + $ret = Order::where('order_id',$order->order_id)->update(['profitsharing_status' => 1, 'profitsharing_time' => time(),'out_order_no' => $out_trade_no]); + echo "微信支付分账中".PHP_EOL; + var_dump($ret); } - $transaction_id = $payment_trade->trade_no; - $out_trade_no = "PS".date("YmdHis").mt_rand(1000,9999); - $receivers = [ - [ - "type" => "MERCHANT_ID", - "account" => $platform_wechat_config['mchId'], - "amount" => 1, - "description" => "分到商户" - ] - ]; - $sharing = $payment->profit_sharing->share($transaction_id, $out_trade_no, $receivers); - var_dump($sharing); - var_dump($sharing->return_code); - var_dump($sharing->result_code); - //更新 - $ret = Order::where('order_id',$order->order_id)->update(['profitsharing_status' => 1, 'profitsharing_time' => time(),'out_order_no' => $out_trade_no]); - echo "微信支付分账中".PHP_EOL; - var_dump($ret); } + } catch (Exception $e) { + } + } diff --git a/app/common/library/payment/gateway/Driver.php b/app/common/library/payment/gateway/Driver.php index cf6929c9..d37995b4 100644 --- a/app/common/library/payment/gateway/Driver.php +++ b/app/common/library/payment/gateway/Driver.php @@ -63,6 +63,10 @@ abstract class Driver * @return bool * @throws BaseException */ + abstract public function addReceiver(string $type, string $account, string $name, string $relation_type = "HEADQUARTER", string $custom_relation = ""): bool; + + abstract public function profitsharing(string $transaction_id, string $out_order_no, array $receivers): bool; + abstract public function unify(string $outTradeNo, string $totalFee, array $extra = []): bool; /** diff --git a/app/common/library/payment/gateway/driver/Wechat.php b/app/common/library/payment/gateway/driver/Wechat.php index 690070e2..fa516eb3 100644 --- a/app/common/library/payment/gateway/driver/Wechat.php +++ b/app/common/library/payment/gateway/driver/Wechat.php @@ -49,7 +49,37 @@ class Wechat extends Driver } return $this->app; } - + /* 统一下单API + * @param string $outTradeNo 交易订单号 + * @param string $totalFee 实际付款金额 + * @param array $extra 附加的数据 (需要携带openid) + * @return bool + * @throws BaseException + */ + public function addReceiver(string $type, string $account, string $name, string $relation_type = "HEADQUARTER", string $custom_relation = ""): bool + { + if (!$this->getApp()->setOptions($this->options, $this->client)->addReceiver($type, $account, $name, $relation_type, $custom_relation)) { + $this->setError($this->getApp()->getError()); + return false; + } + return true; + } + /** + * 统一下单API + * @param string $outTradeNo 交易订单号 + * @param string $totalFee 实际付款金额 + * @param array $extra 附加的数据 (需要携带openid) + * @return bool + * @throws BaseException + */ + public function profitsharing(string $transaction_id, string $out_order_no, array $receivers): bool + { + if (!$this->getApp()->setOptions($this->options, $this->client)->profitsharing($transaction_id, $out_order_no, $receivers)) { + $this->setError($this->getApp()->getError()); + return false; + } + return true; + } /** * 统一下单API * @param string $outTradeNo 交易订单号 diff --git a/app/common/library/payment/gateway/driver/wechat/V3.php b/app/common/library/payment/gateway/driver/wechat/V3.php index c0d9d7d8..c28c24b7 100644 --- a/app/common/library/payment/gateway/driver/wechat/V3.php +++ b/app/common/library/payment/gateway/driver/wechat/V3.php @@ -63,7 +63,85 @@ class V3 $this->config = $this->getConfig($options); return $this; } + public function addReceiver(string $type, string $account, string $name, string $relation_type = "HEADQUARTER", string $custom_relation = ""): bool{ + //是否解冻剩余未分资金,暂时请求分账即解冻,后续可看需求调整 + $unfreeze_unsplit = true; + // 下单的参数 + $params = [ + 'type' => $type, + 'account' => $account, + 'name' => $name, + 'relation_type' => $relation_type, + //'custom_relation' => $custom_relation, + ]; + + // 普通商户参数和服务商支付参数 + if ($this->isProvider()) { + $params['sp_appid'] = $this->config['app_id']; + $params['sp_mchid'] = $this->config['mch_id']; + $params['sub_appid'] = $this->config['sub_appid']; + $params['sub_mchid'] = $this->config['sub_mchid']; + } else { + $params['appid'] = $this->config['app_id']; + $params['mchid'] = $this->config['mch_id']; + } + + try { + // 统一下单API + // Doc: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml + $resp = $this->getApp() + ->chain($this->getAddReceiverUrl()) + ->post(['json' => $params]); + // 记录api返回的数据 + $unifyResult = helper::jsonDecode((string)$resp->getBody()); + var_dump($unifyResult);exit; + return true; + } catch (\Throwable $e) { + // 异常处理 + $message = $this->getThrowMessage($e); + $this->throwError('profitsharing', "微信支付分账添加分账人:{$message}"); + } + return false; + } + public function profitsharing(string $transaction_id, string $out_order_no, array $receivers): bool{ + //是否解冻剩余未分资金,暂时请求分账即解冻,后续可看需求调整 + $unfreeze_unsplit = true; + // 下单的参数 + $params = [ + 'out_order_no' => $out_order_no, + 'transaction_id' => $transaction_id, + 'receivers' => $receivers, + 'unfreeze_unsplit' => $unfreeze_unsplit, + ]; + // 普通商户参数和服务商支付参数 + if ($this->isProvider()) { + $params['sp_appid'] = $this->config['app_id']; + $params['sp_mchid'] = $this->config['mch_id']; + $params['sub_appid'] = $this->config['sub_appid']; + $params['sub_mchid'] = $this->config['sub_mchid']; + } else { + $params['appid'] = $this->config['app_id']; + $params['mchid'] = $this->config['mch_id']; + } + + try { + // 统一下单API + // Doc: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml + $resp = $this->getApp() + ->chain($this->getProfitUrl()) + ->post(['json' => $params]); + // 记录api返回的数据 + $unifyResult = helper::jsonDecode((string)$resp->getBody()); + var_dump($unifyResult);exit; + return true; + } catch (\Throwable $e) { + // 异常处理 + $message = $this->getThrowMessage($e); + $this->throwError('profitsharing', "微信支付分账失败:{$message}"); + } + return false; + } /** * 统一下单API * @param string $outTradeNo 交易订单号 @@ -636,4 +714,22 @@ class V3 { return 'v3/transfer/batches'; } + + /** + * 分账API的Url + * @return string + */ + private function getProfitUrl(): string + { + return 'v3/profitsharing/orders'; + } + /** + * 分账API的Url + * @return string + */ + private function getAddReceiverUrl(): string + { + return 'v3/profitsharing/receivers/add'; + } + } \ No newline at end of file