Withdraw.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Models\Amount;
  4. use App\Models\Store;
  5. use App\Handlers\SignHandler;
  6. use App\Models\WithdrawLog;
  7. use Illuminate\Console\Command;
  8. use Illuminate\Support\Facades\DB;
  9. use Illuminate\Support\Facades\Log;
  10. class Withdraw extends Command
  11. {
  12. /**
  13. * The name and signature of the console command.
  14. *
  15. * @var string
  16. */
  17. protected $signature = 'withdraw';
  18. /**
  19. * The console command description.
  20. *
  21. * @var string
  22. */
  23. protected $description = '定时查询提现状态';
  24. /**
  25. * Create a new command instance.
  26. *
  27. * @return void
  28. */
  29. public function __construct()
  30. {
  31. parent::__construct();
  32. }
  33. /**
  34. * Execute the console command.
  35. *
  36. * @return mixed
  37. */
  38. public function handle()
  39. {
  40. // Log::info('监测查询提现状态定时任务。。。。。');
  41. $amount=Amount::where('status','0')->where('status_code','CREATE_SUCCESS')->where('type',3)->orderBy('id')->limit(50)->get();
  42. // Log::info($amount);
  43. $handler=new SignHandler();
  44. foreach($amount as $key=>$val){
  45. $withdraw_id=$val->transaction_id;
  46. $out_request_no=$val->order_no;
  47. $sub_mchid=Store::withTrashed()->where('is_failure',0)->where('id',$val->store_id)->value('sub_mchid');
  48. // $url='https://api.mch.weixin.qq.com/v3/ecommerce/fund/withdraw/'.$withdraw_id.'?sub_mchid='.$sub_mchid;//查询地址
  49. $url='https://api.mch.weixin.qq.com/v3/ecommerce/fund/withdraw/out-request-no/'.$out_request_no.'?sub_mchid='.$sub_mchid;
  50. $merchant_id=config('wechat.payment.default.mch_id');//商户号
  51. $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号
  52. $mch_private_key=$handler->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文
  53. $timestamp=time();//时间戳
  54. $nonce=$handler->nonce_str();//随机字符串
  55. $body="";
  56. $sign=$handler->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名
  57. $header=[
  58. 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
  59. 'Accept:application/json',
  60. 'User-Agent:' . $merchant_id,
  61. 'Content-Type:application/json',
  62. 'Wechatpay-Serial:' . $handler->getzhengshu()//获取平台证书序列号
  63. ];
  64. $result=$handler->curl($url,'',$header,'GET');
  65. $result=json_decode($result,true);
  66. if(!isset($result['status'])){
  67. Log::info($val->order_no.':提现查询失败,out-request-no:'.$out_request_no.'?sub_mchid:'.$sub_mchid);
  68. // Log::info($result);
  69. continue;
  70. }
  71. DB::transaction(function()use($result,$val,$withdraw_id,$out_request_no,$sub_mchid){
  72. if($result['status']=='SUCCESS'){
  73. $store=Store::withTrashed()->where('is_failure',0)->where('id',$val->store_id)->lockForUpdate()->first();
  74. $start_amount=$store->available_amount;
  75. $store->available_amount -= $val->money;
  76. $store->withdrawal += $val->money;
  77. $store->account -= $result['amount']/100;
  78. $store->save();
  79. $amo = Amount::where('transaction_id',$result['withdraw_id'])->where('order_no',$result['out_request_no'])->where('type',3)->where('status',1)->first();
  80. if(!$amo){
  81. Amount::create([
  82. 'transaction_id'=>$result['withdraw_id'],
  83. 'order_no'=>$result['out_request_no'],
  84. 'store_id'=>$store->id,
  85. 'money'=>$result['amount']/100,
  86. 'type'=>3,//提现
  87. 'status'=>1,
  88. 'status_code'=>$result['status'],
  89. 'service_fee'=>0,
  90. 'remark'=>'提现成功',
  91. 'remark_amount'=>$result['account_type'].'-'.$result['account_number'].'-'.$result['account_bank'].'-'.$store->account_bank.'-'.$store->account_number,
  92. 'account'=>$store->account
  93. ]);
  94. }
  95. Amount::where('id',$val->id)->update(['status_code'=>'SUCCESS']);
  96. // Amount::where('transaction_id',$withdraw_id)
  97. // ->update([
  98. // 'start_money'=>$store->pending_amount,
  99. // 'end_money'=>$store->pending_amount,
  100. // 'start_amount'=>$start_amount,
  101. // 'end_amount'=> $store->available_amount,
  102. // 'status'=>1,
  103. // 'status_code'=>$result['status'],
  104. // 'account'=> $store->account,
  105. // 'actual_money'=> $result['amount']/100
  106. // ]);
  107. }else{
  108. // Log::info($val->order_no.':提现查询失败,out-request-no:'.$out_request_no.'?sub_mchid:'.$sub_mchid);
  109. // Log::info(json_encode($result));
  110. if($result['status']=='FAIL' ||$result['status']=='REFUND' ||$result['status']=='CLOSE'){
  111. $reason=$result['reason'];
  112. }else{
  113. $reason=null;
  114. }
  115. Amount::where('transaction_id',$withdraw_id)
  116. ->update([
  117. 'status'=>0,
  118. 'status_code'=>$result['status'],
  119. 'reason'=>$reason,
  120. ]);
  121. }
  122. WithdrawLog::updateOrCreate(
  123. ['sub_mchid' => $result['sub_mchid'],'sp_mchid' => $result['sp_mchid'],'withdraw_id' => $result['withdraw_id'],'out_request_no' => $result['out_request_no']], //查询条件
  124. [
  125. 'status' => $result['status'],'amount' => $result['amount'],'create_time' => $result['create_time'],'update_time' => $result['update_time'],'reason' => $result['reason'],
  126. 'remark' => $result['remark'],'bank_memo' => $result['bank_memo'],'account_type' => $result['account_type'],'account_number' => $result['account_number'],
  127. 'account_bank' => $result['account_bank'],'bank_name' => array_key_exists('bank_name',$result)?$result['bank_name']:null
  128. ]); //添加或者修改的数据
  129. });
  130. }
  131. }
  132. }