'Order Processing', 2 => 'Payment Failed, Insufficient Balance', 9 => 'Payment Failed' ]; public function __construct() { } /** * 华为发货接口 */ public function deliveryHuaweiPay($param){ //验证华为返回支付参数是否正确 $ret = $this->validateHuaweiPay($param); if( !$ret ){ return $this->responsePayment(5, 'SIGN ERROR'); } //校验支付结果 $orderId = $param['TradeNo'];//订单ID $productId = $param['ProductId'];//商品ID $tradeStatus = $param['TradeStatus'];//支付结果 0:支付成功1:订单处理中(最终结果以后台通知为准,如有必要由应用调用queryPayment做漏单查询)2:支付失败,余额不足9:支付失败,其它错误 $uin = $param['Uin'];//华为用户的UIN,如果未登录则为空 $appId = $param['AppId'];//应用ID $act = $param['Act'];//101:表示支付结果通知2.0 $consumeStreamId = $param['ConsumeStreamId']; if(empty($act)) { oo::logs()->debug3('act错误:'.$appId.' 订单号:'.$orderId.' uin:'.$uin.' 华为流水号:'.$consumeStreamId, 'hwPaymentFail.php'); return $this->responsePayment(3, 'ACT ERROR'); } if(empty($appId) || $appId != $this->appId) { oo::logs()->debug3('appid错误:'.$appId.' 订单号:'.$orderId.' uin:'.$uin.' 华为流水号:'.$consumeStreamId, 'hwPaymentFail.php'); return $this->responsePayment(2, 'APPID ERROR'); } if($tradeStatus != 0) { $msg = $this->error[$tradeStatus] ?? 'Payment Failed'; oo::logs()->debug3('支付错误码:'.$tradeStatus.' 订单号:'.$orderId.' uin:'.$uin.' 华为流水号:'.$consumeStreamId, 'hwPaymentFail.php'); return $this->responsePayment(0, $msg); } $dbGoods = oo::commonOprModel('goods')->getGoodsInfoByOrderId($orderId); if (empty($dbGoods) || $productId != $dbGoods['gpid']) {//验证商品对不对 oo::logs()->debug3('商品错误 orderId:'.$orderId.' productId:'.$productId.' dbgoods:'.json_encode($dbGoods) . 'uin:'.$uin.' 华为流水号:'.$consumeStreamId,'hwPaymentFail.php'); return $this->responsePayment(0, 'GOODS ERROR'); } $uid = $dbGoods['uid']; $pubDeliveryRet = oo::commonOprModel('payment')->pubDelivery($uid, $orderId, $consumeStreamId); if( $pubDeliveryRet === true || $pubDeliveryRet === -3 ){//发货成功或者是已发货的订单,则返回正确 return $this->responsePayment(1, 'SUCCESS'); } return $this->responsePayment(0, 'DELIVERY FAIL'); } /** * 返回消息到华为服务器 * @param $errorCode int 错误码:0:失败 1:成功(已处理的请求也作为成功返回) 2:AppId无效 3:Act无效 4:参数无效 5:Sign无效 其他:应用自己定义,并在错误描述中体现 * @param string $errMsg */ private function responsePayment($errorCode, $errMsg = '') { $data['ErrorCode'] = intval($errorCode); $data['ErrorDesc'] = $errMsg; return $data; } /** * 验证华为支付 */ protected function validateHuaweiPay($param) { if(empty($param)) { return false; } $signature = urldecode($param['Signature']); unset($param['Signature']); $urlParam = $this->dealUrlParam($param); $valid = $this->verify($urlParam, $signature); if (!empty($valid)) { oo::logs()->debug3('valid:'.$valid.' urlParam:'.$urlParam .' signature:'.$signature, 'hwPaymentVerifyFail.php'); return false; } return true; } /** * 对参数进行处理 * @param $data * @return string */ protected function dealUrlParam($data) { $urlParam = ''; //按ascii码升序排列 ksort($data); foreach ($data as $key => $v) { $v = urldecode($v); $urlParam .= '&'.$key .'='.$v; } $urlParam = ltrim($urlParam, '&'); return $urlParam; } /** * 使用RSA算法 SHA1WithRSA进行签名 --取消(SHA256WithRSA) * @param $data * @return string */ protected function verify($data, $signature) { $key = "-----BEGIN PUBLIC KEY-----\n".chunk_split( $this->_publicKey, 64, "\n" ).'-----END PUBLIC KEY-----'; $key = openssl_get_publickey( $key ); if ( empty( $key ) ) { return 'Please pass a Base64-encoded public key from the Market portal'; } // $signature = str_replace('\\', '', $signature); // $signature = str_replace(' ', '+', $signature); $result = openssl_verify( $data, base64_decode( $signature ), $key, OPENSSL_ALGO_SHA1 ); if ( 0 === $result ) { oo::logs()->debug3('openssl error string:'.openssl_error_string()."\n".' 验签的参数:'.$data."\n".' 验签的signature:'.$signature, 'hw_verify.php'); return 'fail to verify'; } else if ( 1 !== $result ) { return 'Unknown error verifying the signature in openssl_verify '.$result; } return ''; } }