url($config['type'], $config['id']); $this->config = $config; } /** * 通知 */ public function notify() { $input = file_get_contents("php://input"); if ($input) { parse_str($input, $input); } else { $input = Dever::input(); } $this->log('支付回调-初始化', $input); return; ksort($input); $input = http_build_query($input); $tools = new \Cmbc\Handle(); $callback = $tools->get('notify', $this->config); $result = $callback->request($input, $this); if ($result) { $this->log('支付回调-获取数据', $result); $this->updateOrder($result['mhtOrderNo'], $result['mhtOrderAmt']); echo 'SUCCESS';die; } else { echo 'FAILED';die; } } /** * 获取统一下单的基本信息 */ public function order($account_id, $project_id, $uid, $username, $product_id, $name, $cash, $openid = false, $type = 1, $order_id = false) { $trade_type = $this->getType($type); $order_id = $this->createOrder($uid, $username, $account_id, $project_id, $product_id, $name, $cash, $this->config['type'], $order_id); $request['merOrderId'] = $order_id; $request['mid'] = $this->config['mchid']; $request['tid'] = $this->config['key']; $request['instMid'] = 'MINIDEFAULT'; $request['totalAmount'] = $cash * 100; $request['subAppId'] = $this->config['appid']; $request['requestTimestamp'] = date("Y-m-d H:i:s"); $request['expireTime'] = $this->config['timeout']; $request['notifyUrl'] = $this->config['notify']; $request['tradeType'] = 'MINI'; /* # 是否启用分账 $request['divisionFlag'] = true; # 平台分账金额 $request['platformAmount'] = $request['totalAmount'] * 0.1; if ($request['divisionFlag']) { $request['subOrders'] = array(); $request['subOrders']['mid'] = 1; $request['subOrders']['totalAmount'] = $request['totalAmount'] - $request['platformAmount']; }*/ if (!$openid) { # 测试的openid $request['subOpenId'] = 'ofBUV0RUoy_8C4VctZjrSDGzhUfY'; } else { $request['subOpenId'] = $openid; } $result = Base::pay($request, $this->config); $this->updateOrderParam($order_id, $result); return $result; } # 退款 public function refund($order_id, $cash, $refund_order_id = false) { $request['merOrderId'] = $order_id; $request['mid'] = $this->config['mchid']; $request['tid'] = $this->config['key']; $request['instMid'] = 'MINIDEFAULT'; $request['subAppId'] = $this->config['appid']; $request['requestTimestamp'] = date("Y-m-d H:i:s"); $request['targetOrderId'] = $order_id; $request['refundAmount'] = $cash * 100; if ($refund_order_id) { $request['refundOrderId'] = $refund_order_id; } $result = Base::refund($request, $this->config); if (isset($result['refundStatus']) && $result['refundStatus'] == 'SUCCESS') { return true; } return false; } # 查询 public function query($order_id) { $request['merOrderId'] = $order_id; $request['mid'] = $this->config['mchid']; $request['tid'] = $this->config['key']; $request['instMid'] = 'MINIDEFAULT'; $request['requestTimestamp'] = date("Y-m-d H:i:s"); $result = Base::refund($request, $this->config); return $result; } # 关闭订单 public function close($order_id) { $request['merOrderId'] = $order_id; $request['mid'] = $this->config['mchid']; $request['tid'] = $this->config['key']; $request['instMid'] = 'MINIDEFAULT'; $request['requestTimestamp'] = date("Y-m-d H:i:s"); $result = Base::close($request, $this->config); return $result; } /** * 获取二维码支付 */ public function qrcode($order, $refer) { $notify = new \NativePay(); $result = $notify->GetPayUrl($order); $url = $result['code_url']; return $url; } /** * 获取小程序支付 */ public function applet($order) { $result = array(); if (isset($order['prepay_id'])) { $result['time'] = $order['timeStamp']; $result['nonce_str'] = $order['nonceStr']; $result['prepay_id'] = $order['prepay_id']; $result['sign_type'] = $order['signType']; $result['sign'] = $order['paySign']; } return $result; } /** * 获取页面支付 */ public function page($order, $refer) { $refer = urldecode($refer); $tools = new \JsApiPay($this->config); $info = $tools->GetJsApiParameters($order); $html = ''; return $html; } private function getType($type) { switch ($type) { case 1: $type = 'JSAPI'; break; case 2: $type = 'NATIVE'; break; case 3: $type = 'APP'; break; case 4: $type = 'MWEB'; break; } return $type; } } class Base { static $test_host = 'https://test-api-open.chinaums.com/'; static $host = 'https://api-mop.chinaums.com/'; static $signMethod = 'SHA256'; //签名方式 # 获取token static $token_url = 'v1/token/access'; # 微信下单支付 static $pay_wechat_url = 'v1/netpay/wx/unified-order'; # 支付宝下单支付 static $pay_alipay_url = 'v1/netpay/trade/create'; # 云闪付下单支付 static $pay_uac_url = 'v1/netpay/uac/mini-order'; # 交易查询 static $query_url = 'v1/netpay/query'; # 退款 static $refund_url = 'v1/netpay/refund'; # 退款查询 static $refund_query_url = 'v1/netpay/refund-query'; # 订单关闭 static $close_url = 'v1/netpay/close'; //===================== 支付相关 ============================== /** * 支付交易 */ static public function pay($param, $config) { $url = self::$refund_url; $result = self::get($url, $param, $config); return $result; } /** * 支付撤销 */ static public function close() { $url = self::$close_url; $result = self::get($url, $param, $config); return $result; } /** * 交易退款 */ static public function refund($param, $config) { $url = self::$pay_wechat_url; $result = self::get($url, $param, $config); return $result; } /** * 交易查询 */ static public function query() { $url = self::$query_url; $result = self::get($url, $param, $config); return $result; } /** * 交易退款查询 */ static public function refundQuery() { $url = self::$refund_query_url; $result = self::get($url, $param, $config); return $result; } //====================== 获取调用凭证=========================== /** * 通用调用凭证获取 * 默认使用token方式,使用签名方式需要传入参数 */ static public function getAuth($type = 'token', $param, $config) { if ($type === 'token') { return self::getAccessTokenByToken($config); } return self::getAccessTokenBySig($param, $config); } /** * 方式一,OPEN-ACCESS-TOKEN方式 */ static function getAccessTokenByToken($config) { $param = [ 'appId' => $config['appid'], 'timestamp' => date('YmdHis'), 'nonce' => md5(uniqid(microtime(true),true)), 'signMethod' => self::$signMethod, ]; $param['signature'] = self::signature($param, $config['appsecret']); $result = self::get(self::$token_url, $param, $config); if (isset($result['errCode']) && isset($result['accessToken'])) { return 'OPEN-ACCESS-TOKEN AccessToken='.$result['accessToken']; } return ''; } /** * 方式二,OPEN-BODY-SIG方式 */ static function getAccessTokenBySig($data, $config) { $param = [ 'AppId' => $config['appid'], 'Timestamp' => date('YmdHis'), 'Nonce' => md5(uniqid(microtime(true),true)) ]; return 'OPEN-BODY-SIG AppId="'.$param['AppId'].'", Timestamp="'.$param['Timestamp'].'", Nonce="'.$param['Nonce'].'", Signature="'.self::signature2($data, $param, $config['appsecret']).'"'; } /** * 计算签名,方式一 */ static function signature($param, $appsecret) { return bin2hex(hash(self::$signMethod, $param['appId'].$param['timestamp'].$param['nonce'].$appsecret, true)); } /** * 计算签名,方式二 */ static function signature2($data, $param, $appsecret) { $str = bin2hex(hash('sha256', Dever::json_encode($data), true)); return base64_encode(hash_hmac('sha256', $param['AppId'].$param['Timestamp'].$param['Nonce'].$str, $appsecret, true)); } /** * 获取信息 */ static function get($url, $param, $config) { $url = $config['box'] == 1 ? self::$host . $url : self::$test_host . $url; $header = array(); $header['Authorization'] = self::getAuth('sig', $param, $config); $result = Dever::curl($url, $param, 'post', true, $header); if (strstr($result, '')) { Dever::alert('系统错误'); } $result = Dever::json_decode($result); print_r($param); print_r($result);die; if (isset($result['errCode'])) { if ($result['errCode'] == '0000') { return $result; } elseif (isset($result['errInfo'])) { Dever::alert($result['errInfo']); } elseif (isset($result['errMsg'])) { Dever::alert($result['errMsg']); } } else { Dever::alert('系统错误'); } } }