RefillBase.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. <?php
  2. namespace refill;
  3. require_once(BASE_HELPER_PATH . '/queue/rdispatcher.php');
  4. require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
  5. require_once(BASE_HELPER_PATH . '/refill/IRefill.php');
  6. require_once(BASE_HELPER_PATH . '/refill/IRefillOil.php');
  7. require_once(BASE_HELPER_PATH . '/refill/IRefillPhone.php');
  8. require_once(BASE_HELPER_PATH . '/refill/IRefillCallBack.php');
  9. require_once(BASE_HELPER_PATH . '/refill/ProviderManager.php');
  10. require_once(BASE_HELPER_PATH . '/refill/CalcMerchantPrice.php');
  11. require_once(BASE_HELPER_PATH . '/refill/util.php');
  12. require_once(BASE_HELPER_PATH . '/refill/errcode.php');
  13. use Log;
  14. use mtopcard;
  15. use QueueClient;
  16. use member_info;
  17. use Exception;
  18. use trans_wapper;
  19. use Swoole;
  20. class RefillBase
  21. {
  22. protected $mPolicy;
  23. protected $mLimits = [];
  24. protected function __construct($policy)
  25. {
  26. $this->mPolicy = $policy;
  27. }
  28. public function allow($mchid,$card_type,$amount,$quality)
  29. {
  30. return $this->mPolicy->allow($mchid,$card_type,$amount,$quality);
  31. }
  32. public function goods()
  33. {
  34. return $this->mPolicy->goods();
  35. }
  36. public function load()
  37. {
  38. $this->mPolicy->load();
  39. }
  40. public function find_quality(order $order,$skip = false)
  41. {
  42. return $this->mPolicy->find_quality($order,$skip);
  43. }
  44. public function notify($chname, $input)
  45. {
  46. $caller = $this->mPolicy->getCaller($chname);
  47. if($caller === false) {
  48. return false;
  49. }
  50. elseif ($caller->verify($input))
  51. {
  52. [$order_id, $success, $can_try, $need_handle] = $caller->notify($input);
  53. if (!$need_handle) {
  54. return true;
  55. }
  56. if ($order_id !== false) {
  57. return $this->proc_notify($order_id, $success, $can_try, $chname,$input);
  58. } else {
  59. Log::record("{$chname} callback 系统无此订单ID:{$order_id}", Log::ERR);
  60. }
  61. }
  62. else {
  63. $orgdata = json_encode($input);
  64. Log::record("{$chname} 签名失败:input={$orgdata}",Log::ERR);
  65. }
  66. return true;
  67. }
  68. private function proc_notify($order_id,$success, $can_try,$chname,$input=[])
  69. {
  70. $mod_order = Model('vr_order');
  71. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id]);
  72. $order_state = intval($order_info['order_state']);
  73. if ($order_state == ORDER_STATE_PAY)
  74. {
  75. if(!empty($input)) {
  76. Log::record(__METHOD__ . " recv notify when order_state=ORDER_STATE_PAY" ,Log::DEBUG);
  77. Swoole\Coroutine::sleep(5);
  78. util::push_notify($chname,$input);
  79. }
  80. return false;
  81. }
  82. if ($order_state != ORDER_STATE_SEND) {
  83. return false;
  84. }
  85. $logic_vr_order = Logic("vr_order");
  86. $mod_refill = Model('refill_order');
  87. try
  88. {
  89. $tran = new trans_wapper($mod_order,'notify change order state trans');
  90. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id],'*',true,true);
  91. $order_state = intval($order_info['order_state']);
  92. if ($order_state != ORDER_STATE_SEND) {
  93. $tran->commit();
  94. return false;
  95. }
  96. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id,'inner_status' => 0]);
  97. if(empty($refill_info)) {
  98. $tran->commit();
  99. return false;
  100. }
  101. $quality = intval($refill_info['quality']);
  102. $card_type = intval($refill_info['card_type']);
  103. $spec = intval($refill_info['refill_amount']);
  104. $mchid = intval($refill_info['mchid']);
  105. $org_quality = intval($refill_info['org_quality']);
  106. $mch_order = $refill_info['mch_order'];
  107. if ($success) {
  108. util::incr_notify($chname, $card_type, $spec, $quality, true);
  109. util::incr_user_success($mchid,$card_type, $spec,$org_quality);
  110. $logic_vr_order->changeOrderStateSuccess($order_id,true);
  111. util::onOrderSuccess($refill_info,$order_info);
  112. }
  113. elseif ($can_try)
  114. {
  115. util::incr_notify($chname, $card_type, $spec, $quality, false);
  116. util::incr_amount_lock($mchid,$card_type,$spec);
  117. $logic_vr_order->changeOrderStateCancel($order_info, '', "{$chname}接口回调通知失败,正在重试",true,true);
  118. [$can_retry,$params] = $this->retry($refill_info, $order_info);
  119. if ($can_retry)
  120. {
  121. $mod_refill->edit($order_id, ['is_retrying' => 1,'notify_time' => time()]);
  122. $tran->commit();
  123. if(util::push_add($params)) {
  124. return true;
  125. }
  126. }
  127. }
  128. else {
  129. util::incr_notify($chname, $card_type, $spec, $quality, false);
  130. util::incr_amount_lock($mchid,$card_type,$spec);
  131. $logic_vr_order->changeOrderStateCancel($order_info, '', "{$chname}接口回调通知失败,不可重试.",true,true);
  132. }
  133. $tran->commit();
  134. }
  135. catch (Exception $ex) {
  136. $tran->rollback();
  137. Log::record("Error:" . $ex->getMessage(), Log::ERR);
  138. }
  139. if(!$success) {
  140. util::incr_user_fail($mchid,$card_type, $spec,$org_quality);
  141. }
  142. $mod_refill->edit($order_id, ['notify_time' => time(), 'is_retrying' => 0,'notify_state' => 1]);
  143. util::pop_queue_order($mchid,$mch_order);
  144. QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id,'manual' => false]);
  145. return true;
  146. }
  147. private function retry(array $refill_info, array $order_info)
  148. {
  149. $order = order::from_db($refill_info,$order_info);
  150. if($order->is_third()) {
  151. return [false,null];
  152. }
  153. [$org_quality,$quality] = $this->find_quality($order);
  154. if($quality <= 0) {
  155. return [false,null];
  156. }
  157. else {
  158. $params = $order->queue_params();
  159. return [true,$params];
  160. }
  161. }
  162. public function zero_order(order $order,$errmsg='')
  163. {
  164. $buyer_id = $order->buyer_id();
  165. $minfo = new member_info($buyer_id);
  166. $calc = new ZeroMerchantPrice($order->mchid(), $order->spec(), $order->card_type(),$order->cur_quality());
  167. $mch_amount = $calc->calc_vgoods_price([]);
  168. $input['goods_id'] = ZERO_GOODS_ID;
  169. $input['quantity'] = 1; //数量
  170. $input['buyer_phone'] = $minfo->mobile();
  171. $input['buyer_name'] = $minfo->truename();
  172. $input['buyer_msg'] = $_POST['buyer_msg'] ?? '';
  173. $input['order_from'] = 1;
  174. $input['pd_pay'] = true;
  175. $logic_buy_virtual = Logic('buy_virtual');
  176. $result = $logic_buy_virtual->buyStep3($input, $buyer_id, [$calc, 'calc_vorder_amount'], true,false);
  177. $mod_refill = Model('refill_order');
  178. if ($result['state'] === true)
  179. {
  180. $order_sn = $result['data']['order_sn'];
  181. $order_id = $result['data']['order_id'];
  182. $logic_vr_order = Logic("vr_order");
  183. $order_info = Model('vr_order')->getOrderInfo(['order_id' => $order_id]);
  184. $logic_vr_order->changeOrderStateCancel($order_info, '', '无法下单创建0元订单',true,true);
  185. $mch_order = $order->mch_order();
  186. if (empty($mch_order)) {
  187. $order->set_mchorder($order_sn);
  188. }
  189. $thrid_refill = Model('thrid_refill');
  190. if($order->is_third()) {
  191. $product = $thrid_refill->getProduct(['system_code' => $order->pcode()]);
  192. $refill_amount = $product['refill_amount'];
  193. } else {
  194. $refill_amount = $order->spec();
  195. }
  196. //虚拟订单表信息扩展
  197. $orderext = $order->ZeroRefillParams($order_id,$order_sn,$refill_amount,$mch_amount,'',0,$errmsg);
  198. $order->commit_times_inc();
  199. $mod_refill->add_refill($orderext);
  200. if($order->is_third()) {
  201. $thrid_refill = Model('thrid_refill');
  202. $ext = $order->third_extparams($order_id,$order_sn);
  203. $thrid_refill->addExt($ext);
  204. }
  205. return $order_id;
  206. }
  207. else {
  208. return 0;
  209. }
  210. }
  211. //返回值:[ 错误码,错误信息,订单ID,是否是网络错误]
  212. //说明:错误码为true 表示成功
  213. // 其它情况,则需要判断订单ID
  214. public function add(order $order)
  215. {
  216. $last_orderid = $order->last_order_id();
  217. $mchid = $order->mchid();
  218. $mch_order = $order->mch_order();
  219. [$providers, $overload] = $this->mPolicy->find_providers($order);
  220. $chfilters = new channel_filter($mchid,$mch_order,$order->cur_quality(),$order->card_type());
  221. $providers = $chfilters->getProviders($providers);
  222. if (empty($providers)) {
  223. Log::record("canot find any providers", Log::DEBUG);
  224. return [errcode::CANNOT_MATCH_PROVIDER, "匹配不到合适的充值通道", $last_orderid, false, 0];
  225. }
  226. try
  227. {
  228. $minfo = new member_info($order->buyer_id());
  229. $org_quality = $order->org_quality();
  230. if(PolicyUtil::mixed_quality($org_quality)) {
  231. $calc = new CalcMerchantPrice($mchid, $order->spec(), $order->card_type(),$org_quality,$this->mPolicy,$order->thrid_params());
  232. }
  233. else {
  234. $calc = new CalcMerchantPrice($mchid, $order->spec(), $order->card_type(),$order->cur_quality(),$this->mPolicy,$order->thrid_params());
  235. }
  236. $mch_price = $calc->calc_vgoods_price([]);
  237. $mch_amount = $mch_price * $order->quantity();
  238. }
  239. catch (Exception $ex) {
  240. return [errcode::MERCHANT_PRICE_UNSETTING, "没有协商商品价格",$last_orderid,false,0];
  241. }
  242. $available = $minfo->available_predeposit();
  243. if ($mch_amount > $available) {
  244. Log::record("下单时机构余额不足,可用余额为:{$available}", Log::DEBUG);
  245. return [errcode::MERCHANT_SHORT_MONEY, "余额不足支付订单",$last_orderid,false,0];
  246. }
  247. $refill_state = false;
  248. $order_success = false;
  249. $net_errno = 0;
  250. foreach ($providers as $provider)
  251. {
  252. $channel_name = $provider->name();
  253. [$goods_id, $price] = $provider->goods($order->cur_quality(),$order->spec(),$order->card_type(),$order->region_no(),$order->thrid_params());
  254. if ($goods_id <= 0) continue;
  255. //非组合通道,以原始质量算价格. //通道价格大于客户价格,换通道.
  256. if(PolicyUtil::mixed_quality($org_quality) == false && $price > $mch_price) {
  257. continue;
  258. }
  259. $mod_refill = Model('refill_order');
  260. $channel_amount = $price * $order->quantity();
  261. [$order_success,$order_id,$order_sn] = $this->create_refill_order($order,$goods_id,$minfo,$calc,$channel_name,$channel_amount,$mch_amount);
  262. $last_orderid = $order_id;
  263. if(!$order_success) continue;
  264. util::incr_commit_pre($channel_name, $order->card_type(), $order->spec(), $order->cur_quality());
  265. util::decr_amount_lock($mchid, $order->card_type(), $order->spec());
  266. $start = microtime(true);
  267. $net_errno = "";
  268. $params = $order->channel_params($order_id,$order_sn,$goods_id);
  269. $card_no = $order->card_no();
  270. $card_type = $order->card_type();
  271. $spec = $order->spec();
  272. $quality = $order->cur_quality();
  273. [$state, $errmsg, $neterr] = $provider->add($card_no, $card_type, $spec, $params,$net_errno);
  274. Log::record(sprintf(" %s add request time=%.6f", $channel_name,microtime(true) - $start), Log::DEBUG);
  275. if ($state)
  276. {
  277. $chfilters->add_channel($channel_name,true);
  278. util::incr_commit($channel_name,$card_type,$spec,$quality,true);
  279. $trade_no = $errmsg;
  280. $refill_type = $provider->refill_type();
  281. if ($refill_type == 'api') {
  282. $logic_vr_order = Logic("vr_order");
  283. $logic_vr_order->changeOrderStateSend($order_id,true);
  284. } elseif($refill_type == 'fetch') {
  285. $logic_vr_order = Logic("vr_order");
  286. $logic_vr_order->changeOrderStateSend($order_id,true);
  287. $order_info = Model('vr_order')->getOrderInfo(['order_id' => $order_id]);
  288. $mod_fetch_order = Model('fetch_order');
  289. $fetch_datas = ['order_id' => $order_id, 'order_sn' => $order_sn, 'store_id' => $order_info['store_id'],'channel_name' => $channel_name,
  290. 'fetch_status' => 1, 'card_no' => $card_no, 'card_type' => $card_type, 'refill_amount' => $spec,
  291. 'add_time' => time()];
  292. $mod_fetch_order->add($fetch_datas);
  293. }
  294. else {
  295. Log::record("Err refill_type = {$refill_type}",Log::ERR);
  296. }
  297. $data = ['commit_time' => time(), 'ch_trade_no' => $trade_no];
  298. $mod_refill->edit($order_id, $data);
  299. $refill_state = true;
  300. //如果对方没有回调能力,则启动主动查询.
  301. if($provider->callback() === false) {
  302. QueueClient::async_push("QueryRefillState",['order_id' => $order_id],60);
  303. }
  304. break;
  305. }
  306. else
  307. {
  308. $chfilters->add_channel($channel_name,false);
  309. if(!empty($neterr) && util::need_check($net_errno)) {
  310. $mod_refill->edit($order_id, ['commit_time' => time(),'neterr' => 1,'err_msg' => "neterr={$net_errno}"]);
  311. break;
  312. } else {
  313. $neterr = false;
  314. $net_errno = 0;
  315. }
  316. util::incr_commit($channel_name,$card_type,$spec,$order->cur_quality(),false);
  317. util::incr_amount_lock($mchid,$card_type,$spec);
  318. Log::record("channel:{$channel_name} err:{$errmsg}");
  319. $logic_vr_order = Logic("vr_order");
  320. $order_info = Model('vr_order')->getOrderInfo(['order_id' => $order_id]);
  321. $logic_vr_order->changeOrderStateCancel($order_info, '', "调用{$channel_name}接口失败",true,true);
  322. if(!is_string($errmsg)) {
  323. $errmsg = "{$errmsg}";
  324. }
  325. $mod_refill->edit($order_id, ['commit_time' => time(),'err_msg' => $errmsg]);
  326. }
  327. }
  328. if ($refill_state) {
  329. return [true, '', $last_orderid, false, 0];
  330. } elseif ($order_success) {
  331. return [errcode::MERCHANT_REFILL_ERROR, "充值失败", $last_orderid, $neterr, $net_errno];
  332. } else {
  333. return [errcode::MERCHANT_REFILL_ERROR, "充值失败", $last_orderid, false, 0];
  334. }
  335. }
  336. private function create_refill_order(order $order,$goods_id,$minfo,$calc,$ch_name,$ch_amount,$mch_amount)
  337. {
  338. try
  339. {
  340. $fTrans = false;
  341. $logic_buy_virtual = Logic('buy_virtual');
  342. $mod_refill = Model('refill_order');
  343. if($fTrans) {
  344. $trans = new trans_wapper($mod_refill,__METHOD__);
  345. } else {
  346. $start = microtime(true);
  347. }
  348. $input['goods_id'] = $goods_id;
  349. $input['quantity'] = $order->quantity();
  350. $input['buyer_phone'] = $minfo->mobile();
  351. $input['buyer_name'] = $minfo->truename();
  352. $input['buyer_msg'] = $_POST['buyer_msg'] ?? '';
  353. $input['order_from'] = 1;
  354. $input['pd_pay'] = true;
  355. $result = $logic_buy_virtual->buyStep3($input, $order->buyer_id(), [$calc, 'calc_vorder_amount'], true, false);
  356. if ($result['state'] === true)
  357. {
  358. $order_sn = $result['data']['order_sn'];
  359. $order_id = $result['data']['order_id'];
  360. $last_orderid = $order->last_order_id();
  361. if($last_orderid > 0) {
  362. $mod_refill->edit($last_orderid, ['inner_status' => 1]);
  363. }
  364. $order->set_last_orderid($order_id);
  365. $thrid_refill = Model('thrid_refill');
  366. if($order->is_third()) {
  367. $product = $thrid_refill->getProduct(['system_code' => $order->pcode()]);
  368. $refill_amount = $product['refill_amount'];
  369. } else {
  370. $refill_amount = $order->spec();
  371. }
  372. if(empty($order->mch_order())) {
  373. $order->set_mchorder($order_sn);
  374. }
  375. $order->commit_times_inc();
  376. $orderext = $order->refill_params($order_id,$order_sn,$refill_amount, $ch_name, $ch_amount,$mch_amount);
  377. $mod_refill->add_refill($orderext);
  378. if($order->is_third()) {
  379. $ext = $order->third_extparams($order_id,$order_sn);
  380. $thrid_refill->addExt($ext);
  381. }
  382. if(!$this->pay_completed($order_sn))
  383. {
  384. $logic_vr_order = Logic("vr_order");
  385. $order_info = Model('vr_order')->getOrderInfo(['order_id' => $order_id]);
  386. $logic_vr_order->changeOrderStateCancel($order_info, '', "预存款不足以支付该订单",true,true);
  387. if($fTrans) {
  388. $trans->commit();
  389. }
  390. return [false,$order_id,$order_sn];
  391. }
  392. elseif($fTrans) {
  393. $trans->commit();
  394. }
  395. else {
  396. Log::record(sprintf(__METHOD__ . " request time=%.6f", microtime(true) - $start), Log::DEBUG);
  397. }
  398. return [true,$order_id,$order_sn];
  399. }
  400. else
  401. {
  402. if ($fTrans) $trans->commit();
  403. Log::record("{$result['msg']}", Log::ERR);
  404. return [false,0,''];
  405. }
  406. }
  407. catch (Exception $ex)
  408. {
  409. Log::record($ex->getMessage(), Log::ERR);
  410. if($fTrans) {
  411. $trans->rollback();
  412. }
  413. return [false,0,''];
  414. }
  415. }
  416. private function pay_completed($order_sn)
  417. {
  418. $logic_payment = Logic('payment');
  419. $order = $logic_payment->getVrOrderInfo($order_sn,'',true);
  420. $api_pay_amount = $order['data']['api_pay_amount'];
  421. return ($api_pay_amount == ncPriceFormat(0.00));
  422. }
  423. public function notify_merchant($order_id,$manual)
  424. {
  425. if ($order_id <= 0) {
  426. return [false, "订单ID小于0"];
  427. }
  428. $vr_order = Model('vr_order');
  429. $refill_order = Model('refill_order');
  430. $order_info = $vr_order->getOrderInfo(['order_id' => $order_id]);
  431. $refill_info = $refill_order->getOrderInfo(['order_id' => $order_id,'inner_status' => 0,'is_retrying' => 0]);
  432. if (empty($order_info) || empty($refill_info)) {
  433. return [false, "无此订单"];
  434. }
  435. //手动通知,之所以不做尝试,是担心客户方状态处理不当
  436. if (!$manual && $refill_info['mch_notify_state'] != 0) {
  437. return [false, "已经通知客户方"];
  438. }
  439. $notify_url = $refill_info['notify_url'];
  440. if (empty($notify_url)) {
  441. $refill_order->edit($order_id, ['mch_notify_state' => 1, 'mch_notify_times' => 0]);
  442. return [false, "回调地址为空"];
  443. }
  444. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  445. $order_state = intval($order_info['order_state']);
  446. if ($order_state !== ORDER_STATE_CANCEL && $order_state !== ORDER_STATE_SUCCESS) {
  447. return [false, "错误的订单状态,不能通知."];
  448. }
  449. $resp = $this->mPolicy->notify($order_info,$refill_info);
  450. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  451. if ($resp) {
  452. $refill_order->edit($order_id, ['mch_notify_state' => 1, 'mch_notify_times' => ['exp', 'mch_notify_times+1']]);
  453. return [true, ""];
  454. }
  455. else
  456. {
  457. $refill_order->edit($order_id, ['mch_notify_times' => ['exp', 'mch_notify_times+1']]);
  458. $times = $refill_info['mch_notify_times'] + 1;
  459. if ($times > 100) {
  460. $refill_order->edit($order_id, ['mch_notify_state' => 2]);
  461. } else {
  462. $period = 5;
  463. QueueClient::async_push("NotifyMerchantComplete", ['order_id' => $order_id,'manual' => false], $period);
  464. }
  465. return [false, "通知{$times}次,失败."];
  466. }
  467. }
  468. public function query($order_id)
  469. {
  470. $mod_order = Model('vr_order');
  471. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id]);
  472. if(empty($order_info)) return false;
  473. $mod_refill = Model('refill_order');
  474. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id,'inner_status' => 0]);
  475. $chname = $refill_info['channel_name'];
  476. if($refill_info['notify_state'] == 1) {
  477. QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id,'manual' => false]);
  478. return true;
  479. }
  480. if($order_info['order_state'] == ORDER_STATE_SEND) {
  481. $query_able = true;
  482. }
  483. else {
  484. $query_able = false;
  485. }
  486. if($query_able)
  487. {
  488. if(empty($chname)) return false;
  489. $provider = $this->mPolicy->provider($chname);
  490. if(empty($provider)) return false;
  491. [$state, $order_state] = $provider->query($refill_info);
  492. if(!$state) {
  493. return false;
  494. }
  495. elseif($order_state == ORDER_STATE_SUCCESS) {
  496. $this->proc_notify($order_id,true,false,$chname);
  497. }
  498. elseif($order_state == ORDER_STATE_CANCEL) {
  499. $this->proc_notify($order_id,false,true,$chname);
  500. }
  501. else {
  502. Log::record("RefillBase::query order_state={$order_state}",Log::DEBUG);
  503. }
  504. }
  505. return true;
  506. }
  507. public function query_net($order_id)
  508. {
  509. $mod_order = Model('vr_order');
  510. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id]);
  511. if(empty($order_info)) return false;
  512. $mod_refill = Model('refill_order');
  513. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id,'inner_status' => 0]);
  514. $chname = $refill_info['channel_name'];
  515. $mchid = $refill_info['mchid'];
  516. $mch_order = $refill_info['mch_order'];
  517. $card_type = intval($refill_info['card_type']);
  518. if($order_info['order_state'] == ORDER_STATE_PAY) {
  519. $query_able = true;
  520. }
  521. else {
  522. $query_able = false;
  523. }
  524. if($query_able)
  525. {
  526. if(empty($chname)) return false;
  527. $provider = $this->mPolicy->provider($chname);
  528. if(empty($provider)) return false;
  529. [$state, $order_state] = $provider->query($refill_info);
  530. if(!$state) {
  531. QueueClient::async_push("QueryOrderNeterr",['order_id' => $order_id],30);
  532. return false;
  533. }
  534. elseif($order_state == ORDER_STATE_SUCCESS || $order_state == ORDER_STATE_CANCEL)
  535. {
  536. $logic_vr_order = Logic("vr_order");
  537. $logic_vr_order->changeOrderStateSend($order_id,true);
  538. $data = ['commit_time' => time()];
  539. $mod_refill->edit($order_id, $data);
  540. QueueClient::async_push("QueryRefillState",['order_id' => $order_id],1);
  541. }
  542. elseif ($order_state == ORDER_STATE_NOEXIST) {
  543. $logic_vr_order = Logic("vr_order");
  544. $logic_vr_order->changeOrderStateCancel($order_info, '', "{$chname}查询订单不存在.",true,true);
  545. $mod_refill->edit($order_id, ['notify_time' => time(), 'notify_state' => 1]);
  546. util::pop_queue_order($mchid,$mch_order);
  547. QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id,'manual' => false]);
  548. }
  549. else {
  550. QueueClient::async_push("QueryOrderNeterr",['order_id' => $order_id],30);
  551. }
  552. }
  553. return true;
  554. }
  555. public function manual_success($order_id)
  556. {
  557. $order_id = intval($order_id);
  558. if($order_id <= 0) return false;
  559. try {
  560. $mod_order = Model('vr_order');
  561. $tran = new trans_wapper($mod_order,'manual_success state trans');
  562. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id],'*',true,true);
  563. if(!empty($order_info) && $order_info['order_state'] == ORDER_STATE_SEND) {
  564. $tran->commit();
  565. $logic_vr_order = Logic("vr_order");
  566. $logic_vr_order->changeOrderStateSuccess($order_id,true);
  567. $refill_order = Model('refill_order');
  568. $refill_order->edit($order_id, ['notify_time' => time(), 'notify_state' => 1,'is_retrying' => 0]);
  569. mtopcard\cards_helper::assign($order_id);
  570. $refill_info = $refill_order->getOrderInfo(['order_id' => $order_id]);
  571. util::pop_queue_order($refill_info['mchid'],$refill_info['mch_order']);
  572. }
  573. else {
  574. $tran->commit();
  575. }
  576. QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id,'manual' => true]);
  577. return true;
  578. }
  579. catch (Exception $ex) {
  580. $tran->rollback();
  581. Log::record("manual_success exception:{$ex->getMessage()}",Log::ERR);
  582. return false;
  583. }
  584. }
  585. public function manual_cancel($order_id)
  586. {
  587. $order_id = intval($order_id);
  588. if($order_id <= 0) return false;
  589. try {
  590. $mod_order = Model('vr_order');
  591. $tran = new trans_wapper($mod_order,'manual_cancel state trans');
  592. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id],'*',true,true);
  593. if(!empty($order_info) && $order_info['order_state'] == ORDER_STATE_SEND) {
  594. $tran->commit();
  595. $logic_vr_order = Logic("vr_order");
  596. $logic_vr_order->changeOrderStateCancel($order_info, '', "后台手动回调通知失败",true,true);
  597. $refill_order = Model('refill_order');
  598. $refill_order->edit($order_id, ['notify_time' => time(), 'notify_state' => 1,'is_retrying' => 0]);
  599. mtopcard\cards_helper::reuse($order_id);
  600. $refill_info = $refill_order->getOrderInfo(['order_id' => $order_id]);
  601. util::pop_queue_order($refill_info['mchid'],$refill_info['mch_order']);
  602. }
  603. else {
  604. $tran->commit();
  605. }
  606. QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id,'manual' => true]);
  607. return true;
  608. }
  609. catch (Exception $ex) {
  610. $tran->rollback();
  611. Log::record("manual_cancel exception:{$ex->getMessage()}",Log::ERR);
  612. return false;
  613. }
  614. }
  615. public function UpdateRatio($ratios)
  616. {
  617. $this->mPolicy->update_ratios($ratios);
  618. }
  619. public function UpdatMchRatios($ratios)
  620. {
  621. $this->mPolicy->update_mchratios($ratios);
  622. }
  623. }