pay_helper.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: stanley-king
  5. * Date: 16/6/4
  6. * Time: 上午11:12
  7. */
  8. require_once(BASE_ROOT_PATH . "/helper/session_helper.php");
  9. require_once(BASE_ROOT_PATH . '/helper/bonus_helper.php');
  10. require_once(BASE_ROOT_PATH . '/helper/account_helper.php');
  11. require_once(BASE_ROOT_PATH . '/helper/pay/IPay.php');
  12. if(defined('SERVER_TYPE') && SERVER_TYPE == 'panda') {
  13. require_once(BASE_ROOT_PATH . '/helper/pay/alipay.php');
  14. }
  15. elseif(defined('SERVER_TYPE') && SERVER_TYPE == 'car') {
  16. require_once(BASE_ROOT_PATH . '/helper/pay/aopay.php');
  17. }
  18. else {
  19. Log::record("没有找到阿里支付密钥",Log::DEBUG);
  20. }
  21. require_once(BASE_ROOT_PATH . '/helper/pay/wxpay.php');
  22. require_once(BASE_ROOT_PATH . '/helper/pay/cmbpay.php');
  23. require_once(BASE_ROOT_PATH . '/helper/pay/jspay.php');
  24. require_once(BASE_ROOT_PATH . '/helper/pay/minipay.php');
  25. require_once(BASE_ROOT_PATH . '/helper/pay/webpay.php');
  26. class pay_helper
  27. {
  28. const WX_PAYMENT = "wxpay";
  29. const ALI_PAYMENT = "alipay";
  30. const CMB_PAYMENT = "cmbpay";
  31. const PUBWX_PAYMENT = "jspay";
  32. const virtual_order = 1;
  33. const real_order = 2;
  34. private $mOrderType;
  35. private $mPaymentLogic;
  36. private $mPaysn;
  37. public function __construct($paysn)
  38. {
  39. $this->mPaymentLogic = Logic('payment');
  40. $order_pay_info = Model('order')->getOrderPayInfo(array('pay_sn' => $paysn),true);
  41. if (empty($order_pay_info)) {
  42. $this->mOrderType = pay_helper::virtual_order;
  43. } else {
  44. $this->mOrderType = pay_helper::real_order;
  45. }
  46. $this->mPaysn = $paysn;
  47. }
  48. public function pay($payment,$usebonus,$usepred,&$err)
  49. {
  50. $usebonus = false;
  51. if($this->mOrderType == self::real_order) {
  52. return $this->real_pay($payment,$usebonus,$usepred,$err);
  53. } else {
  54. return $this->virtual_pay($payment,$usebonus,$usepred,$err);
  55. }
  56. }
  57. private function real_pay($payment,$usebonus,$usepred,&$err)
  58. {
  59. $pay_sn = $this->mPaysn;
  60. $payinfo = $this->mPaymentLogic->getRealOrderInfo($pay_sn, $_SESSION['member_id'],true);
  61. if (intval($payinfo['data']['api_pay_state']) != 0) {
  62. $err = array('code' => errcode::ErrPayment, 'msg' => $payinfo['msg']);
  63. return false;
  64. }
  65. Log::record("payinfo=" . json_encode($payinfo),Log::DEBUG);
  66. $left_cents = intval(doubleval($payinfo['data']['api_pay_amount']) * 100 + 0.5);
  67. if($left_cents == 0)
  68. {
  69. $output['need_pay'] = false;
  70. $output['tips'] = "已经用红包支付完成";
  71. $output['is_virtual'] = false;
  72. $payinfo = $this->update_order($pay_sn, 'bonus'); // 更新订单
  73. if (isset($payinfo) && $payinfo['state'])
  74. {
  75. if(is_pushoms())
  76. {
  77. $logic_delivery = Logic('delivery');
  78. $ret = $logic_delivery->putOrder($pay_sn, $pay_sn);
  79. if(empty($ret)) { //todo must add to 定时任务
  80. Log::record("Put order to oms error: pay_sn={$pay_sn},bonus pay.",Log::ERR);
  81. }
  82. }
  83. $this->OnSuccess();
  84. }
  85. return $output;
  86. }
  87. else {
  88. return $this->third_pay($payment,$payinfo,$left_cents,$err);
  89. }
  90. }
  91. private function virtual_pay($payment,$usebonus,$usepred,&$err)
  92. {
  93. $order_sn = $this->mPaysn;
  94. $payinfo = $this->mPaymentLogic->getVrOrderInfo($order_sn, null,true);
  95. if(!$payinfo['state']) goto onerror;
  96. if ($payinfo['data']['order_state'] != ORDER_STATE_NEW || empty($payinfo['data']['api_pay_amount'])) goto onerror;
  97. $left_cents = intval(doubleval($payinfo['data']['api_pay_amount']) * 100 + 0.5);
  98. if($left_cents == 0)
  99. {
  100. $output['need_pay'] = false;
  101. $output['tips'] = "支付完成";
  102. $output['is_virtual'] = true;
  103. $payinfo = $this->update_order($order_sn, 'bonus'); // 更新订单
  104. if ($payinfo['state']) {
  105. $this->OnSuccess();
  106. }
  107. return $output;
  108. }
  109. else {
  110. return $this->third_pay($payment,$payinfo,$left_cents,$err);
  111. }
  112. onerror:
  113. $err = array('code' => errcode::ErrPayment, 'msg' => $payinfo['msg']);
  114. return false;
  115. }
  116. private function third_pay($payment, $payinfo, $left_cents, &$err)
  117. {
  118. $pay = null;
  119. if($payment == "wxpay") {
  120. $pay = new Pay\wxpay();
  121. }
  122. else if($payment == "jspay")
  123. {
  124. $openid = session_helper::pub_openid();
  125. Log::record("openid = {$openid}",Log::DEBUG);
  126. if(empty($openid)) {
  127. $err = array('code' => errcode::ErrPayment, 'msg' => '微信未授权,不可以进行网页支付.');
  128. return false;
  129. }
  130. else {
  131. $pay = new Pay\jspay($openid);
  132. }
  133. }
  134. else if($payment == "webpay")
  135. {
  136. $openid = session_helper::pub_openid();
  137. $pay = new Pay\webpay($openid);
  138. }
  139. else if($payment == "minipay")
  140. {
  141. $openid = session_helper::pub_openid();
  142. Log::record("openid = {$openid}",Log::DEBUG);
  143. if(empty($openid)) {
  144. $err = array('code' => errcode::ErrPayment, 'msg' => '微信未授权,不可以进行小程序支付.');
  145. return false;
  146. }
  147. else {
  148. $pay = new Pay\minipay($openid);
  149. }
  150. }
  151. else if($payment == "alipay")
  152. {
  153. if(defined('SERVER_TYPE') && SERVER_TYPE == 'panda') {
  154. $pay = new Pay\alipay();
  155. }
  156. elseif(defined('SERVER_TYPE') && SERVER_TYPE == 'car') {
  157. $pay = new Pay\aopay();
  158. }
  159. else {
  160. Log::record("没有找到阿里支付密钥",Log::DEBUG);
  161. }
  162. }
  163. else if($payment == "cmbpay") {
  164. $pay = new Pay\cmbpay();
  165. }
  166. else {
  167. $err = array('code' => errcode::ErrPayment, 'msg' => $payinfo['msg']);
  168. return false;
  169. }
  170. $subject = $payinfo['data']['subject'];
  171. $pay_sn = $payinfo['data']['pay_sn'];
  172. $order_sn = $payinfo['data']['order_sn'];
  173. $output['need_pay'] = true;
  174. $output['tips'] = "";
  175. try{
  176. $third_param = $pay->gen_pay($pay_sn,$left_cents,$order_sn,$subject);
  177. }
  178. catch (Exception $ex) {
  179. Log::record($ex->getTraceAsString(),Log::ERR);
  180. }
  181. $output['param'] = $third_param;
  182. return $output;
  183. }
  184. public function confirm(&$err,&$amount,&$fcode_state)
  185. {
  186. $pay_sn = $this->mPaysn;
  187. if($this->mOrderType == pay_helper::real_order)
  188. {
  189. $result = $this->mPaymentLogic->getRealOrderInfo($pay_sn,null,true);
  190. if(empty($result)) {
  191. $err = ['code'=> errcode::ErrOrder,'msg' => '无此订单.'];
  192. return false;
  193. }
  194. $amount = $result['data']['api_pay_amount'];
  195. $fcode_state = intval($result['data']['fcode_state']);
  196. if (intval($result['data']['api_pay_state']) == 0) {
  197. $err = ['code'=> errcode::ErrOrder,'msg' => '此订单未完成支付.'];
  198. return false;
  199. }
  200. else {
  201. return true;
  202. }
  203. }
  204. else
  205. {
  206. $result = $this->mPaymentLogic->getVrOrderInfo($pay_sn, null,true);
  207. if(!$result['state']) {
  208. $err = ['code'=> errcode::ErrOrder,'msg' => '无此订单.'];
  209. return false;
  210. }
  211. if ($result['data']['order_state'] != ORDER_STATE_NEW) {
  212. $fcode_state = 1;
  213. return true;
  214. } else {
  215. $err = ['code'=> errcode::ErrOrder,'msg' => '订单未完成支付.'];
  216. return false;
  217. }
  218. }
  219. }
  220. public function check_fee($total_fee,&$need_pay)
  221. {
  222. $pay_sn = $this->mPaysn;
  223. if($this->mOrderType == pay_helper::real_order)
  224. {
  225. $result = $this->mPaymentLogic->getRealOrderInfo($pay_sn,null,true);
  226. if (intval($result['data']['api_pay_state']) != 0) {
  227. return false;
  228. }
  229. $need_pay = intval($result['data']['api_pay_amount'] * 100 + 0.5);
  230. $total_fee = intval($total_fee * 100 + 0.5);
  231. return ($need_pay === $total_fee);
  232. }
  233. else
  234. {
  235. $result = $this->mPaymentLogic->getVrOrderInfo($pay_sn);
  236. if(!$result['state']) return false;
  237. $need_pay = intval($result['data']['api_pay_amount'] * 100 + 0.5);
  238. $total_fee = intval($total_fee * 100 + 0.5);
  239. return ($need_pay === $total_fee);
  240. }
  241. }
  242. public function paied()
  243. {
  244. $pay_sn = $this->mPaysn;
  245. if($this->mOrderType == self::real_order)
  246. {
  247. $result = $this->mPaymentLogic->getRealOrderInfo($pay_sn,null,true);
  248. if (intval($result['data']['api_pay_state']) != 0) {
  249. return true;
  250. }
  251. }
  252. else
  253. {
  254. $result = $this->mPaymentLogic->getVrOrderInfo($pay_sn);
  255. if(!$result['state']) return false;
  256. if ($result['data']['order_state'] != ORDER_STATE_NEW) {
  257. return true;
  258. }
  259. }
  260. return false;
  261. }
  262. public function OnSuccess()
  263. {
  264. $pay_sn = $this->mPaysn;
  265. if ($this->mOrderType == self::real_order)
  266. {
  267. $result = $this->mPaymentLogic->getRealOrderInfo($pay_sn,null,true);
  268. if($result['state'] != true) {
  269. return false;
  270. } else {
  271. QueueClient::push('onAsyncOrderPaied',['pay_sn' => $pay_sn]);
  272. return true;
  273. }
  274. }
  275. else
  276. {
  277. $result = $this->mPaymentLogic->getVrOrderInfo($pay_sn,null,true);
  278. if($result['state'] != true) {
  279. return false;
  280. } else {
  281. QueueClient::push('onAsyncOrderPaied',['pay_sn' => $pay_sn]);
  282. return true;
  283. }
  284. }
  285. }
  286. public function update_order($trade_no, $payment)
  287. {
  288. $paysn = $this->mPaysn;
  289. if ($this->mOrderType == self::real_order)
  290. {
  291. $result = $this->mPaymentLogic->getRealOrderInfo($paysn,null,true);
  292. if (intval($result['data']['api_pay_state'])) {
  293. return ['state' => true];
  294. }
  295. $order_list = $result['data']['order_list'];
  296. $result = $this->mPaymentLogic->updateRealOrder($paysn, $payment, $order_list, $trade_no);
  297. }
  298. else
  299. {
  300. $result = $this->mPaymentLogic->getVrOrderInfo($paysn);
  301. if(!$result['state']) {
  302. return ['state' => false];
  303. }
  304. if ($result['data']['order_state'] != ORDER_STATE_NEW) {
  305. return ['state' => true];
  306. }
  307. $result = $this->mPaymentLogic->updateVrOrder($paysn, $payment, $result['data'], $trade_no);
  308. }
  309. return $result;
  310. }
  311. static public function pay_types()
  312. {
  313. //支付宝,微信,招商银行,各自的描述语
  314. $types = [];
  315. $types[] = ["payment" => "wxpay","desc" => ""];
  316. $types[] = ["payment" => "alipay","desc" => ""];
  317. $types[] = ["payment" => "cmbpay","desc" => ""];
  318. return $types;
  319. }
  320. public static function OnOmsNotify($order_sn, $express_id, $logistics_no,$logistics_company)
  321. {
  322. $model_order = Model('order');
  323. $order_info = $model_order->getOrderInfo(array('order_sn' => $order_sn),array('order_common','order_goods'));
  324. $data['reciver_name'] = $order_info['extend_order_common']['reciver_name'];
  325. $data['reciver_info'] = $order_info['extend_order_common']['reciver_info'];
  326. $data['deliver_explain'] = $order_info['extend_order_common']['deliver_explain'];
  327. $data['daddress_id'] = intval($order_info['extend_order_common']['daddress_id']);
  328. $data['shipping_express_id'] =intval($express_id);
  329. $data['shipping_code'] = $logistics_no;
  330. $data['store_id'] = 6;
  331. $logic_order = Logic('order');
  332. $result = $logic_order->changeOrderSend($order_info, 'system', $order_info['buyer_name'], $data);
  333. QueueClient::push('onAsyncOrderSended',
  334. ['pay_sn' => $order_info['pay_sn'],
  335. 'logistics_company' => $logistics_company,
  336. 'logistics_no' => $logistics_no]);
  337. return $result['state'];
  338. }
  339. public static function OnNotify($param,$payment)
  340. {
  341. $pay = self::gen_payment($payment);
  342. if($pay == null) {
  343. return false;
  344. }
  345. $result = $pay->on_notify($param);
  346. if($result != false)
  347. {
  348. $pay_sn = $result['pay_sn'];
  349. $trade_no = $result['trade_no'];
  350. $payer = new pay_helper($pay_sn);
  351. $cb_info = $payer->update_order($trade_no,$payment);
  352. if ($cb_info['state'] == false) {
  353. Log::record("update_order fail: pay_sn={$pay_sn},trade_no={$trade_no}", Log::DEBUG);
  354. return false;
  355. }
  356. else
  357. {
  358. if(is_pushoms()) {
  359. $logic_delivery = Logic('delivery');
  360. $logic_delivery->putOrder($pay_sn, $trade_no);
  361. Log::record("update_order success: pay_sn={$pay_sn}", Log::DEBUG);
  362. }
  363. $payer->OnSuccess();
  364. return true;
  365. }
  366. }
  367. else {
  368. return false;
  369. }
  370. }
  371. private static function gen_payment($payment)
  372. {
  373. if($payment == "wxpay") {
  374. return new Pay\wxpay();
  375. }
  376. else if($payment == "jspay")
  377. {
  378. return new Pay\jspay("");
  379. }
  380. else if($payment == "minipay")
  381. {
  382. return new Pay\jspay("");
  383. }
  384. else if($payment == "alipay") {
  385. return new Pay\alipay();
  386. }
  387. else if($payment == "cmbpay") {
  388. return new Pay\cmbpay();
  389. }
  390. else {
  391. return null;
  392. }
  393. }
  394. }