notify.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. /**
  3. * 接收华为后台通知(支付)
  4. * @version
  5. * 1.0.0 Created at 2018-3-1. by --gwang
  6. * @author gwang (mail@wanggangzero.cn)
  7. * @copyright ? 2018-3-1, SJZ LoyalSoft Corporation & gwang. All rights reserved.
  8. *
  9. */
  10. include_once __DIR__ . '/../../../main.php'; # 导入game utils
  11. include_once __DIR__ . '/../Mo/resp.php'; # 导入通用返回值结构
  12. include_once __DIR__ . '/../Mo/payRequest.php'; # 导入通用返回值结构
  13. require_once __DIR__ . '/../Mo/OrderNotice.php';
  14. require_once 'config.huawei.php'; # 配置文件
  15. // 签名算法
  16. use loyalsoft\CLog;
  17. use loyalsoft\HttpUtil;
  18. use loyalsoft\pay\OrderNotice;
  19. header("Content-Type: application/json; charset=utf-8");
  20. /**
  21. * 华为验签算法
  22. * @param type $params
  23. * @return boolean
  24. */
  25. function verify_sign_huawei($params)
  26. {
  27. ksort($params);
  28. $sign = $params['sign'];
  29. $signType = isset($params['signType']) ? $params['signType'] : "RSA"; # 默认RSA
  30. $form = $params;
  31. unset($form['sign']);
  32. unset($form['signType']);
  33. if (empty($sign)) {
  34. return false;
  35. }
  36. $content = "";
  37. $i = 0;
  38. foreach ($form as $key => $value) {
  39. if ($key != "sign" && $key != "signType") {
  40. $content .= ($i == 0 ? '' : '&') . $key . '=' . $value;
  41. }
  42. $i++;
  43. }
  44. $pubKey = config_for_huawei::Inst()->getPubkey();
  45. $openssl_public_key = @openssl_get_publickey($pubKey);
  46. if (!$openssl_public_key) {
  47. return false;
  48. }
  49. $ok = @openssl_verify($content, base64_decode($sign), $openssl_public_key, $signType);
  50. @openssl_free_key($openssl_public_key);
  51. return $ok;
  52. }
  53. class OrderNotice_huawei extends OrderNotice
  54. {
  55. static public function Parse($args)
  56. {
  57. $o = new OrderNotice();
  58. $o->callbackInfo = rawurldecode($args['extReserved']); # 透传参数, uid-uc,zoneid,cpOrderId
  59. $extArgs = explode(',', $o->callbackInfo);
  60. $o->channel = "huawei"; # 渠道代码
  61. $o->cpOrderId = $args['requestId']; # 订单编号
  62. $o->status = ($args["result"] == "0") ? 1 : 2; # 订单状态(华为返回值: 0/成功, 1. 退款成功(暂未启用), 其他失败)
  63. $o->uid = $extArgs[0]; // openid # 玩家uid
  64. $o->amount = $args['amount'] * 100; # 支付金额, 统一单位是分
  65. $o->sdk_orderid = $args['orderId']; # 华为支付平台订单编号
  66. // $o->otherInfo = $args['notifyTime'];
  67. return $o;
  68. }
  69. }
  70. try {
  71. HttpUtil::PostOnly(); # 华为那边肯定以POST方式来发送消息
  72. CLog::pay("[notify.华为] 收到支付回调请求: " . HttpUtil::getQueryString());
  73. $cfg = config_for_huawei::Inst(); # 配置信息
  74. $params = HttpUtil::getQueryParas(); # 提取参数
  75. if ($sign != verify_sign_huawei($params)) { # 验证签名
  76. exit('{"result":1}'); # 返回验签失败
  77. }
  78. $order = OrderNotice_huawei::Parse($params); # 将参数归一化到order
  79. if ($order != null) {
  80. if ($order->Check()) { # 订单校验, 1代表支付成功
  81. if ($order->status == 1) { # 订单状态是成功
  82. $order->UpdateOrderStatus(); # 更新订单状态,->已付款
  83. CLog::pay("[notify.华为] [发货] 订单: " . $order->cpOrderId . ", 金额: " . $order->amount);
  84. } else if ($order->status == 2) { # status为2(failed)的情况
  85. $order->UpdateOrderStatus(); # 直接更新订单状态,->支付失败
  86. CLog::pay("[notify.华为] [不发货] 订单: " . $order->cpOrderId);
  87. } else {
  88. echo 'FAILURE';
  89. CLog::pay("[notify.华为][处理结果]: FAILURE (未知的支付状态)"); # 日志
  90. return;
  91. }
  92. echo 'SUCCESS'; //返回给sdk server的响应内容
  93. CLog::pay("[notify.华为][处理结果]:" . "SUCCESS"); # 日志
  94. return;
  95. }
  96. }
  97. CLog::pay("[notify.华为][处理结果]:" . "FAILURE"); # 日志
  98. echo 'FAILURE'; //返回给sdk server的响应内容 ,对于重复多次通知失败的订单,请参考文档中通知机制。
  99. return;
  100. } catch (Exception $e) {
  101. CLog::pay("[notify.华为]" . $e->getMessage()); # 日志
  102. throw new exception($e->getMessage());
  103. }