OrderNotice.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <?php
  2. namespace loyalsoft\pay;
  3. /**
  4. * Description of OrderNotice
  5. * 通用支付订单通知模型
  6. * @version
  7. * 1.0.0 Created at 2017-12-26. by --gwang
  8. * @author gwang (mail@wanggangzero.cn)
  9. * @copyright ? 2017-12-26, SJZ LoyalSoft Corporation & gwang. All rights reserved.
  10. */
  11. class OrderNotice extends \loyalsoft\Object_ext {
  12. const orderTab = 'tpl_order_tab';
  13. /**
  14. * uid,zoneid,cpOrderId
  15. * @var string 充值回调透传参数(len=250)
  16. */
  17. public $callbackInfo;
  18. /**
  19. * @var int 充值金额 单位:分
  20. */
  21. public $amount;
  22. /**
  23. * @var string 订单ID (len=30)
  24. */
  25. public $cpOrderId;
  26. /**
  27. * @var string 平台UID
  28. */
  29. public $uid;
  30. /**
  31. * @var string 平台字符串
  32. */
  33. public $channel;
  34. /**
  35. *
  36. * @var type 订单状态: 0:创建订单,1:支付成功,2: 支付失败
  37. */
  38. public $status;
  39. /**
  40. *
  41. * @var type
  42. */
  43. protected $sdk_orderid;
  44. /**
  45. *
  46. * @var type
  47. */
  48. protected $otherInfo;
  49. /**
  50. * @return boolean 校验订单数据
  51. */
  52. public function Check() {
  53. // var_dump($this);
  54. $dbOrder = \loyalsoft\daoInst()->select()->from(self::orderTab)
  55. ->where('cpOrderId')->eq($this->cpOrderId)
  56. ->limit(1)->fetch();
  57. // var_dump($dbOrder);
  58. \loyalsoft\CLog::pay('查询订单结果: ' . var_export($dbOrder, TRUE));
  59. if (!$dbOrder) {
  60. \loyalsoft\CLog::pay('订单不存在! ' . $this);
  61. return false;
  62. }
  63. if ($dbOrder->status == 1) {
  64. \loyalsoft\CLog::pay('订单已经完成!' . $this);
  65. return false;
  66. }
  67. // // 提取纯UID作比较
  68. // $pureUID = function($str) {
  69. //// var_dump($str);
  70. // if (!strpos($str, "-")) {
  71. // return $str;
  72. // }
  73. // return substr($str, strpos($str, "-") + 1);
  74. // };
  75. //// var_dump($this->uid);
  76. // if ($pureUID($dbOrder->uid) != $pureUID($this->uid)) {
  77. // \loyalsoft\CLog::pay('UID校验不匹配! ' . $pureUID($this->uid) . " (" . $pureUID($dbOrder->uid) . ")");
  78. // return false;
  79. // }
  80. if ($dbOrder->amount != $this->amount) {
  81. \loyalsoft\CLog::pay('金额校验不匹配! ' . $this->amount . " (" . $dbOrder->amount . ")");
  82. return false;
  83. }
  84. return true;
  85. }
  86. /**
  87. * 检查重复的渠道订单id(目前仅在ios平台做了校验,其他都是后台通知。
  88. * @return boolean true 验证通过,false 验证失败,已经存在相同的订单id
  89. */
  90. public function CheckDuplicateSdkOrder() {
  91. $n = \loyalsoft\daoInst()->select()->from(self::orderTab)
  92. ->where('sdk_orderid')->eq($this->sdk_orderid)
  93. ->count();
  94. return $n <= 0;
  95. }
  96. /**
  97. * @return boolean 更新订单状态
  98. */
  99. public function UpdateOrderStatus() {
  100. $n = \loyalsoft\daoInst()->update(self::orderTab)
  101. ->data(array('status' => $this->status,
  102. 'sdk_orderid' => $this->sdk_orderid,
  103. 'otherInfo' => $this->otherInfo,
  104. 'close_ts' => \loyalsoft\now()))
  105. ->where('cpOrderId')->eq($this->cpOrderId)
  106. ->exec();
  107. return $n > 0;
  108. }
  109. /**
  110. * 识别UC后台通知数据
  111. * @param array $args
  112. * @return \loyalsoft\pay\OrderNotice
  113. */
  114. public static function Parse_UcOrder($args) {
  115. $o = new OrderNotice();
  116. $o->channel = "uc"; # 渠道代码
  117. $o->cpOrderId = $args["data"]["cpOrderId"]; # (后台)订单编号
  118. $o->status = ($args["data"]["orderStatus"] == "S") ? 1 : 2; # 订单状态(九游返回值: S/F)
  119. $o->uid = $args['data']['accountId']; # 玩家uid
  120. $o->amount = $args['data']['amount'] * 100; # 支付金额, uc 返回的单位是元
  121. $o->callbackInfo = $args['data']['callbackInfo']; # uid-uc,zoneid,cpOrderId
  122. $o->sdk_orderid = $args['orderId']; # UC订单ID
  123. $o->otherInfo = $args['failedDesc']; # 其他信息
  124. return $o;
  125. }
  126. /**
  127. * 解析易接后台通知数据
  128. * @param array $args
  129. */
  130. public static function Parse_1SDKOrder($args) {
  131. $o = new OrderNotice();
  132. $o->channel = "1sdk"; # 渠道代码
  133. $ext = explode(',', $args['cbi']);
  134. $o->cpOrderId = $ext[2]; # 这个字段藏在透传参数中
  135. $o->status = ($args["st"] == "1") ? 1 : 2; # 订单状态(易接SDK返回值: 1/成功,其他失败)
  136. $o->uid = $args['uid']; # 玩家uid
  137. $o->amount = $args['fee']; # 支付金额, 易接返回值单位是分
  138. $o->callbackInfo = $args['cbi']; # 透传参数, uid-uc,zoneid,cpOrderId
  139. $o->sdk_orderid = $args['ssid']; # 渠道订单id
  140. $o->otherInfo = $args['tcd']; # 易接订单id
  141. return $o;
  142. }
  143. /**
  144. * 生成苹果支付订单数据.
  145. * @param array $argsClient
  146. * @param array $receipt 苹果凭证
  147. */
  148. public static function reParse_IOSOrder($argsClient, $receipt) {
  149. $o = new OrderNotice();
  150. $o->channel = "ios"; # 渠道代码
  151. $o->uid = $argsClient->uid; # 玩家uid
  152. $o->cpOrderId = $argsClient->cpOrderId; # 这个字段藏在透传参数中
  153. $o->callbackInfo = $argsClient->callbackInfo; # 透传参数, uid-uc,zoneid,cpOrderId
  154. $o->status = ($receipt["status"] == "0") ? 1 : 2; # 订单状态(苹果返回值: 0/成功,其他失败)
  155. $product_id = $receipt['product_id']; # 道具ID
  156. $itemModel = \loyalsoft\GameConfig::shop_getItem($product_id); # 道具常量
  157. $o->amount = $itemModel->price * 100; # 入库单位是分, 后台单位是元
  158. $o->sdk_orderid = $receipt['transaction_id']; # 交易订单id
  159. $o->otherInfo = $receipt['purchase_date']; # 购买时间
  160. return $o;
  161. }
  162. /**
  163. * 解析支付宝通知
  164. * @param type $args
  165. * @return \loyalsoft\pay\OrderNotice
  166. */
  167. public static function Parse_alipayOrder($args) {
  168. $o = new OrderNotice();
  169. $exts = explode(',', urldecode($args['passback_params'])); # 透传参数
  170. $o->channel = "soft"; # 渠道代码zfb?
  171. $o->cpOrderId = $args['out_trade_no']; # 订单编号(龙游)
  172. $o->status = ($args["trade_status"] == "TRADE_SUCCESS") ? 1 : 2; # 订单状态()
  173. $uid = $exts[0];
  174. $o->uid = substr($uid, strpos($uid, '-') + 1); # 玩家uid
  175. $o->amount = $args['total_amount']; # 支付金额, 游戏后台单位是分
  176. $o->callbackInfo = $args['passback_params']; # 透传参数, uid-uc,zoneid,cpOrderId
  177. $o->sdk_orderid = $args['trade_no']; # 支付宝订单id
  178. $o->otherInfo = $args['buyer_logon_id']; # 支付宝登录账户号
  179. return $o;
  180. }
  181. /**
  182. * 解析微信通知
  183. * @param type $args
  184. * @return \loyalsoft\pay\OrderNotice
  185. */
  186. public static function Parse_weixinpayOrder($args) {
  187. $o = new OrderNotice();
  188. $exts = explode(',', urldecode($args['attach'])); # 透传参数
  189. $o->channel = "soft"; # 渠道代码zfb?
  190. $o->cpOrderId = $args['out_trade_no']; # 订单编号(龙游)
  191. $o->status = ($args["result_code"] == "SUCCESS") ? 1 : 2; # 订单状态()
  192. $uid = $exts[0];
  193. $o->uid = substr($uid, strpos($uid, '-') + 1); # 玩家uid
  194. $o->amount = $args['total_fee']/100; # 支付金额, 游戏后台单位是分
  195. $o->callbackInfo = $args['attach']; # 透传参数, uid-uc,zoneid,cpOrderId
  196. $o->sdk_orderid = $args['transaction_id']; # 微信订单id
  197. $o->otherInfo = $args['time_end']; # 结束时间
  198. return $o;
  199. }
  200. /**
  201. * 解析应用宝充值通知
  202. * @param array $args
  203. */
  204. public static function Parse_yybOrder($args) {
  205. $o = new OrderNotice();
  206. $o->channel = "yyb"; # 渠道代码
  207. $o->cpOrderId = $args['orderId']; # 订单编号
  208. $o->status = ($args["status"] == "1") ? 1 : 2; # 订单状态(易接SDK返回值: 1/成功,其他失败)
  209. $o->uid = $args['uid']; // openid # 玩家uid
  210. $o->amount = $args['amount'] * 100; # 支付金额, 游戏后台统一单位是分
  211. $o->callbackInfo = $args['extReserved']; # 透传参数, uid-uc,zoneid,cpOrderId
  212. $o->otherInfo = $args['pf']; # 手Qor微信的平台串
  213. return $o;
  214. }
  215. /**
  216. * 解析360充值通知
  217. */
  218. public static function Parse_360Order($args) {
  219. $exts = explode(',', $args['app_ext1']);
  220. $o = new OrderNotice();
  221. $o->channel = 'qihoo360';
  222. if (isset($args['app_order_id'])) {
  223. $o->cpOrderId = $args['app_order_id'];
  224. } else {
  225. $o->cpOrderId = $exts[2]; # 第三个参数是cpOrderId
  226. }
  227. $o->sdk_orderid = $args['order_id'];
  228. $o->status = ($args['gateway_flag'] == 'success') ? 1 : 2;
  229. $o->uid = $args['app_uid'];
  230. $o->amount = $args['amount']; # 360通知的单位是分,与后台一致
  231. $o->callbackInfo = $args['app_ext1'];
  232. $o->otherInfo = $args['user_id'];
  233. return $o;
  234. }
  235. /**
  236. * 解析vivo充值通知接口
  237. */
  238. public static function Parse_vivoOrder($args) {
  239. $o = new OrderNotice();
  240. $o->channel = 'vivo';
  241. $o->cpOrderId = $args['cpOrderNumber'];
  242. $o->sdk_orderid = $args['orderNumber'];
  243. $o->status = ($args['tradeStatus'] == '0000') ? 1 : 2;
  244. $o->uid = $args['uid'];
  245. $o->amount = $args['orderAmount']; # vivo通知的单位是分, 与游戏后台一致
  246. $o->callbackInfo = $args['extInfo'];
  247. $o->otherInfo = 'payTime:' . $args['payTime'];
  248. return $o;
  249. }
  250. /**
  251. * 解析联想支付通知
  252. * @param type $args
  253. */
  254. public static function Parse_lenovo($args) {
  255. // var_dump($args);
  256. $exts = explode(',', $args['cpprivate']);
  257. $o = new OrderNotice();
  258. $o->channel = 'lenovo';
  259. $o->cpOrderId = $args['exorderno'];
  260. $o->sdk_orderid = $args['transid'];
  261. $o->status = ($args['result'] == 0) ? 1 : 2;
  262. $o->uid = $exts[0];
  263. $o->amount = $args['money'];
  264. $o->callbackInfo = $args['cpprivate'];
  265. $o->otherInfo = 'payType:' . $args['paytype'];
  266. return $o;
  267. }
  268. /**
  269. * 解析金立支付通知
  270. * @param type $args
  271. */
  272. public static function Parse_gionee($args) {
  273. // var_dump($args);
  274. $exts = explode(',', $args['ext_info']); # 透传参数
  275. $o = new OrderNotice();
  276. $o->channel = 'gionee';
  277. $o->cpOrderId = $args['out_order_no'];
  278. // $o->sdk_orderid = $args['transid']; # 金立订单只在创建的时候返回,通知的时候没有╭(╯^╰)╮
  279. $o->status = 1; # 金立后台只将支付成功的订单进行返回,未成功订单不会有通知
  280. $o->uid = $exts[0];
  281. $o->amount = $args['deal_price'] * 100; # 金立后台单位是元, 游戏后台单位是分
  282. $o->callbackInfo = $args['ext_info'];
  283. // $o->otherInfo = ''; #
  284. return $o;
  285. }
  286. /**
  287. * 解析百度支付通知
  288. * @param type $args
  289. */
  290. public static function Parse_Baidu($args) {
  291. // var_dump($args);
  292. $o = new OrderNotice();
  293. $o->channel = 'baidu';
  294. $o->cpOrderId = $args['CooperatorOrderSerial']; # CP 订单号
  295. $o->sdk_orderid = $args['OrderSerial']; # SDK订单号
  296. $Contents = json_decode(base64_decode(urldecode($args['Content']))); # 数据结构
  297. $o->status = $Contents->OrderStatus == 1 ? 1 : 2; # 0 失败, 1 成功
  298. $o->uid = $Contents->UID; # UID
  299. $o->amount = $Contents->OrderMoney * 100; # 百度后台单位是元, 游戏后台单位是分
  300. $o->callbackInfo = $Contents->ExtInfo; # 透传参数
  301. $o->otherInfo = '银行到账时间:' . $Contents->BankDateTime # 其他信息
  302. . ' 代金券金额:' . $Contents->VoucherMoney; #
  303. return $o;
  304. }
  305. /**
  306. * 解析三星支付通知
  307. * @param type $args
  308. */
  309. public static function Parse_samsung($args) {
  310. $exts = explode(',', $args['cpprivate']);
  311. $o = new OrderNotice();
  312. $o->channel = 'samsung';
  313. if (isset($args['cporderid'])) {
  314. $o->cpOrderId = $args['cporderid'];
  315. } else {
  316. $o->cpOrderId = $exts[2]; // uid,zoneid,cporderid
  317. }
  318. $o->sdk_orderid = $args['transid']; // 平台流水号
  319. $o->status = ($args['result'] == 0) ? 1 : 2;
  320. $o->uid = $args['appuserid'];
  321. $o->amount = $args['money'] * 100; // float 单位:元, Ps.游戏后台是分
  322. $o->callbackInfo = $args['cpprivate'];
  323. $o->otherInfo = 'transtype:' . $args['transtype']; // 交易类型
  324. return $o;
  325. }
  326. /**
  327. * 解析小七手游支付通知
  328. * @param type $args
  329. */
  330. public static function Parse_x7sy($args) {
  331. $exts = explode(',', $args['extends_info_data']);
  332. $o = new OrderNotice();
  333. $o->channel = 'x7sy';
  334. if (isset($args['game_orderid'])) { // cpOrder
  335. $o->cpOrderId = $args['game_orderid'];
  336. } else {
  337. $o->cpOrderId = $exts[2]; // uid,zoneid,cporderid
  338. }
  339. $o->sdk_orderid = $args['xiao7_goid']; // 渠道流水号
  340. $o->status = 1; //($args['result'] == 0) ? 1 : 2; // 只要通知就是成功,不成功的不通知
  341. $o->uid = $args['guid'];
  342. $o->amount = $args['pay_price'] * 100; // float 单位:元, Ps.游戏后台是分
  343. // $o->callbackInfo = $args['cpprivate'];
  344. // $o->otherInfo = 'transtype:' . $args['transtype']; // 交易类型
  345. return $o;
  346. }
  347. }