paymentos.php 5.7 KB

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