paymenthw.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. defined('IN_WEB') or die('Include Error!');
  3. /**
  4. * Huawei本地支付
  5. */
  6. include 'verifyhw.php';
  7. class ModelPaymenthw extends ModelVerifyhw
  8. {
  9. private $appId = 1000151708;
  10. private $error = [
  11. 1 => 'Order Processing',
  12. 2 => 'Payment Failed, Insufficient Balance',
  13. 9 => 'Payment Failed'
  14. ];
  15. public function __construct()
  16. {
  17. }
  18. /**
  19. * 华为发货接口
  20. */
  21. public function deliveryHuaweiPay($param){
  22. //验证华为返回支付参数是否正确
  23. $ret = $this->validateHuaweiPay($param);
  24. if( !$ret ){
  25. return $this->responsePayment(5, 'SIGN ERROR');
  26. }
  27. //校验支付结果
  28. $orderId = $param['TradeNo'];//订单ID
  29. $productId = $param['ProductId'];//商品ID
  30. $tradeStatus = $param['TradeStatus'];//支付结果 0:支付成功1:订单处理中(最终结果以后台通知为准,如有必要由应用调用queryPayment做漏单查询)2:支付失败,余额不足9:支付失败,其它错误
  31. $uin = $param['Uin'];//华为用户的UIN,如果未登录则为空
  32. $appId = $param['AppId'];//应用ID
  33. $act = $param['Act'];//101:表示支付结果通知2.0
  34. $consumeStreamId = $param['ConsumeStreamId'];
  35. if(empty($act)) {
  36. oo::logs()->debug3('act错误:'.$appId.' 订单号:'.$orderId.' uin:'.$uin.' 华为流水号:'.$consumeStreamId, 'hwPaymentFail.php');
  37. return $this->responsePayment(3, 'ACT ERROR');
  38. }
  39. if(empty($appId) || $appId != $this->appId) {
  40. oo::logs()->debug3('appid错误:'.$appId.' 订单号:'.$orderId.' uin:'.$uin.' 华为流水号:'.$consumeStreamId, 'hwPaymentFail.php');
  41. return $this->responsePayment(2, 'APPID ERROR');
  42. }
  43. if($tradeStatus != 0) {
  44. $msg = $this->error[$tradeStatus] ?? 'Payment Failed';
  45. oo::logs()->debug3('支付错误码:'.$tradeStatus.' 订单号:'.$orderId.' uin:'.$uin.' 华为流水号:'.$consumeStreamId, 'hwPaymentFail.php');
  46. return $this->responsePayment(0, $msg);
  47. }
  48. $dbGoods = oo::commonOprModel('goods')->getGoodsInfoByOrderId($orderId);
  49. if (empty($dbGoods) || $productId != $dbGoods['gpid']) {//验证商品对不对
  50. oo::logs()->debug3('商品错误 orderId:'.$orderId.' productId:'.$productId.' dbgoods:'.json_encode($dbGoods) . 'uin:'.$uin.' 华为流水号:'.$consumeStreamId,'hwPaymentFail.php');
  51. return $this->responsePayment(0, 'GOODS ERROR');
  52. }
  53. $uid = $dbGoods['uid'];
  54. $pubDeliveryRet = oo::commonOprModel('payment')->pubDelivery($uid, $orderId, $consumeStreamId);
  55. if( $pubDeliveryRet === true || $pubDeliveryRet === -3 ){//发货成功或者是已发货的订单,则返回正确
  56. return $this->responsePayment(1, 'SUCCESS');
  57. }
  58. return $this->responsePayment(0, 'DELIVERY FAIL');
  59. }
  60. /**
  61. * 返回消息到华为服务器
  62. * @param $errorCode int 错误码:0:失败 1:成功(已处理的请求也作为成功返回) 2:AppId无效 3:Act无效 4:参数无效 5:Sign无效 其他:应用自己定义,并在错误描述中体现
  63. * @param string $errMsg
  64. */
  65. private function responsePayment($errorCode, $errMsg = '')
  66. {
  67. $data['ErrorCode'] = intval($errorCode);
  68. $data['ErrorDesc'] = $errMsg;
  69. return $data;
  70. }
  71. /**
  72. * 验证华为支付
  73. */
  74. protected function validateHuaweiPay($param)
  75. {
  76. if(empty($param)) {
  77. return false;
  78. }
  79. $signature = urldecode($param['Signature']);
  80. unset($param['Signature']);
  81. $urlParam = $this->dealUrlParam($param);
  82. $valid = $this->verify($urlParam, $signature);
  83. if (!empty($valid)) {
  84. oo::logs()->debug3('valid:'.$valid.' urlParam:'.$urlParam .' signature:'.$signature, 'hwPaymentVerifyFail.php');
  85. return false;
  86. }
  87. return true;
  88. }
  89. /**
  90. * 对参数进行处理
  91. * @param $data
  92. * @return string
  93. */
  94. protected function dealUrlParam($data)
  95. {
  96. $urlParam = '';
  97. //按ascii码升序排列
  98. ksort($data);
  99. foreach ($data as $key => $v) {
  100. $v = urldecode($v);
  101. $urlParam .= '&'.$key .'='.$v;
  102. }
  103. $urlParam = ltrim($urlParam, '&');
  104. return $urlParam;
  105. }
  106. /**
  107. * 使用RSA算法 SHA1WithRSA进行签名 --取消(SHA256WithRSA)
  108. * @param $data
  109. * @return string
  110. */
  111. protected function verify($data, $signature)
  112. {
  113. $key = "-----BEGIN PUBLIC KEY-----\n".chunk_split( $this->_publicKey, 64, "\n" ).'-----END PUBLIC KEY-----';
  114. $key = openssl_get_publickey( $key );
  115. if ( empty( $key ) )
  116. {
  117. return 'Please pass a Base64-encoded public key from the Market portal';
  118. }
  119. // $signature = str_replace('\\', '', $signature);
  120. // $signature = str_replace(' ', '+', $signature);
  121. $result = openssl_verify( $data, base64_decode( $signature ), $key, OPENSSL_ALGO_SHA1 );
  122. if ( 0 === $result )
  123. {
  124. oo::logs()->debug3('openssl error string:'.openssl_error_string()."\n".' 验签的参数:'.$data."\n".' 验签的signature:'.$signature, 'hw_verify.php');
  125. return 'fail to verify';
  126. }
  127. else if ( 1 !== $result )
  128. {
  129. return 'Unknown error verifying the signature in openssl_verify '.$result;
  130. }
  131. return '';
  132. }
  133. }