notify.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. // <editor-fold defaultstate="collapsed" desc="辅助类型,可删">
  3. /**
  4. * 订单通知结构
  5. */
  6. class hw_orderNotification {
  7. public $version;
  8. public $notificationType;
  9. public $purchaseToken;
  10. public $productId;
  11. }
  12. /**
  13. * hw通知结构
  14. */
  15. class Hw_notify {
  16. /**
  17. * @var string V2
  18. */
  19. public $version;
  20. /**
  21. * @var long 通知时间 UnixTimeMilliseconds
  22. */
  23. public $notifyTime;
  24. /**
  25. * @var 通知类型 通知类型,取值如下:
  26. * ORDER:订单
  27. * SUBSCRIPTION:订阅
  28. */
  29. public $eventType;
  30. /**
  31. * @var 应用的AppId
  32. */
  33. public $applicationId;
  34. /**
  35. * @var hw_orderNotification 订单通知数据
  36. */
  37. public $orderNotification;
  38. /**
  39. * @var object 订阅通知数据
  40. */
  41. public $subNotification;
  42. }
  43. /**
  44. * 包含购买数据的订单详情 参见: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/server-data-model-0000001050986133#section264617465219
  45. */
  46. class Hw_VerifyDetails {
  47. public $applicationId;
  48. public $autoRenewing;
  49. public $orderId;
  50. public $kind;
  51. public $packageName;
  52. /**
  53. * @var string 关键, 这个是在华为后台配置的
  54. */
  55. public $productId;
  56. public $productName;
  57. public $purchaseTime;
  58. public $purchaseTimeMillis;
  59. /**
  60. * @var int 重要, 订单交易状态。
  61. * -1:初始化
  62. * 0:已购买
  63. * 1:已取消
  64. * 2:已撤销或已退款
  65. * 3:待处理
  66. */
  67. public $purchaseState;
  68. /**
  69. * @var string 重要: 透传参数
  70. */
  71. public $developerPayload;
  72. /**
  73. * @var string 重要: 货币类型
  74. */
  75. public $currency;
  76. /**
  77. * @var int 重要 结算金额
  78. */
  79. public $price;
  80. public $purchaseToken;
  81. /**
  82. * @var string (华为)交易单号, 用户支付成功后生成.
  83. */
  84. public $payOrderId;
  85. }
  86. class Hw_VerifyResp {
  87. public $responseCode;
  88. public $responseMessage;
  89. /**
  90. * @var Hw_VerifyDetails 包含购买数据的订单详情
  91. */
  92. public $purchaseTokenData;
  93. public $dataSignature;
  94. public $signatureAlgorithm;
  95. }
  96. // </editor-fold>
  97. /**
  98. * 再次恢复后台通知模式
  99. * @version
  100. * 1.0.1 海外版适配 at 2022.10.19
  101. * 1.0.0 接收来自客户端的发货通知(支付) (不依赖后台通知,改为验签模式)
  102. * Created at 2020-9-21. by --gwang
  103. * @author gwang (wanggangzero@qq.com)
  104. * @copyright 2020.9.21, SJZ LoyalSoft Corporation & gwang. All rights reserved.
  105. *
  106. */
  107. include_once __DIR__ . '/../../../main.php'; # 导入game utils
  108. #
  109. //include_once __DIR__ . '/../deliverProc.php'; # 导入发货逻辑
  110. //require_once __DIR__ . '/../Mo/OrderHuaweiModel.php'; # 导入订单识别
  111. require_once __DIR__ . '/order_service.php'; # 华为辅助代码
  112. include_once __DIR__ . '/../Mo/payResp.php'; # 导入通用返回值结构
  113. include_once __DIR__ . '/../Mo/payRequest.php'; # 导入通用返回值结构
  114. require_once __DIR__ . '/../Mo/OrderNotice.php';
  115. //require_once 'config.huawei.php'; # 配置文件
  116. //require_once 'HuaweiSignUtils.php'; # 与客户端通讯验签
  117. //require_once 'config_for_hw_oversea.php'; # 配置文件
  118. use loyalsoft\CLog;
  119. use loyalsoft\HttpUtil;
  120. use loyalsoft\pay\OrderNotice;
  121. header("Content-Type: application/json; charset=utf-8");
  122. $tag = "[notify.华为] "; # 日志标签
  123. $errMsg = "success";
  124. $result = 200;
  125. try {
  126. CLog::pay("$tag收到客户端请求: " . HttpUtil::getQueryString()); # 打日志
  127. $json = HttpUtil::getQueryString(); # 提取参数
  128. // false and $params = new Hw_notify(); # 智能感知提示
  129. $params = json_decode($json); # 转为对象
  130. if ($params->eventType == "ORDER") { # 是: 订单通知
  131. $purchaseToken = $params->orderNotification->purchaseToken;
  132. $productId = $params->orderNotification->productId;
  133. CLog::pay($tag . json_encode($params)); # 打日志
  134. $orderService = new OrderService();
  135. CLog::pay($tag . json_encode($orderService)); # 打日志
  136. // false and $respData = new Hw_VerifyResp(); # 智能感知提示
  137. $respData = $orderService->verifyToken($purchaseToken, $productId); # 去华为服务端校验purchaseToken. (内含http通讯)
  138. CLog::pay($tag . json_encode($respData)); # 打日志
  139. # Ps. 返回值结构: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/api-order-verify-purchase-token-0000001050746113
  140. $responseCode = (int) ($respData->responseCode);
  141. if ($responseCode == 0) {
  142. # Ps. 订单详情: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/server-data-model-0000001050986133#section264617465219
  143. $purchaseTokenData = json_decode($respData->purchaseTokenData); # 解析订单详情
  144. # 模拟创建订单流程
  145. $payReq = PayRequest::From_HW((array) $purchaseTokenData);
  146. if ($payReq->InserDataBase()) { # end of 模拟创建订单流程
  147. $order = OrderNotice::Parse_hwOrder((array) $purchaseTokenData); # 转换为内部订单格式
  148. CLog::pay("$tag [order]" . json_encode($order)); # 打日志
  149. if ($order != null) {
  150. if ($order->Check()) { # 订单校验, 1代表支付成功
  151. if ($order->status == 1) { # 订单状态是成功
  152. $order->UpdateOrderStatus(); # 更新订单状态,->已付款
  153. $errMsg = " [发货] 订单: " . $order->cpOrderId . ", 金额: " . $order->amount; #
  154. } else if ($order->status == 2) { # status为2(failed)的情况
  155. $order->UpdateOrderStatus(); # 直接更新订单状态,->支付失败
  156. $errMsg = "[不发货] 订单: " . $order->cpOrderId; # 这个也返回200, 不必重复通知了
  157. } else {
  158. $errMsg = "[处理结果]: FAILURE (未知的支付状态)"; # 日志
  159. $result = 502; # 这里酌情吧 500还是200
  160. }
  161. } else {
  162. $result = 503; # 订单校验问题
  163. }
  164. } else {
  165. $errMsg = "订单归一化失败!";
  166. $result = 504;
  167. }
  168. } else {
  169. $errMsg = "内部订单生成失败!";
  170. $result = 500;
  171. }
  172. } else { # 验签失败
  173. $result = 501;
  174. $errMsg = "去华为验签失败" . $respData->responseMessage;
  175. }
  176. } else { # 其他类型的通知, 不做处理 --gwang
  177. $errMsg = "invalid notify info!";
  178. $reult = 400;
  179. }
  180. } catch (Exception $e) { # 捕获异常
  181. $result = 500;
  182. $errMsg = $e->getMessage();
  183. }
  184. CLog::pay($tag . $errMsg); # 日志
  185. http_response_code($result); # 设定响应码
  186. echo($errMsg); # 输出body