├── composer.json ├── src ├── QQPayException.php ├── TransferService.php ├── BaseService.php └── PaymentService.php ├── README.md └── LICENSE /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cccyun/qqpay-sdk", 3 | "description": "QQ钱包支付第三方 PHP SDK,基于官方最新版本。", 4 | "type": "library", 5 | "keywords": [ 6 | "qqpay", 7 | "qpay", 8 | "QQ支付" 9 | ], 10 | "license": "MIT", 11 | "minimum-stability": "dev", 12 | "prefer-stable": true, 13 | "require": { 14 | "php": ">=7.1" 15 | }, 16 | "authors": [ 17 | { 18 | "name": "caihong", 19 | "email": "admin@cccyun.cn" 20 | } 21 | ], 22 | "autoload": { 23 | "psr-4": { 24 | "QQPay\\": "src/" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/QQPayException.php: -------------------------------------------------------------------------------- 1 | res = $res; 18 | if (isset($res['err_code'])) { 19 | $message = '['.$res['err_code'].']'.$res['err_code_des']; 20 | } elseif (isset($res['return_code'])) { 21 | $message = '['.$res['return_code'].']'.$res['return_msg']; 22 | } else { 23 | $message = '返回数据解析失败'; 24 | } 25 | parent::__construct($message); 26 | } 27 | 28 | public function getResponse() 29 | { 30 | return $this->res; 31 | } 32 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QQPay SDK for PHP 2 | QQ钱包支付第三方 PHP SDK,基于官方最新版本。 3 | 4 | ### 功能特点 5 | 6 | - 根据QQ钱包支付最新API开发,相比官方SDK,功能更完善,代码更简洁 7 | - 支持Composer安装,无需加载多余组件,可应用于任何平台或框架 8 | - 符合`PSR`标准,你可以各种方便的与你的框架集成 9 | - 基本完善的PHPDoc,可以随心所欲添加本项目中没有的API接口 10 | 11 | ### 环境要求 12 | 13 | `PHP` >= 7.1 14 | 15 | ### 使用方法 16 | 17 | 1. Composer 安装。 18 | 19 | ```bash 20 | composer require cccyun/qqpay-sdk 21 | ``` 22 | 23 | 2. 创建配置文件 [`config.php`](./examples/config.php),填写QQ钱包支付商户信息。 24 | 25 | 3. 引入配置文件,构造请求参数,调用PaymentService中的方法发起请求,参考 [`examples/qrpay.php`](./examples/qrpay.php)。 26 | 27 | 4. 更多实例,请移步 [`examples`](examples/) 目录。 28 | 29 | 5. 类功能说明 30 | 31 | | 类名 | 说明 | 32 | | --------------- | ------------------------------------ | 33 | | PaymentService | 基础支付服务类,所有支付功能都用这个 | 34 | | TransferService | QQ钱包企业付款功能 | 35 | 36 | 6. 要对接的API在以上实现类中没有,可根据QQ钱包官方的文档,使用BaseService类中的execute方法直接调用接口。 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 消失的彩虹海 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/TransferService.php: -------------------------------------------------------------------------------- 1 | publicParams = [ 16 | 'mch_id' => $this->mchId, 17 | 'nonce_str' => $this->getNonceStr(), 18 | ]; 19 | } 20 | 21 | /** 22 | * 企业付款到余额 23 | * @param $out_trade_no 商户订单号 24 | * @param $uin 收款QQ号码 25 | * @param $name 用户姓名(填写后校验) 26 | * @param $amount 金额 27 | * @param $memo 备注 28 | * @return mixed {"out_trade_no":"商户订单号","transaction_id":"QQ钱包订单号"} 29 | */ 30 | public function transfer($out_trade_no, $uin, $name, $amount, $memo) 31 | { 32 | $url = 'https://api.qpay.qq.com/cgi-bin/epay/qpay_epay_b2c.cgi'; 33 | $params = [ 34 | 'input_charset' => 'UTF-8', 35 | 'out_trade_no' => $out_trade_no, 36 | 'uin' => $uin, 37 | 'fee_type' => 'CNY', 38 | 'total_fee' => $amount, 39 | 'memo' => $memo, 40 | 'check_real_name' => '0' 41 | ]; 42 | if (!empty($name)) { 43 | $params['check_name'] = 'FORCE_CHECK'; 44 | $params['re_user_name'] = $name; 45 | } 46 | $params += [ 47 | 'op_user_id' => $this->opUserId, 48 | 'op_user_passwd' => md5($this->opUserPwd), 49 | 'spbill_create_ip' => $_SERVER['SERVER_ADDR'] 50 | ]; 51 | return $this->execute($url, $params, true); 52 | } 53 | 54 | /** 55 | * 查询企业付款 56 | * @param $out_trade_no 商户订单号 57 | * @return mixed {"out_trade_no":"商户订单号","detail_id":"微信付款单号","status":"转账状态","reason":"失败原因","openid":"用户openid","transfer_name":"用户姓名","payment_amount":"付款金额","transfer_time":"转账时间","payment_time":"付款成功时间","desc":"付款备注"} 58 | */ 59 | public function transferQuery($out_trade_no) 60 | { 61 | $url = 'https://qpay.qq.com/cgi-bin/pay/qpay_epay_query.cgi'; 62 | $params = [ 63 | 'out_trade_no' => $out_trade_no 64 | ]; 65 | return $this->execute($url, $params); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/BaseService.php: -------------------------------------------------------------------------------- 1 | mchId = $config['mchid']; 46 | $this->apiKey = $config['apikey']; 47 | if (isset($config['appid'])) { 48 | $this->appId = $config['appid']; 49 | } 50 | if (isset($config['appkey'])) { 51 | $this->appKey = $config['appkey']; 52 | } 53 | $this->sslCertPath = $config['sslcert_path']; 54 | $this->sslKeyPath = $config['sslkey_path']; 55 | if (isset($config['op_userid'])) { 56 | $this->opUserId = $config['op_userid']; 57 | } 58 | if (isset($config['op_userpwd'])) { 59 | $this->opUserPwd = $config['op_userpwd']; 60 | } 61 | } 62 | 63 | 64 | /** 65 | * 请求接口并解析返回数据 66 | * @param $url url 67 | * @param $params 请求参数 68 | * @param $cert 是否需要证书 69 | * @return mixed 70 | */ 71 | public function execute($url, $params, $cert = false) 72 | { 73 | $params = array_merge($this->publicParams, $params); 74 | $params['sign'] = $this->makeSign($params); 75 | $xml = $this->array2Xml($params); 76 | $response = $this->curl($url, $xml, $cert); 77 | $result = $this->xml2array($response); 78 | if (isset($result['return_code']) && $result['return_code'] == 'SUCCESS') { 79 | if (isset($result['result_code']) && $result['result_code'] == 'SUCCESS') { 80 | if (isset($result['sign']) && !$this->checkSign($result)) { 81 | throw new \Exception('返回数据验签失败'); 82 | } 83 | return $result; 84 | } 85 | } 86 | throw new QQPayException($result); 87 | } 88 | 89 | /** 90 | * 下载账单接口 91 | * @param $url url 92 | * @param $params 请求参数 93 | * @param $cert 是否需要证书 94 | * @return mixed 95 | */ 96 | public function download($url, $params) 97 | { 98 | $params = array_merge($this->publicParams, $params); 99 | $params['sign'] = $this->makeSign($params); 100 | $xml = $this->array2Xml($params); 101 | $response = $this->curl($url, $xml); 102 | return $response; 103 | } 104 | 105 | /** 106 | * 验签 107 | * @param $data 108 | * @return bool 109 | */ 110 | protected function checkSign($data) 111 | { 112 | if (!isset($data['sign'])) return false; 113 | 114 | $sign = $this->makeSign($data); 115 | 116 | return $sign === $data['sign']; 117 | } 118 | 119 | /** 120 | * 生成签名 121 | * @param $data 122 | * @return string 123 | */ 124 | protected function makeSign($data) 125 | { 126 | ksort($data); 127 | $signStr = ''; 128 | foreach ($data as $k => $v) { 129 | if($k != 'sign' && !is_array($v) && !$this->isEmpty($v)){ 130 | $signStr .= $k . '=' . $v . '&'; 131 | } 132 | } 133 | $signStr = trim($signStr, '&') . '&key=' . $this->apiKey; 134 | $sign = md5($signStr); 135 | return strtoupper($sign); 136 | } 137 | 138 | /** 139 | * 校验某字符串或可被转换为字符串的数据,是否为 NULL 或均为空白字符. 140 | * 141 | * @param string|null $value 142 | * 143 | * @return bool 144 | */ 145 | protected function isEmpty($value) 146 | { 147 | return $value === null || $value === ''; 148 | } 149 | 150 | /** 151 | * 产生随机字符串,不长于32位 152 | * @param int $length 153 | * @return 产生的随机字符串 154 | */ 155 | protected function getNonceStr($length = 32) 156 | { 157 | $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; 158 | $str = ""; 159 | for ($i = 0; $i < $length; $i++) { 160 | $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); 161 | } 162 | return $str; 163 | } 164 | 165 | /** 166 | * 转为XML数据 167 | * @param array $data 源数据 168 | * @return string 169 | */ 170 | protected function array2Xml($data) 171 | { 172 | if (!is_array($data)) { 173 | return false; 174 | } 175 | $xml = ''; 176 | foreach ($data as $key => $val) { 177 | $xml .= (is_numeric($val) ? "<{$key}>{$val}" : "<{$key}>"); 178 | } 179 | return $xml . ''; 180 | } 181 | 182 | /** 183 | * 解析XML数据 184 | * @param string $xml 源数据 185 | * @return mixed 186 | */ 187 | protected function xml2array($xml) 188 | { 189 | if (!$xml) { 190 | return false; 191 | } 192 | LIBXML_VERSION < 20900 && libxml_disable_entity_loader(true); 193 | return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA), JSON_UNESCAPED_UNICODE), true); 194 | } 195 | 196 | /** 197 | * 以post方式提交xml到对应的接口url 198 | * @param string $url url 199 | * @param string $xml 需要post的xml数据 200 | * @param bool $useCert 是否需要证书 201 | * @param int $second url执行超时时间 202 | * @return string 203 | */ 204 | protected function curl($url, $xml, $useCert = false, $second = 10) 205 | { 206 | $ch = curl_init(); 207 | $curlVersion = curl_version(); 208 | $ua = "QQPaySDK/1.0 (" . PHP_OS . ") PHP/" . PHP_VERSION . " CURL/" . $curlVersion['version'] . " ". $this->mchId; 209 | 210 | curl_setopt($ch, CURLOPT_TIMEOUT, $second); 211 | curl_setopt($ch, CURLOPT_URL, $url); 212 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 213 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 214 | curl_setopt($ch, CURLOPT_USERAGENT, $ua); 215 | curl_setopt($ch, CURLOPT_HEADER, false); 216 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 217 | if ($useCert) { 218 | if (!file_exists($this->sslCertPath) || !file_exists($this->sslKeyPath)) { 219 | throw new \Exception('商户证书文件不存在'); 220 | } 221 | //使用证书:cert 与 key 分别属于两个.pem文件 222 | curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); 223 | curl_setopt($ch, CURLOPT_SSLCERT, $this->sslCertPath); 224 | curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM'); 225 | curl_setopt($ch, CURLOPT_SSLKEY, $this->sslKeyPath); 226 | } 227 | curl_setopt($ch, CURLOPT_POST, true); 228 | curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 229 | $data = curl_exec($ch); 230 | if (curl_errno($ch) > 0) { 231 | $errmsg = curl_error($ch); 232 | curl_close($ch); 233 | throw new \Exception($errmsg, 0); 234 | } 235 | curl_close($ch); 236 | return $data; 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/PaymentService.php: -------------------------------------------------------------------------------- 1 | publicParams = [ 16 | 'mch_id' => $this->mchId, 17 | 'nonce_str' => $this->getNonceStr(), 18 | ]; 19 | } 20 | 21 | /** 22 | * 统一下单 23 | * @param $params 下单参数 24 | * @return mixed 25 | */ 26 | public function unifiedOrder($params) 27 | { 28 | $url = 'https://qpay.qq.com/cgi-bin/pay/qpay_unified_order.cgi'; 29 | if (empty($params['out_trade_no'])) { 30 | throw new \InvalidArgumentException('缺少统一支付接口必填参数out_trade_no'); 31 | } 32 | if (empty($params['body'])) { 33 | throw new \InvalidArgumentException('缺少统一支付接口必填参数body'); 34 | } 35 | if (empty($params['total_fee'])) { 36 | throw new \InvalidArgumentException('缺少统一支付接口必填参数total_fee'); 37 | } 38 | if (empty($params['trade_type'])) { 39 | throw new \InvalidArgumentException('缺少统一支付接口必填参数trade_type'); 40 | } 41 | return $this->execute($url, $params); 42 | } 43 | 44 | /** 45 | * NATIVE支付 46 | * @param $params 下单参数 47 | * @return mixed {"code_url":"二维码链接","prepay_id":"预支付会话标识"} 48 | */ 49 | public function nativePay($params) 50 | { 51 | $params['trade_type'] = 'NATIVE'; 52 | return $this->unifiedOrder($params); 53 | } 54 | 55 | /** 56 | * JSAPI支付 57 | * @param $params 下单参数 58 | * @return mixed {"tokenId":"预支付会话标识","appInfo":"标记业务及渠道"} 59 | */ 60 | public function jsapiPay($params) 61 | { 62 | $params['trade_type'] = 'JSAPI'; 63 | $result = $this->unifiedOrder($params); 64 | return ['tokenId' => $result['prepay_id'], 'appInfo' => 'appid#' . $this->appId . '|bargainor_id#' . $this->mchId . '|channel#wallet']; 65 | } 66 | 67 | /** 68 | * APP支付 69 | * @param $params 下单参数 70 | * @return mixed APP支付json数据 71 | */ 72 | public function appPay($params) 73 | { 74 | $params['trade_type'] = 'APP'; 75 | $result = $this->unifiedOrder($params); 76 | return $this->getAppParameters($result['prepay_id']); 77 | } 78 | 79 | /** 80 | * 获取APP支付的参数 81 | * @param $prepay_id 预支付交易会话标识 82 | * @return array 83 | */ 84 | private function getAppParameters($prepay_id) 85 | { 86 | $params = [ 87 | 'appId' => $this->appId, 88 | 'nonce' => $this->getNonceStr(), 89 | 'tokenId' => $prepay_id, 90 | 'pubAcc' => '', 91 | 'bargainorId' => $this->mchId, 92 | ]; 93 | $params['sig'] = $this->makeAppSign($params); 94 | $params['sigType'] = 'HMAC-SHA1'; 95 | $params['timeStamp'] = time(); 96 | return $params; 97 | } 98 | 99 | /** 100 | * 生成APP支付签名 101 | * @param $data 102 | * @return string 103 | */ 104 | private function makeAppSign() 105 | { 106 | ksort($data); 107 | $signStr = ''; 108 | foreach ($data as $k => $v) { 109 | $signStr .= $k . '=' . $v . '&'; 110 | } 111 | $signStr = trim($signStr, '&'); 112 | $sign = base64_encode(hash_hmac("sha1", $signStr, $this->appKey.'&', true)); 113 | return $sign; 114 | } 115 | 116 | /** 117 | * 付款码支付 118 | * @param $params 下单参数 119 | * @return mixed {"trade_state":"SUCCESS","total_fee":888,"cash_fee":888,"transaction_id":"QQ钱包订单号","out_trade_no":"商户订单号","time_end":"支付完成时间","trade_state_desc":"交易状态描述","openid":"用户标识"} 120 | */ 121 | public function microPay($params) 122 | { 123 | $url = 'https://qpay.qq.com/cgi-bin/pay/qpay_micro_pay.cgi'; 124 | if (empty($params['out_trade_no'])) { 125 | throw new \InvalidArgumentException('缺少付款码支付接口必填参数out_trade_no'); 126 | } 127 | if (empty($params['body'])) { 128 | throw new \InvalidArgumentException('缺少付款码支付接口必填参数body'); 129 | } 130 | if (empty($params['total_fee'])) { 131 | throw new \InvalidArgumentException('缺少付款码支付接口必填参数total_fee'); 132 | } 133 | if (empty($params['auth_code'])) { 134 | throw new \InvalidArgumentException('缺少付款码支付接口必填参数auth_code'); 135 | } 136 | return $this->execute($url, $params); 137 | } 138 | 139 | /** 140 | * 撤销订单 141 | * @param $out_trade_no 商户订单号 142 | * @return mixed 143 | */ 144 | public function reverse($out_trade_no) 145 | { 146 | $url = 'https://api.qpay.qq.com/cgi-bin/pay/qpay_reverse.cgi'; 147 | $params = [ 148 | 'out_trade_no' => $out_trade_no, 149 | 'op_user_id' => $this->opUserId, 150 | 'op_user_passwd' => md5($this->opUserPwd) 151 | ]; 152 | return $this->execute($url, $params, true); 153 | } 154 | 155 | /** 156 | * 查询订单,QQ钱包订单号、商户订单号至少填一个 157 | * @param $transaction_id QQ钱包订单号 158 | * @param $out_trade_no 商户订单号 159 | * @return mixed 160 | */ 161 | public function orderQuery($transaction_id = null, $out_trade_no = null) 162 | { 163 | $url = 'https://qpay.qq.com/cgi-bin/pay/qpay_order_query.cgi'; 164 | $params = []; 165 | if ($transaction_id) { 166 | $params['transaction_id'] = $transaction_id; 167 | } elseif ($out_trade_no) { 168 | $params['out_trade_no'] = $out_trade_no; 169 | } 170 | return $this->execute($url, $params); 171 | } 172 | 173 | /** 174 | * 判断订单是否已完成 175 | * @param $transaction_id QQ钱包订单号 176 | * @return bool 177 | */ 178 | public function orderQueryResult($transaction_id) 179 | { 180 | try { 181 | $data = $this->orderQuery($transaction_id); 182 | return $data['trade_state'] == 'SUCCESS' || $data['trade_state'] == 'REFUND'; 183 | } catch (\Exception $e) { 184 | return false; 185 | } 186 | } 187 | 188 | /** 189 | * 关闭订单 190 | * @param $out_trade_no 商户订单号 191 | * @return mixed 192 | */ 193 | public function closeOrder($out_trade_no) 194 | { 195 | $url = 'https://qpay.qq.com/cgi-bin/pay/qpay_close_order.cgi'; 196 | $params = [ 197 | 'out_trade_no' => $out_trade_no 198 | ]; 199 | return $this->execute($url, $params); 200 | } 201 | 202 | /** 203 | * 申请退款 204 | * @param $params 205 | * @return mixed 206 | */ 207 | public function refund($params) 208 | { 209 | $url = 'https://api.qpay.qq.com/cgi-bin/pay/qpay_refund.cgi'; 210 | if (empty($params['transaction_id']) && empty($params['out_trade_no'])) { 211 | throw new \InvalidArgumentException('out_trade_no、transaction_id至少填一个'); 212 | } 213 | if (empty($params['out_refund_no'])) { 214 | throw new \InvalidArgumentException('out_refund_no参数不能为空'); 215 | } 216 | if (empty($params['refund_fee'])) { 217 | throw new \InvalidArgumentException('refund_fee参数不能为空'); 218 | } 219 | $params += [ 220 | 'op_user_id' => $this->opUserId, 221 | 'op_user_passwd' => md5($this->opUserPwd) 222 | ]; 223 | return $this->execute($url, $params, true); 224 | } 225 | 226 | /** 227 | * 查询退款 228 | * @param $params 229 | * @return mixed 230 | */ 231 | public function refundQuery($params) 232 | { 233 | $url = 'https://qpay.qq.com/cgi-bin/pay/qpay_refund_query.cgi'; 234 | if (empty($params['transaction_id']) && empty($params['out_trade_no']) && empty($params['out_refund_no']) && empty($params['refund_id'])) { 235 | throw new \InvalidArgumentException('退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个'); 236 | } 237 | return $this->execute($url, $params); 238 | } 239 | 240 | /** 241 | * 下载对账单 242 | * @param $params 243 | * @return mixed 244 | */ 245 | public function downloadBill($params) 246 | { 247 | $url = 'https://qpay.qq.com/cgi-bin/sp_download/qpay_mch_statement_down.cgi'; 248 | if (empty($params['bill_date'])) { 249 | throw new \InvalidArgumentException('bill_date参数不能为空'); 250 | } 251 | if (empty($params['bill_type'])) { 252 | throw new \InvalidArgumentException('bill_type参数不能为空'); 253 | } 254 | return $this->download($url, $params); 255 | } 256 | 257 | /** 258 | * 下载资金账单 259 | * @param $params 260 | * @return mixed 261 | */ 262 | public function downloadFundFlow($params) 263 | { 264 | $url = 'https://qpay.qq.com/cgi-bin/sp_download/qpay_mch_acc_roll.cgi'; 265 | if (empty($params['bill_date'])) { 266 | throw new \InvalidArgumentException('bill_date参数不能为空'); 267 | } 268 | if (empty($params['acc_type'])) { 269 | throw new \InvalidArgumentException('acc_type参数不能为空'); 270 | } 271 | return $this->download($url, $params); 272 | } 273 | 274 | /** 275 | * 支付结果通知 276 | * @return bool|mixed 277 | */ 278 | public function notify() 279 | { 280 | $xml = file_get_contents("php://input"); 281 | if (empty($xml)) { 282 | throw new \Exception('NO_DATA'); 283 | } 284 | $result = $this->xml2array($xml); 285 | if (!$result) { 286 | throw new \Exception('XML_ERROR'); 287 | } 288 | if (!$this->checkSign($result)) { 289 | throw new \Exception('签名校验失败'); 290 | } 291 | if (!isset($result['transaction_id'])) { 292 | throw new \Exception('缺少订单号参数'); 293 | } 294 | if (!$this->orderQueryResult($result['transaction_id'])) { 295 | throw new \Exception('订单未完成'); 296 | } 297 | return $result; 298 | } 299 | 300 | /** 301 | * 回复通知 302 | * @param $isSuccess 是否成功 303 | * @param $msg 失败原因 304 | */ 305 | public function replyNotify($isSuccess = true, $msg = '') 306 | { 307 | $data = []; 308 | if ($isSuccess) { 309 | $data['return_code'] = 'SUCCESS'; 310 | } else { 311 | $data['return_code'] = 'FAIL'; 312 | $data['return_msg'] = $msg; 313 | } 314 | $xml = $this->array2Xml($data); 315 | echo $xml; 316 | } 317 | } 318 | --------------------------------------------------------------------------------