国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
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.

292 lines
11KB

  1. <?php
  2. if(!defined('DEDEINC')) exit('dedebiz');
  3. /**
  4. * 支付宝接口类
  5. */
  6. class Alipay
  7. {
  8. var $dsql;
  9. var $mid;
  10. var $return_url = "/plus/carbuyaction.php?dopost=return";
  11. /**
  12. * 构造函数
  13. *
  14. * @access public
  15. * @param
  16. *
  17. * @return void
  18. */
  19. function Alipay()
  20. {
  21. global $dsql;
  22. $this->dsql = $dsql;
  23. }
  24. function __construct()
  25. {
  26. $this->Alipay();
  27. }
  28. /**
  29. * 设定接口会送地址
  30. *
  31. * 例如: $this->SetReturnUrl($cfg_basehost."/tuangou/control/index.php?ac=pay&orderid=".$p2_Order)
  32. *
  33. * @param string $returnurl 会送地址
  34. * @return void
  35. */
  36. function SetReturnUrl($returnurl='')
  37. {
  38. if (!empty($returnurl))
  39. {
  40. $this->return_url = $returnurl;
  41. }
  42. }
  43. /**
  44. * 生成支付代码
  45. * @param array $order 订单信息
  46. * @param array $payment 支付方式信息
  47. */
  48. function GetCode($order, $payment)
  49. {
  50. global $cfg_basehost,$cfg_cmspath,$cfg_soft_lang;
  51. $charset = $cfg_soft_lang;
  52. //对于二级目录的处理
  53. if(!empty($cfg_cmspath)) $cfg_basehost = $cfg_basehost.'/'.$cfg_cmspath;
  54. $real_method = $payment['alipay_pay_method'];
  55. switch ($real_method){
  56. case '0':
  57. $service = 'trade_create_by_buyer';
  58. break;
  59. case '1':
  60. $service = 'create_partner_trade_by_buyer';
  61. break;
  62. case '2':
  63. $service = 'create_direct_pay_by_user';
  64. break;
  65. }
  66. $agent = 'C4335994340215837114';
  67. $parameter = array(
  68. 'agent' => $agent,
  69. 'service' => $service,
  70. 'partner' => $payment['alipay_partner'],
  71. //'partner' => ALIPAY_ID,
  72. '_input_charset' => $charset,
  73. 'notify_url' => $cfg_basehost.$this->return_url."&code=".$payment['code'],
  74. 'return_url' => $cfg_basehost.$this->return_url."&code=".$payment['code'],
  75. /* 业务参数 */
  76. 'subject' => "支付订单号:".$order['out_trade_no'],
  77. 'out_trade_no' => $order['out_trade_no'],
  78. 'price' => $order['price'],
  79. 'quantity' => 1,
  80. 'payment_type' => 1,
  81. /* 物流参数 */
  82. 'logistics_type' => 'EXPRESS',
  83. 'logistics_fee' => 0,
  84. 'logistics_payment' => 'BUYER_PAY_AFTER_RECEIVE',
  85. /* 买卖双方信息 */
  86. 'seller_email' => $payment['alipay_account']
  87. );
  88. ksort($parameter);
  89. reset($parameter);
  90. $param = '';
  91. $sign = '';
  92. foreach ($parameter AS $key => $val)
  93. {
  94. $param .= "$key=" .urlencode($val). "&";
  95. $sign .= "$key=$val&";
  96. }
  97. $param = substr($param, 0, -1);
  98. $sign = substr($sign, 0, -1). $payment['alipay_key'];
  99. $button = '<div style="text-align:center"><input type="button" onclick="window.open(\'https://www.alipay.com/cooperate/gateway.do?'.$param. '&sign='.md5($sign).'&sign_type=MD5\')" value="立即使用alipay支付宝支付"/></div>';
  100. /* 清空购物车 */
  101. require_once DEDEINC.'/shopcar.class.php';
  102. $cart = new MemberShops();
  103. $cart->clearItem();
  104. $cart->MakeOrders();
  105. return $button;
  106. }
  107. /**
  108. * 响应操作
  109. */
  110. function respond()
  111. {
  112. if (!empty($_POST))
  113. {
  114. foreach($_POST as $key => $data)
  115. {
  116. $_GET[$key] = $data;
  117. }
  118. }
  119. /* 引入配置文件 */
  120. $code = preg_replace( "#[^0-9a-z-]#i", "", $_GET['code'] );
  121. require_once DEDEDATA.'/payment/'.$code.'.php';
  122. /* 取得订单号 */
  123. $order_sn = trim(addslashes($_GET['out_trade_no']));
  124. /*判断订单类型*/
  125. if(preg_match ("/S-P[0-9]+RN[0-9]/",$order_sn)) {
  126. //检查支付金额是否相符
  127. $row = $this->dsql->GetOne("SELECT * FROM #@__shops_orders WHERE oid = '{$order_sn}'");
  128. if ($row['priceCount'] != $_GET['total_fee'])
  129. {
  130. return $msg = "支付失败,支付金额与商品总价不相符!";
  131. }
  132. $this->mid = $row['userid'];
  133. $ordertype="goods";
  134. }else if (preg_match ("/M[0-9]+T[0-9]+RN[0-9]/", $order_sn)){
  135. $row = $this->dsql->GetOne("SELECT * FROM #@__member_operation WHERE buyid = '{$order_sn}'");
  136. //获取订单信息,检查订单的有效性
  137. if(!is_array($row)||$row['sta']==2) return $msg = "您的订单已经处理,请不要重复提交!";
  138. elseif($row['money'] != $_GET['total_fee']) return $msg = "支付失败,支付金额与商品总价不相符!";
  139. $ordertype = "member";
  140. $product = $row['product'];
  141. $pname= $row['pname'];
  142. $pid=$row['pid'];
  143. $this->mid = $row['mid'];
  144. } else {
  145. return $msg = "支付失败,您的订单号有问题";
  146. }
  147. /* 检查数字签名是否正确 */
  148. ksort($_GET);
  149. reset($_GET);
  150. $sign = '';
  151. foreach ($_GET AS $key=>$val)
  152. {
  153. if ($key != 'sign' && $key != 'sign_type' && $key != 'code' && $key != 'dopost')
  154. {
  155. $sign .= "$key=$val&";
  156. }
  157. }
  158. $sign = substr($sign, 0, -1).$payment['alipay_key'];
  159. if (md5($sign) != $_GET['sign'])
  160. {
  161. return $msg = "支付失败!";
  162. }
  163. if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'WAIT_SELLER_SEND_GOODS' || $_GET['trade_status'] == 'TRADE_SUCCESS')
  164. {
  165. if($ordertype=="goods"){
  166. if($this->success_db($order_sn)) return $msg = "支付成功!<br> <a href='/'>返回主页</a> <a href='/member'>会员中心</a>";
  167. else return $msg = "支付失败<br> <a href='/'>返回主页</a> <a href='/member'>会员中心</a>";
  168. } else if ( $ordertype=="member" ) {
  169. $oldinf = $this->success_mem($order_sn,$pname,$product,$pid);
  170. return $msg = "<span style='color:#dc3545'>".$oldinf."</span><br> <a href='/'>返回主页</a> <a href='/member'>会员中心</a>";
  171. }
  172. } else {
  173. $this->log_result ("verify_failed");
  174. return $msg = "支付失败<br> <a href='/'>返回主页</a> <a href='/member'>会员中心</a>";
  175. }
  176. }
  177. /*处理物品交易*/
  178. function success_db($order_sn)
  179. {
  180. //获取订单信息,检查订单的有效性
  181. $row = $this->dsql->GetOne("SELECT state FROM #@__shops_orders WHERE oid='$order_sn' ");
  182. if($row['state'] > 0)
  183. {
  184. return TRUE;
  185. }
  186. /* 改变订单状态_支付成功 */
  187. $sql = "UPDATE `#@__shops_orders` SET `state`='1' WHERE `oid`='$order_sn' AND `userid`='".$this->mid."'";
  188. if($this->dsql->ExecuteNoneQuery($sql))
  189. {
  190. $this->log_result("verify_success,订单号:".$order_sn); //将验证结果存入文件
  191. return TRUE;
  192. } else {
  193. $this->log_result ("verify_failed,订单号:".$order_sn);//将验证结果存入文件
  194. return FALSE;
  195. }
  196. }
  197. /*处理点卡,会员升级*/
  198. function success_mem($order_sn,$pname,$product,$pid)
  199. {
  200. //更新交易状态为已付款
  201. $sql = "UPDATE `#@__member_operation` SET `sta`='1' WHERE `buyid`='$order_sn' AND `mid`='".$this->mid."'";
  202. $this->dsql->ExecuteNoneQuery($sql);
  203. /* 改变点卡订单状态_支付成功 */
  204. if($product=="card")
  205. {
  206. $row = $this->dsql->GetOne("SELECT cardid FROM `#@__moneycard_record` WHERE ctid='$pid' AND isexp='0' ");;
  207. //如果找不到某种类型的卡,直接为用户增加金币
  208. if(!is_array($row))
  209. {
  210. $nrow = $this->dsql->GetOne("SELECT num FROM `#@__moneycard_type` WHERE pname = '{$pname}'");
  211. $dnum = $nrow['num'];
  212. $sql1 = "UPDATE `#@__member` SET `money`=money+'{$nrow['num']}' WHERE `mid`='".$this->mid."'";
  213. $oldinf ="已经充值了".$nrow['num']."金币到您的帐号";
  214. } else {
  215. $cardid = $row['cardid'];
  216. $sql1=" UPDATE `#@__moneycard_record` SET uid='".$this->mid."',isexp='1',utime='".time()."' WHERE cardid='$cardid' ";
  217. $oldinf='您的充值密码是:<span style="color:color:#dc3545">'.$cardid.'</span>';
  218. }
  219. //更新交易状态为已关闭
  220. $sql2=" UPDATE `#@__member_operation` SET sta=2,oldinfo='$oldinf' WHERE buyid='$order_sn'";
  221. if($this->dsql->ExecuteNoneQuery($sql1) && $this->dsql->ExecuteNoneQuery($sql2))
  222. {
  223. $this->log_result("verify_success,订单号:".$order_sn); //将验证结果存入文件
  224. return $oldinf;
  225. } else {
  226. $this->log_result ("verify_failed,订单号:".$order_sn);//将验证结果存入文件
  227. return "支付失败";
  228. }
  229. /* 改变会员订单状态_支付成功 */
  230. } else if ( $product=="member" ){
  231. $row = $this->dsql->GetOne("SELECT `rank`,exptime FROM `#@__member_type` WHERE aid='$pid' ");
  232. $rank = $row['rank'];
  233. $exptime = $row['exptime'];
  234. /*计算原来升级剩余的天数*/
  235. $rs = $this->dsql->GetOne("SELECT uptime,exptime FROM `#@__member` WHERE mid='".$this->mid."'");
  236. if($rs['uptime']!=0 && $rs['exptime']!=0 )
  237. {
  238. $nowtime = time();
  239. $mhasDay = $rs['exptime'] - ceil(($nowtime - $rs['uptime'])/3600/24) + 1;
  240. $mhasDay=($mhasDay>0)? $mhasDay : 0;
  241. }
  242. //获取会员默认级别的金币和积分数
  243. $memrank = $this->dsql->GetOne("SELECT money,scores FROM `#@__arcrank` WHERE `rank`='$rank'");
  244. //更新会员信息
  245. $sql1 = " UPDATE `#@__member` SET `rank`='$rank',money=money+'{$memrank['money']}',
  246. scores=scores+'{$memrank['scores']}',exptime='$exptime'+'$mhasDay',uptime='".time()."'
  247. WHERE mid='".$this->mid."'";
  248. //更新交易状态为已关闭
  249. $sql2=" UPDATE `#@__member_operation` SET sta='2',oldinfo='会员升级成功!' WHERE buyid='$order_sn' ";
  250. if($this->dsql->ExecuteNoneQuery($sql1) && $this->dsql->ExecuteNoneQuery($sql2))
  251. {
  252. $this->log_result("verify_success,订单号:".$order_sn); //将验证结果存入文件
  253. return "会员升级成功";
  254. } else {
  255. $this->log_result ("verify_failed,订单号:".$order_sn);//将验证结果存入文件
  256. return "会员升级失败";
  257. }
  258. }
  259. }
  260. function log_result($word)
  261. {
  262. global $cfg_cmspath;
  263. $fp = fopen(dirname(__FILE__)."/../../data/payment/log.txt","a");
  264. flock($fp, LOCK_EX) ;
  265. fwrite($fp,$word.",执行日期:".strftime("%Y-%m-%d %H:%I:%S",time())."\r\n");
  266. flock($fp, LOCK_UN);
  267. fclose($fp);
  268. }
  269. }//End API