Browse Source

Merge branch 'master' of ssh://8.134.10.79:222/Leadfyy.co/hainan

master
Lemon 4 years ago
parent
commit
c90bd8dcfb
  1. 31
      MySQL_change.sql
  2. 15
      app/Admin/Controllers/SupplierController.php
  3. 2
      app/Admin/Extensions/Grid/AuditIndustryProduct.php
  4. 3
      app/Admin/Forms/Setting.php
  5. 2
      app/AdminAgent/Controllers/IndustryOrderController.php
  6. 110
      app/AdminSettled/Controllers/SupplierController.php
  7. 2
      app/AdminSettled/routes.php
  8. 44
      app/AdminSupplier/Controllers/ProductController.php
  9. 2
      app/Http/Controllers/Api/AgentProductController.php
  10. 9
      app/Http/Controllers/Api/OrderController.php
  11. 4
      app/Http/Controllers/Api/TestController.php
  12. 199
      app/Http/Controllers/Api/WxpayController.php
  13. 133
      app/Http/Controllers/IndustryProductWxpay.php
  14. 13
      app/Models/SettledOrder.php
  15. 5
      app/Models/Supplier.php
  16. 1
      config/admin-settled.php
  17. 9
      routes/api.php

31
MySQL_change.sql

@ -319,3 +319,34 @@ ALTER TABLE `products`
# 10:43 ‎2021/‎10/‎18
ALTER TABLE `industry_orders`
CHANGE COLUMN `trade_deposit` `trade_deposit` DECIMAL(20,2) NOT NULL DEFAULT '0.00' COMMENT '需要扣除的交易金' AFTER `prepay_timeout`;
# 15:15 ‎2021/‎10/‎18
ALTER TABLE `agent_product_specs`
CHANGE COLUMN `product_spec_id` `product_spec_id` BIGINT(19) UNSIGNED NOT NULL COMMENT '供应商产品规格ID' AFTER `agent_product_id`;
# 16:20 ‎2021/‎10/‎18
ALTER TABLE `order_product_items`
CHANGE COLUMN `price` `price` DECIMAL(20,2) NOT NULL COMMENT '供应商成本价(成本单价*数量)' AFTER `num`;
# 11:53 ‎2021/‎10/‎19
CREATE TABLE `settled_orders` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`order_no` CHAR(22) NOT NULL COMMENT '订单号' COLLATE 'utf8_general_ci',
`username` VARCHAR(120) NOT NULL COMMENT '用户名' COLLATE 'utf8_general_ci',
`user_type` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '用户类型,1供应商,2代理商,3地接',
`transaction_id` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '微信支付订单号' COLLATE 'utf8mb4_general_ci',
`money` DECIMAL(20,2) NOT NULL DEFAULT '0.00' COMMENT '应付入驻费',
`paid_money` DECIMAL(20,2) NOT NULL DEFAULT '0.00' COMMENT '实际支付费用(微信回调后存入)',
`paid_at` TIMESTAMP NULL DEFAULT NULL COMMENT '支付时间',
`status` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '状态,0未支付,1已支付',
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `username_user_type` (`username`, `user_type`) USING BTREE,
UNIQUE INDEX `order_no` (`order_no`) USING BTREE
)
COMMENT='商家入驻支付记录'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

15
app/Admin/Controllers/SupplierController.php

@ -23,7 +23,7 @@ class SupplierController extends AdminController
*/
protected function grid()
{
return Grid::make(new Supplier(), function (Grid $grid) {
return Grid::make(new Supplier(['settledOrder']), function (Grid $grid) {
$grid->disableDeleteButton();
$grid->disableRowSelector();
@ -34,16 +34,19 @@ class SupplierController extends AdminController
$grid->model()->where('id', '>', 1); //隐藏ID=1的领峰云管理员
$grid->column('id')->sortable();
$grid->column('username');
$grid->column('username')->limit(10);
// $grid->column('name');
$grid->column('company_name');
$grid->column('company_name')->limit(10);
$grid->column('license')->image('', 60, 60);
$grid->column('address');
$grid->column('address')->limit(10);
$grid->column('business_license')->image('', 60,60);
$grid->column('director');
$grid->column('contact_phone');
//$grid->column('rate')->editable()->help('分成百分比,如10%,则输入10');
$grid->column('created_at');
$grid->column('cost', '已付入驻费')
->help('该供应商已支付的入驻费(入驻时微信支付的费用)')
->if(fn() => !empty($this->settledOrder->paid_money))
->display(fn() => $this->settledOrder->paid_money ?? 0)->label('success');
$grid->column('created_at', '注册时间');
$grid->column('status', '状态')
->if(fn() => $this->status == UserStatus::UNAUDITED)

2
app/Admin/Extensions/Grid/AuditIndustryProduct.php

@ -45,7 +45,7 @@ class AuditIndustryProduct extends RowAction
}
$industry->status = $status;
$industry->single_deposit = 0; //TODO 交易金单价由前台审核时输入,代理商购买时还要存入行业产品订单表
$industry->single_deposit = 0;
$industry->save();
return $this->response()->success("审核成功")->refresh();

3
app/Admin/Forms/Setting.php

@ -29,7 +29,8 @@ class Setting extends Form
public function form()
{
$this->tab('入驻配置', function () {
$this->number('settled_supplier_cost', '供应商入驻费(元)')->min(0)->default(0)->required();
$this->decimal('settled_supplier_cost', '供应商入驻费(元)')
->rules('numeric|min:0', ['*' => '请输入正确的金额'])->default(0)->required();
$this->file('settled_supplier_contract', '供应商入驻合同')->uniqueName()->autoUpload()->required()
->help('建议为doc/docx/pdf格式,供应商可在入驻页面下载后打印');
$this->file('settled_supplier_agreement', '供应商入驻协议')->uniqueName()->autoUpload()->required()

2
app/AdminAgent/Controllers/IndustryOrderController.php

@ -204,7 +204,7 @@ JS
'app_id' => $config['payee_appid'],
'mch_id' => $config['payee_mchid'],
'key' => $config['payee_mchkey'],
'notify_url' => route('industry_product_wxpay_notify'),
'notify_url' => route('wxpay_industry_product_notify'),
];
$app = Factory::payment($config);

110
app/AdminSettled/Controllers/SupplierController.php

@ -5,10 +5,12 @@ namespace App\AdminSettled\Controllers;
use App\Admin\Repositories\Supplier;
use App\Common\UserStatus;
use App\Models\AdminSetting;
use App\Models\SettledOrder;
use Dcat\Admin\Admin;
use Dcat\Admin\Form;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Widgets\Alert;
use EasyWeChat\Factory;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Storage;
@ -57,6 +59,7 @@ class SupplierController extends AdminController
$form->disableCreatingCheck();
$form->disableEditingCheck();
$form->disableDeleteButton();
$form->text('username')->required();
$form->password('password')->minLength(6)->required();
$form->text('name')->required();
@ -81,7 +84,9 @@ class SupplierController extends AdminController
->script('$(function(){
$(".field_agreement").parent().css("margin-right", 0).after(\'《<a target="_blank" href="'.$agreement_template.'" download="入驻协议">入驻协议</a>》\');
});');
Admin::js('@qrcode');
})->saving(function (Form $form) {
//禁止编辑
if ($form->isEditing()) {
return $form->response()->error('服务器出错了~~');
}
@ -112,9 +117,112 @@ class SupplierController extends AdminController
$form->status = UserStatus::UNAUDITED;
$form->rate = 5;
})->saved(function (Form $form) {
return $form->response()->success('操作成功,请等待管理员审核')->refresh();
$pay = (new SupplierController)->payConfig($form->repository()->model());
if (empty($pay['code_url'])) {
if (isset($pay['result_code'], $pay['err_code_des']) && $pay['result_code'] != 'SUCCESS') {
$msg = $pay['err_code_des'];
} else {
$msg = $pay['return_msg'] ?? '获取支付信息失败';
}
$js = "Dcat.swal.info('支付:$msg', null);";
} else {
$ajax_url = admin_url('is_pay');
$cost = AdminSetting::val('settled_supplier_cost');
$js = <<<JS
Dcat.swal.info(
'<div style="margin-top:1rem;"><div id="qrcode"></div><p style="text-align:center;">入驻费:¥{$cost}元</p></div>',
'<b style="color:red">请微信扫码支付,请勿关闭页面</b>',
{
type: null,
imageWidth: 240,
imageHeight: 240,
animation: false,
// confirmButtonText: '我已完成支付,刷新',
showConfirmButton: false,
allowOutsideClick: false,
allowEscapeKey: false,
onOpen: function () {
$('#qrcode').qrcode({text:'{$pay["code_url"]}', width:240, height:240});
if (window.timer) {
clearInterval(window.timer);
}
window.timer = setInterval(function () {
$.ajax({
url: '$ajax_url',
data: {
username: '{$form->repository()->model()->username}'
},
success: function (res) {
if (res == 1) {
clearInterval(window.timer);
Dcat.swal.success('支付成功,请联系平台审核!', null, {
onClose: function () {
window.location.reload();
}
}).then(() => {
window.location.reload();
});
}
}
});
}, 1000);
}
});
JS;
}
return $form->response()->success('操作成功,请等待管理员审核')->script($js);
})->deleting(function (Form $form) {
return $form->response()->error('服务器出错了~~');
});
}
//付款
private function payConfig($supplier)
{
$setting = AdminSetting::val(['payee_appid', 'payee_mchid', 'payee_mchkey', 'settled_supplier_cost']);
$config = [
'app_id' => $setting['payee_appid'],
'mch_id' => $setting['payee_mchid'],
'key' => $setting['payee_mchkey'],
'notify_url' => route('wxpay_settled_notify'),
];
$app = Factory::payment($config);
//生成订单号
list($micro, $sec) = explode(' ', microtime());
$micro = str_pad(floor($micro * 1000000), 6, 0, STR_PAD_LEFT);
$order_no = date('ymdHis', $sec) . $micro . mt_rand(1000, 9999);
//保存订单记录
SettledOrder::insertOrIgnore([
'order_no' => $order_no,
'user_type' => 1,
'username' => $supplier->username,
'money' => $setting['settled_supplier_cost'],
'status' => 0,
'created_at' => now(),
'updated_at' => now(),
]);
return $app->order->unify([
'product_id' => $supplier->id,
'attach' => $supplier->username,
'body' => mb_strcut($supplier->company_name . ' 供应商入驻', 0, 127),
'out_trade_no' => $order_no,
'total_fee' => round($setting['settled_supplier_cost'] * 100), //支付金额单位为分
'trade_type' => 'NATIVE', // 请对应换成你的支付方式对应的值类型
]);
}
//ajax回调,判断是否已支付
public function isPay(): int
{
$username = request()->input('username');
$order = SettledOrder::where(['username' => $username, 'user_type' => 1])->first();
if (!$order) {
return 0;
}
return (int)$order->status;
}
}

2
app/AdminSettled/routes.php

@ -17,4 +17,6 @@ Route::group([
$router->resource('supplier', 'SupplierController');
$router->resource('agent', 'AgentController');
$router->resource('guide', 'GuideController');
$router->get('is_pay', 'SupplierController@isPay'); //是否支付回调
});

44
app/AdminSupplier/Controllers/ProductController.php

@ -2,12 +2,16 @@
namespace App\AdminSupplier\Controllers;
use App\Admin\Repositories\Order;
use App\AdminSupplier\Repositories\Product;
use App\Common\OrderStatus;
use App\Common\ProductStatus;
use App\Models\AgentProduct;
use App\Models\AgentProductItem;
use App\Models\AgentProductSpec;
use App\Models\Category;
use App\Models\DiyForm;
use App\Models\ProductSpec;
use Dcat\Admin\Admin;
use Dcat\Admin\Form;
use Dcat\Admin\Form\NestedForm;
@ -252,8 +256,16 @@ class ProductController extends AdminController
if (!Admin::user()->publish_type || !in_array($form->type, Admin::user()->publish_type)) {
return $form->response()->error('对不起,你没有此类产品的发布、编辑权限');
}
} else if ($form->isEditing()) { //type不允许编辑
$form->type = $form->model()->type;
} else if ($form->isEditing()) {
$form->type = $form->model()->type; //type不允许编辑
//如果存在未核销的订单不允许编辑
$exists = \App\Models\Order::where('product_id', $form->model()->id)
->whereIn('status', [OrderStatus::PAID, OrderStatus::PAID_RETAINAGE, OrderStatus::OFFLINE_PAID, OrderStatus::REFUSED_REFUND])
->exists();
if ($exists) {
return $form->response()->error('该产品还有未核销的订单,不允许编辑');
}
}
//不允许编辑的字段,忽略字段不起作用?
@ -328,7 +340,33 @@ class ProductController extends AdminController
]);
}
//TODO 还需要规格同步到代理商
$delete_specs = array_filter($form->spec, fn($v) => $v['_remove_'] !== null); //删除的规格
//同步删除代理商规格
AgentProductSpec::whereIn('product_spec_id', array_keys($delete_specs))->delete();
//最新销售价同步到代理商规格
$product_id = $form->getKey();
$agent_product_ids = AgentProduct::where('product_id', $product_id)->pluck('id')->toArray(); //获取当前供应商产品的所有供应商产品ID
$product_specs = ProductSpec::where('product_id', $product_id)->get();
$product_spec_old_ids = $form->model()->spec->pluck('id')->toArray(); //旧的规格ID(不包括新增的)
if ($agent_product_ids && $product_spec_old_ids) {
//将代理商规格价格小于供应商销售价的,设置代理商规格的价格设置为供应商的售价
foreach ($product_specs->whereIn('id', $product_spec_old_ids) as $v) {
AgentProductSpec::whereIn('agent_product_id', $agent_product_ids)
->where([['product_spec_id', '=', $v->id], ['price', '<', $v->price]])
->update(['price' => $v->price]);
}
}
/*if ($product_spec_old_ids) {
$product_spec_new_ids = $product_specs->whereNotIn('id', $product_spec_old_ids)->get()->toArray(); //新增的规格
if ($product_spec_new_ids) {
//暂时不处理新增的规格
}
}*/
}
})->deleting(function (Form $form) {
//不允许删除非自己的数据

2
app/Http/Controllers/Api/AgentProductController.php

@ -47,7 +47,7 @@ round(
)) * 1000),0) AS `distance_m`
SQL));
$fields = ['id', 'sale', 'updated_at', 'price', 'distance_m']; //排序字段 TODO 还有距离排序
$fields = ['id', 'sale', 'updated_at', 'price', 'distance_m']; //排序字段
$field = $fields[$type] ?? $fields[0];
$by = $by == 0 ? 'desc' : 'asc';

9
app/Http/Controllers/Api/OrderController.php

@ -183,12 +183,11 @@ class OrderController extends Controller
return $v;
}, $spec);
//订单总价
$order_price = 0;
$costPrice = 0;
$order_price = 0; //订单总价
$costPrice = 0; //供应商成本总价
foreach ($spec as $v) {
$order_price += $v['price'] * $formData['num'];
$costPrice = bcadd($costPrice,bcmul($v->productSpec->cost_price,$formData['num'],6),6);
$order_price = bcadd($order_price, bcmul($v['price'], $formData['num'], 6), 6);
$costPrice = bcadd($costPrice, bcmul($v['cost_price'], $formData['num'], 6), 6);
}
$order_price = round($order_price, 2);

4
app/Http/Controllers/Api/TestController.php

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Api;
use App\Models\MiniProgramTemplate;
use App\Models\Supplier;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
@ -15,7 +15,7 @@ class TestController
{
public function index()
{
dd(MiniProgramTemplate::find(26)->toArray());
dd(Supplier::with('settledOrder')->find(2)->toArray());
}
/**

199
app/Http/Controllers/Api/WxpayController.php

@ -8,37 +8,47 @@ use App\Models\AdminSetting;
use App\Models\Agent;
use App\Models\AgentProduct;
use App\Models\AgentSetting;
use App\Models\IndustryOrder;
use App\Models\IndustryPayLog;
use App\Models\IndustryProduct;
use App\Models\Order;
use App\Models\Product;
use App\Models\SettledOrder;
use App\Models\UserMoneyLog;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\Exception;
use EasyWeChat\Payment\Kernel\Exceptions\InvalidSignException;
use Illuminate\Support\Facades\DB;
use App\Common\OrderStatus;
use Illuminate\Support\Facades\Log;
class WxpayController
{
//微信支付 支付结果通知网址
public function notify()
private $app = null;
public function __construct()
{
$agent_id = request()->route('agent_id');
// $agent = Agent::find($agent_id);
$setting = AdminSetting::val(['payee_appid', 'payee_mchid', 'payee_mchkey']);
if (!isset($setting['payee_appid'], $setting['payee_mchid'], $setting['payee_mchkey'])) {
return '获取系统配置失败';
}
$config = config('wechat.payment.default');
$config = array_merge($config, [
$config = [
'app_id' => $setting['payee_appid'],
'mch_id' => $setting['payee_mchid'],
'key' => $setting['payee_mchkey'],
]);
$app = Factory::payment($config);
];
$this->app = Factory::payment($config);
}
//微信支付 支付结果通知网址
public function notify()
{
$agent_id = request()->route('agent_id');
// $agent = Agent::find($agent_id);
try {
$response = $app->handlePaidNotify(function ($message, $fail) use ($agent_id) {
$response = $this->app->handlePaidNotify(function ($message, $fail) use ($agent_id) {
//仅测试用,回调记录
DB::table('pay_debugs')->insert(['agent_id' => $agent_id, 'type' => 1, 'content' => json_encode($message)]);
@ -150,7 +160,7 @@ class WxpayController
// 希望微信重试
$fail('Unknown error 2');
});
} catch (InvalidSignException | Exception $e) {
} catch (InvalidSignException | Exception | \Exception $e) {
$this->log($e->getMessage() . $e->getFile() . $e->getLine());
return 'error';
}
@ -164,20 +174,8 @@ class WxpayController
$agent_id = request()->route('agent_id');
// $agent = Agent::find($agent_id);
$setting = AdminSetting::val(['payee_appid', 'payee_mchid', 'payee_mchkey']);
if (!isset($setting['payee_appid'], $setting['payee_mchid'], $setting['payee_mchkey'])) {
return '获取系统配置失败';
}
$config = config('wechat.payment.default');
$config = array_merge($config, [
'app_id' => $setting['payee_appid'],
'mch_id' => $setting['payee_mchid'],
'key' => $setting['payee_mchkey'],
]);
$app = Factory::payment($config);
try {
$response = $app->handleRefundedNotify(function ($message, $reqInfo, $fail) use ($agent_id) {
$response = $this->app->handleRefundedNotify(function ($message, $reqInfo, $fail) use ($agent_id) {
//仅测试用,回调记录
DB::table('pay_debugs')->insert(['agent_id' => $agent_id, 'type' => 2, 'content' => json_encode($message)]);
@ -254,7 +252,7 @@ class WxpayController
$fail('Unknown error 2');
});
} catch (Exception $e) {
} catch (Exception | \Exception $e) {
$this->log($e->getMessage() . $e->getFile() . $e->getLine());
return 'error';
}
@ -274,4 +272,155 @@ class WxpayController
$data .= '[message]: ' . (is_array($write_data) ? json_encode($write_data) : $write_data) . PHP_EOL . PHP_EOL;
file_put_contents($filename, $data, FILE_APPEND);
}
/**
* 行业产品支付回调
*/
public function IndustryProductNotify()
{
try {
$response = $this->app->handlePaidNotify(function ($message, $fail) {
//仅测试用,回调记录
DB::table('pay_debugs')->insert(['agent_id' => -1, 'type' => 1, 'content' => json_encode($message)]);
// 请求成功
if ($message['return_code'] === 'SUCCESS') {
//主要是为了区分定金支付和尾款支付,订单号带有-status后缀,分割后前面才是真正的订单号
$order_no = explode('-', $message['out_trade_no'])[0];
$order = IndustryOrder::query()
->where(['order_no' => $order_no])
->first();
//已经处理过的订单直接返回true
if ($order && in_array($order->status, [OrderStatus::PAID, OrderStatus::PAID_RETAINAGE, OrderStatus::SUCCESS])) {
return true;
}
//判断该微信支付订单号有没有处理过
$exist_log = IndustryPayLog::where([
'agent_id' => $order->agent_id,
'supplier_id' => $order->supplier_id,
'industry_order_id' => $order->id,
'type' => 1,
'transaction_id' => $message['transaction_id'],
])->first();
if ($exist_log) {
return true;
}
// 支付成功
if ($message['result_code'] === 'SUCCESS') {
DB::beginTransaction();
try {
//增加销量,库存在拍下时已经减了
IndustryProduct::query()
->where('id', $order->industry_product_id)
->increment('sale', $order->num);
$old_status = $order->status;
$pay_type = $order->pay_type;
$money = $message['total_fee'] / 100;
//定金支付和首付款支付
if (in_array($pay_type, [PayType::DEPOSIT_PAY, PayType::EARNEST_PAY, PayType::DOWN_PAYMENT])) {
if ($old_status == OrderStatus::UNPAID) {
$order->status = OrderStatus::PAY_EARNEST;
} else if ($old_status == OrderStatus::PAY_EARNEST) {
$order->status = OrderStatus::PAID_RETAINAGE;
$order->verify_code = uniqid(); //生成核销码
}
} else if ($pay_type == PayType::ONLINE) {
$order->status = OrderStatus::PAID;
$order->verify_code = uniqid(); //生成核销码
}
$order->paid_at = now();
$order->paid_money = DB::raw('`paid_money` + ' . $money);
$order->timeout = null;
$order->save();
//资金流水
IndustryPayLog::create([
'agent_id' => $order->agent_id,
'supplier_id' => $order->supplier_id,
'money' => $money,
'industry_order_id' => $order->id,
'type' => 1,
'desc' => DB::raw("LEFT('购买产品:{$order->title}', 250)"),
'transaction_id' => $message['transaction_id'], //微信支付订单号
'created_at' => now(), //模型没有updated_at,无法自动写入时间
'out_trade_no' => $message['out_trade_no'] ?? '',
]);
DB::commit();
return true;
} catch (Exception $e) {
DB::rollBack();
$fail('Unknown error');
}
} // 支付失败
else if ($message['result_code'] === 'FAIL') {
return true;
}
}
// 希望微信重试
$fail('Unknown error 2');
});
} catch (InvalidSignException | Exception | \Exception $e) {
LOG::debug('行业产品支付:', [$e->getFile(), $e->getLine(), $e->getMessage()]);
return 'error';
}
return $response;
}
/**
* 商家入驻支付回调
*/
public function SettledNotify()
{
try {
$response = $this->app->handlePaidNotify(function ($message, $fail) {
//仅测试用,回调记录
DB::table('pay_debugs')->insert(['agent_id' => -2, 'type' => 1, 'content' => json_encode($message)]);
// 请求成功
if ($message['return_code'] === 'SUCCESS') {
$order_no = $message['out_trade_no'];
$order = SettledOrder::query()->where(['order_no' => $order_no])->first();
//已经处理过的订单直接返回true
if ($order && $order->status == 1) {
return true;
}
// 支付成功
if ($message['result_code'] === 'SUCCESS') {
try {
$order->transaction_id = $message['transaction_id'];
$order->paid_money = $message['total_fee'] / 100;
$order->paid_at = now();
$order->status = 1;
$order->save();
return true;
} catch (Exception $e) {
$fail('Unknown error');
}
} // 支付失败
else if ($message['result_code'] === 'FAIL') {
return true;
}
}
// 希望微信重试
$fail('Unknown error 2');
});
} catch (Exception | \Exception $e) {
LOG::debug('商家入驻支付回调:', [$e->getFile(), $e->getLine(), $e->getMessage()]);
return 'error';
}
return $response;
}
}

133
app/Http/Controllers/IndustryProductWxpay.php

@ -1,133 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Common\OrderStatus;
use App\Common\PayType;
use App\Models\AdminSetting;
use App\Models\IndustryOrder;
use App\Models\IndustryPayLog;
use App\Models\IndustryProduct;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\Exception;
use EasyWeChat\Payment\Kernel\Exceptions\InvalidSignException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
/**
* 行业产品微信支付回调
* Class IndustryProductWxpay
* @package App\Http\Controllers
*/
class IndustryProductWxpay
{
public function notify()
{
$setting = AdminSetting::val(['payee_appid', 'payee_mchid', 'payee_mchkey']);
if (!isset($setting['payee_appid'], $setting['payee_mchid'], $setting['payee_mchkey'])) {
return '获取系统配置失败';
}
$config = [
'app_id' => $setting['payee_appid'],
'mch_id' => $setting['payee_mchid'],
'key' => $setting['payee_mchkey'],
];
$app = Factory::payment($config);
try {
$response = $app->handlePaidNotify(function ($message, $fail) {
//仅测试用,回调记录
DB::table('pay_debugs')->insert(['agent_id' => 0, 'type' => 1, 'content' => json_encode($message)]);
// 请求成功
if ($message['return_code'] === 'SUCCESS') {
//主要是为了区分定金支付和尾款支付,订单号带有-status后缀,分割后前面才是真正的订单号
$order_no = explode('-', $message['out_trade_no'])[0];
$order = IndustryOrder::query()
->where(['order_no' => $order_no])
->first();
//已经处理过的订单直接返回true
if ($order && in_array($order->status, [OrderStatus::PAID, OrderStatus::PAID_RETAINAGE, OrderStatus::SUCCESS])) {
return true;
}
//判断该微信支付订单号有没有处理过
$exist_log = IndustryPayLog::where([
'agent_id' => $order->agent_id,
'supplier_id' => $order->supplier_id,
'industry_order_id' => $order->id,
'type' => 1,
'transaction_id' => $message['transaction_id'],
])->first();
if ($exist_log) {
return true;
}
// 支付成功
if ($message['result_code'] === 'SUCCESS') {
DB::beginTransaction();
try {
//增加销量,库存在拍下时已经减了
IndustryProduct::query()
->where('id', $order->industry_product_id)
->increment('sale', $order->num);
$old_status = $order->status;
$pay_type = $order->pay_type;
$money = $message['total_fee'] / 100;
//定金支付和首付款支付
if (in_array($pay_type, [PayType::DEPOSIT_PAY, PayType::EARNEST_PAY, PayType::DOWN_PAYMENT])) {
if ($old_status == OrderStatus::UNPAID) {
$order->status = OrderStatus::PAY_EARNEST;
} else if ($old_status == OrderStatus::PAY_EARNEST) {
$order->status = OrderStatus::PAID_RETAINAGE;
$order->verify_code = uniqid(); //生成核销码
}
} else if ($pay_type == PayType::ONLINE) {
$order->status = OrderStatus::PAID;
$order->verify_code = uniqid(); //生成核销码
}
$order->paid_at = now();
$order->paid_money = DB::raw('`paid_money` + ' . $money);
$order->timeout = null;
$order->save();
//资金流水
IndustryPayLog::create([
'agent_id' => $order->agent_id,
'supplier_id' => $order->supplier_id,
'money' => $money,
'industry_order_id' => $order->id,
'type' => 1,
'desc' => DB::raw("LEFT('购买产品:{$order->title}', 250)"),
'transaction_id' => $message['transaction_id'], //微信支付订单号
'created_at' => now(), //模型没有updated_at,无法自动写入时间
'out_trade_no' => $message['out_trade_no'] ?? '',
]);
DB::commit();
return true;
} catch (Exception $e) {
DB::rollBack();
$fail('Unknown error');
}
} // 支付失败
else if ($message['result_code'] === 'FAIL') {
return true;
}
}
// 希望微信重试
$fail('Unknown error 2');
});
} catch (InvalidSignException | Exception $e) {
LOG::debug('行业产品支付', [$e->getFile(), $e->getLine(), $e->getMessage()]);
return 'error';
}
return $response;
}
}

13
app/Models/SettledOrder.php

@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SettledOrder extends Model
{
use HasFactory;
// protected $guarded = ['id'];
}

5
app/Models/Supplier.php

@ -84,4 +84,9 @@ class Supplier extends BaseModel
{
return $this->belongsTo('App\Models\ChinaArea', 'area_id','code');
}
public function settledOrder()
{
return $this->hasOne(SettledOrder::class, 'username', 'username')->where('user_type', 1);
}
}

1
config/admin-settled.php

@ -153,6 +153,7 @@ return [
'agent/create',
'guide',
'guide/create',
'is_pay',
],
],

9
routes/api.php

@ -21,15 +21,14 @@ use Illuminate\Support\Facades\Route;
# 登录
Route::post('login', 'App\Http\Controllers\Api\LoginController@login');
# 行业产品微信支付回调
Route::any('industry_product/wxpay/notify', 'App\Http\Controllers\IndustryProductWxpay@notify')->name('industry_product_wxpay_notify');
# 微信相关
Route::namespace('App\Http\Controllers\Api')->group(function () {
# 微信支付
Route::prefix('wxpay')->group(function () {
Route::post('notify/{agent_id}', 'WxpayController@notify')->name('wxpay_notify'); //异步通知,aid为代理商ID
Route::post('refund/{agent_id}', 'WxpayController@refund')->name('wxpay_refund'); //退款通知,aid为代理商ID
Route::post('notify/{agent_id}', 'WxpayController@notify')->name('wxpay_notify'); //小程序端支付异步通知
Route::post('refund/{agent_id}', 'WxpayController@refund')->name('wxpay_refund'); //小程序端支付退款通知
Route::post('industry_product_notify', 'WxpayController@IndustryProductNotify')->name('wxpay_industry_product_notify'); //行业产品微信支付回调
Route::post('settled_notify', 'WxpayController@SettledNotify')->name('wxpay_settled_notify'); //商家入驻微信支付回调
});
# 跳转到外部小程序支付

Loading…
Cancel
Save