海南旅游SAAS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
4.2 KiB

4 years ago
4 years ago
4 years ago
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Common\OrderStatus;
  4. use App\Common\PayType;
  5. use App\Models\AdminSetting;
  6. use App\Models\IndustryOrder;
  7. use App\Models\IndustryPayLog;
  8. use App\Models\IndustryProduct;
  9. use EasyWeChat\Factory;
  10. use EasyWeChat\Kernel\Exceptions\Exception;
  11. use EasyWeChat\Payment\Kernel\Exceptions\InvalidSignException;
  12. use Illuminate\Support\Facades\DB;
  13. use Illuminate\Support\Facades\Log;
  14. /**
  15. * 行业产品微信支付回调
  16. * Class IndustryProductWxpay
  17. * @package App\Http\Controllers
  18. */
  19. class IndustryProductWxpay
  20. {
  21. public function notify()
  22. {
  23. $setting = AdminSetting::val(['payee_appid', 'payee_mchid', 'payee_mchkey']);
  24. if (!isset($setting['payee_appid'], $setting['payee_mchid'], $setting['payee_mchkey'])) {
  25. return '获取系统配置失败';
  26. }
  27. $config = [
  28. 'app_id' => $setting['payee_appid'],
  29. 'mch_id' => $setting['payee_mchid'],
  30. 'key' => $setting['payee_mchkey'],
  31. ];
  32. $app = Factory::payment($config);
  33. try {
  34. $response = $app->handlePaidNotify(function ($message, $fail) {
  35. //仅测试用,回调记录
  36. DB::table('pay_debugs')->insert(['agent_id' => 0, 'type' => 1, 'content' => json_encode($message)]);
  37. // 请求成功
  38. if ($message['return_code'] === 'SUCCESS') {
  39. //主要是为了区分定金支付和尾款支付,订单号带有-status后缀,分割后前面才是真正的订单号
  40. $order_no = explode('-', $message['out_trade_no'])[0];
  41. $order = IndustryOrder::query()
  42. ->where(['order_no' => $order_no])
  43. ->first();
  44. //已经处理过的订单直接返回true
  45. if ($order && in_array($order->status, [OrderStatus::PAID, OrderStatus::PAID_RETAINAGE, OrderStatus::SUCCESS])) {
  46. return true;
  47. }
  48. //判断该微信支付订单号有没有处理过
  49. $exist_log = IndustryPayLog::where([
  50. 'agent_id' => $order->agent_id,
  51. 'supplier_id' => $order->supplier_id,
  52. 'industry_order_id' => $order->id,
  53. 'type' => 1,
  54. 'transaction_id' => $message['transaction_id'],
  55. ])->first();
  56. if ($exist_log) {
  57. return true;
  58. }
  59. // 支付成功
  60. if ($message['result_code'] === 'SUCCESS') {
  61. DB::beginTransaction();
  62. try {
  63. //增加销量,库存在拍下时已经减了
  64. IndustryProduct::query()
  65. ->where('id', $order->industry_product_id)
  66. ->increment('sale', $order->num);
  67. $old_status = $order->status;
  68. $pay_type = $order->pay_type;
  69. $money = $message['total_fee'] / 100;
  70. //定金支付和首付款支付
  71. if (in_array($pay_type, [PayType::DEPOSIT_PAY, PayType::EARNEST_PAY, PayType::DOWN_PAYMENT])) {
  72. if ($old_status == OrderStatus::UNPAID) {
  73. $order->status = OrderStatus::PAY_EARNEST;
  74. } else if ($old_status == OrderStatus::PAY_EARNEST) {
  75. $order->status = OrderStatus::PAID_RETAINAGE;
  76. $order->verify_code = uniqid(); //生成核销码
  77. }
  78. } else if ($pay_type == PayType::ONLINE) {
  79. $order->status = OrderStatus::PAID;
  80. $order->verify_code = uniqid(); //生成核销码
  81. }
  82. $order->paid_at = now();
  83. $order->paid_money = DB::raw('`paid_money` + ' . $money);
  84. $order->timeout = null;
  85. $order->save();
  86. //资金流水
  87. IndustryPayLog::create([
  88. 'agent_id' => $order->agent_id,
  89. 'supplier_id' => $order->supplier_id,
  90. 'money' => $money,
  91. 'industry_order_id' => $order->id,
  92. 'type' => 1,
  93. 'desc' => DB::raw("LEFT('购买产品:{$order->title}', 250)"),
  94. 'transaction_id' => $message['transaction_id'], //微信支付订单号
  95. 'created_at' => now(), //模型没有updated_at,无法自动写入时间
  96. 'out_trade_no' => $message['out_trade_no'] ?? '',
  97. ]);
  98. DB::commit();
  99. return true;
  100. } catch (Exception $e) {
  101. DB::rollBack();
  102. $fail('Unknown error');
  103. }
  104. } // 支付失败
  105. else if ($message['result_code'] === 'FAIL') {
  106. return true;
  107. }
  108. }
  109. // 希望微信重试
  110. $fail('Unknown error 2');
  111. });
  112. } catch (InvalidSignException | Exception $e) {
  113. LOG::debug('行业产品支付', [$e->getFile(), $e->getLine(), $e->getMessage()]);
  114. return 'error';
  115. }
  116. return $response;
  117. }
  118. }