PayLogic.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. <?php
  2. /**
  3. * PayLogic.php UTF-8
  4. * 支付处理逻辑
  5. *
  6. * @date : 2018/2/1 15:55
  7. *
  8. * @license 这不是一个自由软件,未经授权不许任何使用和传播。
  9. * @author : linjiebin <ljb@huosdk.com>
  10. * @version : HUOSDK 8.0
  11. */
  12. namespace web\pc\logic;
  13. use huo\model\common\CommonModel;
  14. use think\Session;
  15. use think\Request;
  16. use think\Db;
  17. use think\Loader;
  18. class PayLogic extends CommonModel {
  19. private function setorderid($mem_id) {
  20. list($usec, $sec) = explode(" ", microtime());
  21. // 取微秒前3位+再两位随机数+渠道ID后四位
  22. $orderid = $sec.substr($usec, 2, 3).rand(10, 99).sprintf("%04d", $mem_id % 10000);
  23. return $orderid;
  24. }
  25. /**
  26. *支付宝支付
  27. */
  28. function _alipayweb() {
  29. if (Request::instance()->isPost()) {
  30. $data = $this->_insertpay();
  31. if (empty($data['order_id'])) {
  32. return $data;
  33. }
  34. $_conf_file = ROOT_PATH."data/conf/pay/alipay/config.php";
  35. if (file_exists($_conf_file)) {
  36. $alipay_config = include $_conf_file;
  37. } else {
  38. $alipay_config = array();
  39. }
  40. //支付类型
  41. $payment_type = "1";
  42. //必填,不能修改
  43. //服务器异步通知页面路径
  44. $notify_url = WEBSITE."/v8/pay/ptb_alipay_notify";
  45. //需http://格式的完整路径,不能加?id=123这类自定义参数
  46. //页面跳转同步通知页面路径
  47. $return_url = WEBSITE."/v8/member/index";
  48. //需http://格式的完整路径,不能加?id=123这类自定义参数,不能写成http://localhost/
  49. //商户订单号
  50. $out_trade_no = $data['order_id'];
  51. //商户网站订单系统中唯一订单号,必填
  52. //订单名称
  53. $subject = "平台币充值";
  54. //必填
  55. //付款金额
  56. $total_fee = $data['money'];
  57. //必填
  58. //商品展示地址
  59. $show_url = WEBSITE;
  60. //必填,需以http://开头的完整路径,例如:http://www.商户网址.com/myorder.html
  61. //订单描述
  62. $body = "平台币充值";
  63. //选填
  64. //超时时间
  65. $it_b_pay = '15d';
  66. //选填
  67. //钱包token
  68. $extern_token = "";
  69. //选填
  70. $alipay_config['input_charset'] = 'utf-8';
  71. $alipay_config['sign_type'] = 'RSA';
  72. $alipay_config['private_key_path'] = ROOT_PATH.'data/conf/pay/alipay/key/rsa_private_key.pem';
  73. $alipay_config['public_key_path'] = ROOT_PATH.'data/conf/pay/alipay/key/alipay_public_key.pem';
  74. $parameter = array(
  75. "service" => 'create_direct_pay_by_user',
  76. "partner" => trim($alipay_config['partner']),
  77. "payment_type" => $payment_type,
  78. "notify_url" => $notify_url,
  79. "return_url" => $return_url,
  80. "seller_email" => trim($alipay_config['seller_email']),
  81. "out_trade_no" => $out_trade_no,
  82. "subject" => $subject,
  83. "total_fee" => $total_fee,
  84. "body" => $body,
  85. "show_url" => $return_url,
  86. "anti_phishing_key" => "",
  87. "exter_invoke_ip" => "",
  88. "_input_charset" => trim(strtolower($alipay_config['input_charset']))
  89. );
  90. //建立请求,请求成功之后,会通知服务器的alipay_notify方法,客户端会通知$return_url配置的方法
  91. Loader::import('pay.alipay.AlipaySubmit', '', '.class.php');
  92. $alipaySubmit = new \AlipaySubmit($alipay_config);
  93. $html_text = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>';
  94. $html_text = $alipaySubmit->buildRequestForm($parameter, "get", "跳转中");
  95. $html_text = $html_text."<script>document.forms['alipaysubmit'].submit();</script>";
  96. echo $html_text;
  97. }
  98. }
  99. /**
  100. *支付宝回调
  101. */
  102. function alipay_notify() {
  103. Loader::import('pay.alipay.AlipayNotify', '', '.class.php');
  104. //计算得出通知验证结果
  105. $alipay_config = $this->alipayConfig();
  106. $alipayNotify = new \AlipayNotify($alipay_config);
  107. $verify_result = $alipayNotify->verifyNotify();
  108. if ($verify_result) {//验证成功
  109. //商户订单号
  110. $out_trade_no = $_POST['out_trade_no'];
  111. //支付宝交易号
  112. $trade_no = $_POST['trade_no'];
  113. $amount = $_POST['total_fee'];
  114. //交易状态
  115. $trade_status = $_POST['trade_status'];
  116. if ($trade_status == 'TRADE_FINISHED') {
  117. // 自由网络申请的是普通及时到账接口
  118. //支付成功后,修改支付表中支付状态,并将交易信息写入用户平台充值记录表ptb_charge。
  119. //$this->paypost($out_trade_no,$trade_no,$amount);
  120. } else if ($trade_status == 'TRADE_SUCCESS') {
  121. //支付成功后,修改支付表中支付状态,并将交易信息写入用户平台充值记录表ptb_charge。
  122. $this->paypost($out_trade_no, $amount);
  123. }
  124. } else {
  125. echo '验证失败';
  126. }
  127. }
  128. public function alipayConfig() {
  129. $_conf_file = ROOT_PATH."data/conf/pay/alipay/config.php";
  130. if (file_exists($_conf_file)) {
  131. $alipay_config = include $_conf_file;
  132. } else {
  133. $alipay_config = array();
  134. }
  135. $alipay_config = array(
  136. 'partner' => $alipay_config['partner'],
  137. 'key' => $alipay_config['key'],
  138. 'input_charset' => strtolower('utf-8'),
  139. 'cacert' => $alipay_config['partner'],
  140. 'transport' => 'http',
  141. 'sign_type' => 'RSA',
  142. 'private_key_path' => ROOT_PATH.'data/conf/pay/alipay/key/rsa_private_key.pem',
  143. 'public_key_path' => ROOT_PATH.'data/conf/pay/alipay/key/alipay_public_key.pem'
  144. );
  145. return $alipay_config;
  146. }
  147. /**
  148. *支付记录保存
  149. */
  150. function _insertpay() {
  151. $ptb_cnt = request()->param('amount'); // 获取平台币数量
  152. $username = request()->param('username');
  153. // 获取折扣
  154. $_walle_class = new WalletLogic();
  155. $discount = $_walle_class->getPtbRate();
  156. $amount = $discount['discount'] * $ptb_cnt; // 平台币与充值金额比例暂定为1:1
  157. $paytypeid = request()->param('type');
  158. // 判断充值金额的有效性
  159. if ($amount <= 0) {
  160. return array('error' => 3, 'msg' => '充值金额不能小于或等于0');
  161. }
  162. //验证参数有效性
  163. if (empty($amount) || empty($username)
  164. || empty($ptb_cnt)
  165. || empty($paytypeid)
  166. ) {
  167. $str = "缺少参数,请重新提交";
  168. return array('error' => 4, 'msg' => $str);
  169. }
  170. //检查用户名是否存在
  171. $mem_id = Db::name('member')
  172. ->where(array('username' => $username))
  173. ->value('id');
  174. if (empty($mem_id)) {
  175. $str = "用户不存在";
  176. return array('error' => 5, 'msg' => $str);
  177. }
  178. if (!empty(Session::get('paytime')) && Session::get('paytime') + 5 > time()) {
  179. $str = "订单己存在,请确认是您的付款单号再付款!";
  180. return array('error' => 6, 'msg' => $str);
  181. }
  182. //订单流水号
  183. $order_id = $this->setorderid($mem_id);
  184. Session::set('weborderid', $order_id);
  185. Session::set('paytime', time());
  186. //查询是否为同一订单,插入到平台币充值订单中
  187. $orderdata = Db::name('ptb_charge')->where(array('order_id' => $order_id))->value('id');
  188. //判断订单是否存在
  189. if ($orderdata) {
  190. $str = "订单己存在,请确认是您的付款单号再付款!";
  191. return array('error' => 7, 'msg' => $str);
  192. }
  193. $BuyerIp = request()->ip(); //用户支付时使用的网络终端IP
  194. $transtime = time(); //交易时间
  195. $mem_id = Db::name("member")->where(array("username" => $username))->value("id");
  196. $data['order_id'] = $order_id;
  197. $data['mem_id'] = $mem_id;
  198. $data['money'] = $amount;
  199. $data['ptb_cnt'] = $ptb_cnt;
  200. $data['status'] = 1;
  201. $data['create_time'] = $transtime;
  202. $data['payway'] = $paytypeid;
  203. $data['flag'] = 1; // 官网充值
  204. $data['remark'] = "官网充值";
  205. $data['ip'] = $BuyerIp;
  206. $data["discount"] = "1";
  207. $data["real_amount"] = $amount;
  208. $data['id'] = Db::name('ptb_charge')->insert($data);
  209. if (!$data['id']) {
  210. return array('error' => 8, 'msg' => '数据处理出错,请重新提交!');
  211. }
  212. return $data;
  213. }
  214. function paypost($out_trade_no, $total_fee) {
  215. $time = time();
  216. $data = Db::name("ptb_charge")->where(array("order_id" => $out_trade_no))->find();
  217. $myamount = number_format($data['money']);
  218. $transAmount = number_format($total_fee);
  219. if ($myamount == $transAmount) {
  220. if ($data['status'] == 1) {
  221. $status['status'] = 2;
  222. $rs = Db::name("ptb_charge")->where(array("order_id" => $out_trade_no))->update($status);
  223. if ($rs) {
  224. $check = $this->checkPtb($data['mem_id'], $data['ptb_cnt'], $data['money']);
  225. if ($check) {
  226. echo "OK";
  227. exit;
  228. }
  229. }
  230. }
  231. }
  232. }
  233. //检查是否已经存在过平台币并更新
  234. public function checkPtb($mem_id, $ptb_cnt, $amount) {
  235. //获取玩家平台币余额表中的ID
  236. $data = Db::name('ptb_mem')->where(array('mem_id' => $mem_id))->find();
  237. $where['remain'] = $data['remain'] + $ptb_cnt;
  238. $where['update_time'] = time();
  239. $where['total'] = $data['total'] + $ptb_cnt;
  240. $where['sum_money'] = $data['sum_money'] + $amount;
  241. $map['mem_id'] = $mem_id;
  242. //判断玩家平台币余额表中是否存在数据,没有则添加,有则修改!
  243. if (!empty($data)) {
  244. $result = Db::name('ptb_mem')->where($map)->update($where);
  245. } else {
  246. $where['create_time'] = time();
  247. $where['mem_id'] = $mem_id;
  248. $where['total'] = $ptb_cnt;
  249. $where['remain'] = $ptb_cnt;
  250. $where['sum_money'] = $amount;
  251. $result = Db::name('ptb_mem')->data($where)->insert();
  252. }
  253. //判断充值结果
  254. if ($result) {
  255. return true;
  256. } else {
  257. return false;
  258. }
  259. }
  260. /**
  261. * 扫码支付
  262. *
  263. * @return mixed
  264. */
  265. function _spayweb() {
  266. if (Request::instance()->isPost()) {
  267. $data = $this->_insertpay();
  268. if (empty($data['order_id'])) {
  269. return [
  270. 'status' => 500,
  271. 'msg' => '支付失败'
  272. ];
  273. }
  274. $_conf_file = ROOT_PATH."data/conf/pay/spay/config.php";
  275. if (file_exists($_conf_file)) {
  276. $_config = include $_conf_file;
  277. } else {
  278. $_config = array();
  279. }
  280. header("Content-type:text/html;charset=utf-8");
  281. Loader::import('pay.spay.Utils', '', '.class.php');
  282. Loader::import('pay.spay.RequestHandler', '', '.class.php');
  283. Loader::import('pay.spay.ClientResponseHandler', '', '.class.php');
  284. Loader::import('pay.spay.PayHttpClient', '', '.class.php');
  285. $resHandler = new \ClientResponseHandler();
  286. $reqHandler = new \RequestHandler();
  287. $pay = new \PayHttpClient();
  288. $notify_url = WEBSITE."/v8/pay/ptb_spay_notify";
  289. //导入回调地址
  290. $reqHandler->setGateUrl($_config['url']);
  291. $reqHandler->setKey($_config['key']);
  292. $reqHandler->setParameter('out_trade_no', $data['order_id']);
  293. $reqHandler->setParameter('body', "平台币充值");
  294. $reqHandler->setParameter('attach', "平台币充值");
  295. $reqHandler->setParameter('total_fee', $data['money'] * 100);
  296. $reqHandler->setParameter('mch_create_ip', $data['ip']);
  297. $reqHandler->setParameter('time_start', date('YmdHis', time()));
  298. $reqHandler->setParameter('time_expire', date('YmdHis', time() + 7200));
  299. $reqHandler->setParameter('service', 'pay.weixin.native');//接口类型:pay.weixin.native
  300. $reqHandler->setParameter('mch_id', $_config['mchId']);//必填项,商户号,由威富通分配
  301. $reqHandler->setParameter('version', $_config['version']);
  302. //通知地址,必填项,接收威富通通知的URL,需给绝对路径,255字符内格式如:http://wap.tenpay.com/tenpay.asp
  303. //$notify_url = 'http://'.$_SERVER['HTTP_HOST']; //$reqHandler->setParameter('notify_url',$notify_url.'/payInterface/request.php?method=callback');
  304. $reqHandler->setParameter('notify_url', $notify_url);
  305. $reqHandler->setParameter('nonce_str', mt_rand(time(), time() + rand()));//随机字符串,必填项,不长于 32 位
  306. $reqHandler->createSign();//创建签名
  307. $rdata = \Utils::toXml($reqHandler->getAllParameters());//var_dump($rdata);
  308. $pay->setReqContent($reqHandler->getGateURL(), $rdata);
  309. if ($pay->call()) {
  310. $resHandler->setContent($pay->getResContent());
  311. $resHandler->setKey($reqHandler->getKey());
  312. if ($resHandler->isTenpaySign()) {
  313. //当返回状态与业务结果都为0时才返回支付二维码,其它结果请查看接口文档
  314. if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0) {
  315. $code_img_url = $resHandler->getParameter('code_img_url');
  316. $_rdata = [
  317. 'status' => 1,
  318. 'data' => [
  319. 'code_img_url' => $code_img_url,
  320. 'order_id' => $data['order_id'],
  321. 'checkurl' => WEBSITE."/v8/pay/spay_status",
  322. 'returnurl' => WEBSITE."/v8/member/index"
  323. ]
  324. ];
  325. return $_rdata;
  326. // $this->assign('code_img_url', $code_img_url);
  327. // $this->assign('order_id', $data['order_id']);
  328. // $this->assign('checkurl', WEBSITE."/index.php/index/pay/spaystatus");
  329. // $this->assign('returnurl', WEBSITE);
  330. // \think\Config::set('default_return_type', 'html');
  331. //
  332. // return $this->fetch("spay");
  333. } else {
  334. echo json_encode(
  335. array('status' => 500,
  336. 'msg' => 'Error Code:'.$resHandler->getParameter('err_code').' Error Message:'
  337. .$resHandler->getParameter('err_msg'))
  338. );
  339. exit();
  340. }
  341. }
  342. echo json_encode(
  343. array('status' => 500, 'msg' => 'Error Code:'.$resHandler->getParameter('status').' Error Message:'
  344. .$resHandler->getParameter('message'))
  345. );
  346. } else {
  347. echo json_encode(
  348. array('status' => 500,
  349. 'msg' => 'Response Code:'.$pay->getResponseCode().' Error Info:'.$pay->getErrInfo())
  350. );
  351. }
  352. }
  353. }
  354. /**
  355. *威富通通知
  356. */
  357. function spay_notify() {
  358. if (Request::instance()->isPost()) {
  359. $_conf_file = ROOT_PATH."data/conf/pay/spay/config.php";
  360. if (file_exists($_conf_file)) {
  361. $_config = include $_conf_file;
  362. } else {
  363. $_config = array();
  364. }
  365. header("Content-type:text/html;charset=utf-8");
  366. Loader::import('pay.spay.Utils', '', '.class.php');
  367. Loader::import('pay.spay.RequestHandler', '', '.class.php');
  368. Loader::import('pay.spay.ClientResponseHandler', '', '.class.php');
  369. Loader::import('pay.spay.PayHttpClient', '', '.class.php');
  370. $resHandler = new \ClientResponseHandler();
  371. $xml = file_get_contents('php://input');
  372. $resHandler->setContent($xml);
  373. $resHandler->setKey($_config['key']);
  374. //判断签名结果
  375. $signResult = $resHandler->isTenpaySign();
  376. if ($signResult) {
  377. if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0) {
  378. //更改订单状态
  379. $out_trade_no = $resHandler->getParameter('out_trade_no'); //自己生成的订单状态
  380. $total_fee = $resHandler->getParameter('total_fee') / 100;
  381. //将订单状态写入数据表中
  382. $this->paypost($out_trade_no, $total_fee);
  383. echo 'success';
  384. exit;
  385. } else {
  386. echo 'failure1';
  387. exit();
  388. }
  389. } else {
  390. echo 'failure2';
  391. }
  392. }
  393. echo 'failure2';
  394. }
  395. function spayStatus($order_id) {
  396. $_order_id = $order_id;
  397. if (empty($_order_id)) {
  398. $_data = array(
  399. "success" => 0
  400. );
  401. return $_data;
  402. }
  403. $_status = Db::name("ptb_charge")->where(array("order_id" => $_order_id))->value("status");
  404. if (2 == $_status) {
  405. $_data = array(
  406. "success" => 1
  407. );
  408. } else {
  409. $_data = array(
  410. "success" => 0
  411. );
  412. }
  413. return $_data;
  414. }
  415. }