【转载】http://www.dodobook.net/php/1110
相关的文档可以参阅。
这个接口文档还是比较完备的,相信很多技术人员稍加摸索,就能实现了。
目录结构为
Upmp----upmp_config.php----upmp_core.php----UpmpService.php----notify_url.php
直接上代码:upmp_config.php
upmp_core.php
value), data for post** return param:* mixed:* false: error happened* string: curl return data**/function post($url, $content = null){ if (function_exists("curl_init")) { $curl = curl_init(); if (is_array($content)) { $data = http_build_query($content); } curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $content); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_TIMEOUT, 60); //seconds // https verify curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, upmp_config::VERIFY_HTTPS_CERT); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, upmp_config::VERIFY_HTTPS_CERT); $ret_data = curl_exec($curl); if (curl_errno($curl)) { printf("curl call error(%s): %s\n", curl_errno($curl), curl_error($curl)); curl_close($curl); return false; } else { curl_close($curl); return $ret_data; } } else { throw new Exception("[PHP] curl module is required"); }} ?>
UpmpService.php
修改成分配给你的参数。至此基本上这个包已经完整了。上面还有一些写文件的操作。用于填写报文。
调用的方法和成功的回调响应的接口
//会员充值到账户余额--使用银联--生成订单(简易版本)public function actionChargeByUpmp() { $request = Yii::app()->request; Yii::import('application.extensions.Upmp.*'); //引入Upmp $member_id = $request->getParam('mid'); //会员ID $number = $request->getParam('number'); //会员充值的金额 //加入对会员的安全状态各方面的检测和处理....... $transaction = Yii::app()->db->beginTransaction(); //使用事务能保证尽可能少的产生脏数据 try{ //先本地生成订单,生成订单ID $billList = new MemberBillList; $billList->member_id = $member_id; $billList->number = $number; //充值金额 $billList->in_out = '1'; //会员支出 $billList->in_out_type = '2'; //会员个人余额充值 $billList->add_time = time(); $billList->status = '2'; //账单状态未完成 $billList->remark = '会员银联充值'; //账单状态未完成 $billList->isNewRecord = true; if(!$billList->save()){ throw new Exception('生成账单记录失败,'.$this->getModelFirstError($billList), 11); } //银联的这个账单号的长度是(8-40),我在文档上只看到了不大于40,没看到最小8.(后来询问才知道) $orderNumber = date('Ymd').'MCHA'.$billList->id; //本地的账单ID,经过组装后用于提交给银联 //去服务器上生成流水号 $notify_url = 'http://pay.dodobook.net/api/upmp/successByChargeUpmp'; //通知的地址(成功之后每隔几分钟向该地址发送成功的通知) $bankRt = $this->actionCreateBill($orderNumber,$number,$notify_url); //根据提交的信息去请求并生成流水号 if($bankRt['respCode'] != '00'){ //判断返回的状态 throw new Exception('银行接口返回失败,'.$bankRt['respMsg'], 10); } if(!$bankRt['tn']){ //判断流水号 throw new Exception('银行接口流水号未返回', 11); } //更新刚才的账单的信息,增加刚才账单和流水号等的对应(完整记录) $bank_order_id = $bankRt['tn']; $newBillList = MemberBillList::model()->findByPk($billList->id); $newBillList->bank_tn_id = $bank_order_id; //银行流水号 $newBillList->bank_order_id = $orderNumber; //银行系统记录的账单号 if(!$newBillList->save()){ throw new Exception('更新流水号失败', 12); } $transaction->commit(); $json['id'] = date("YmdHis").'_'.$billList->id; //账单的ID $json['bank_order_id'] = $bank_order_id; //银行流水号 // $this->_end_api('0','账单记录生成成功,账单状态为未完成.',$json); }catch(Exception $e){ $transaction->rollback(); // $this->_end_api($e->getCode(),'生成账单记录失败',$e->getMessage()); }}
//会员充值到账户余额--使用银联--回调方法public function actionSuccessByChargeUpmp() { $request = Yii::app()->request; Yii::import('application.extensions.Upmp.*'); //引入Upmp 测试的时候把返回过来的回调的信息先写文本日志记录 $str = ''; foreach ($_POST as $k => $v) { $str .= $k .'==='.$v.'
'; } file_put_contents('charge_upmp.txt', '交易时间'.date('Y-m-d H:i:s').$str,FILE_APPEND); if($_POST['transStatus'] == '00'){ echo 'success'; } exit(); /* //正式环境下的账单的处理 if (UpmpService::verifySignature($_POST)){// 服务器签名验证成功 //请在这里加上商户的业务逻辑程序代码 //获取通知返回参数,可参考接口文档中通知参数列表(以下仅供参考) $transStatus = $_POST['transStatus'];// 交易状态 if ("" != $transStatus && "00"==$transStatus){ // 交易处理成功 $qn = $_POST['qn']; //查询流水号 $orderNumber = $_POST['orderNumber']; //商户订单号 $total_fee = $_POST['settleAmount'] / 100; //清算金额 $billList = MemberBillList::model()->find("bank_order_id = '{$orderNumber}'"); $bill_list_id = $billList->id; //账单记录ID $memBillList = MemberBillList::model()->findByPk($bill_list_id); if($memBillList->status == '1'){ //如果已处理过 echo 'success'; $this->_end_api('0','Sucess','Sucess'); //处理成功 } $transaction = Yii::app()->db->beginTransaction(); try{ //bill_list_id //total_fee 银联支付的金额 //更新会员账单记录表 member_bill_list $memBillList = MemberBillList::model()->findByPk($bill_list_id); $member_id = $memBillList->member_id; //消费的会员ID $memBill = MemberBill::model()->find("member_id = '{$member_id}'"); $memBillList->status = '1'; //更新状态值为已完成 if(!$memBillList->save()){ $this->_end_api('1','更改会员账单记录表状态失败',$this->getModelFirstError($memBillList)); } //更新会员账单--............. $transaction->commit(); echo 'success'; //成功之后告诉银联,避免银联不断的发送信息过来,会尝试24小时,5次 $this->_end_api('0','success','success'); //处理成功 }catch(Exception $e){ $transaction->rollback(); echo "fail"; $this->_end_api('12','银联支付回调处理失败',''); } }else { file_put_contents('charge_upmp_err.txt', '失败:交易时间'.date('Y-m-d H:i:s').$str,FILE_APPEND); } echo "success"; }else {// 服务器签名验证失败 echo "fail"; $this->_end_api('1','交易失败',''); } */}
//生成账单请求的公共方法public function actionCreateBill($orderNumber='',$orderAmount='',$notify_url) { header('Content-Type:text/html;charset=utf-8'); Yii::import('application.extensions.Upmp.*'); //引入Upmp //需要填入的部分 $req['version'] = upmp_config::$version; // 版本号 $req['charset'] = upmp_config::$charset; // 字符编码 $req['transType'] = "01"; // 交易类型 $req['merId'] = upmp_config::$mer_id; // 商户代码 $req['backEndUrl'] = $notify_url; // 通知URL $req['frontEndUrl'] = $notify_url; // 前台通知URL(可选) $req['orderDescription'] = "订单描述"; // 订单描述(可选) $req['orderTime'] = date("YmdHis"); // 交易开始日期时间yyyyMMddHHmmss $req['orderTimeout'] = ""; // 订单超时时间yyyyMMddHHmmss(可选) $req['orderNumber'] = $orderNumber; //订单号(商户根据自己需要生成订单号) $req['orderAmount'] = intval($orderAmount * 100); // 订单金额(人民币单位为分) $req['orderCurrency'] = "156"; // 交易币种(可选)--人民币 $req['reqReserved'] = "透传信息"; // 请求方保留域(可选,用于透传商户信息) // 保留域填充方法 $merReserved['test'] = "test"; $req['merReserved'] = UpmpService::buildReserved($merReserved); // 商户保留域(可选) $resp = array (); $validResp = UpmpService::trade($req, $resp); // 商户的业务逻辑 if ($validResp){ // 服务器应答签名验证成功 return $resp; }else { // 服务器应答签名验证失败 return $resp; }}
备注说明:
1.可以完全按照银联提供的接口和example来使用,有时候会报错,大多数情况下是目录结构和命名规范导致。自己改进。2.测试报告的报文,都是需要状态为成功的才能通过。即测试的订单推送等都是需要完成的。3.用户发出的请求报文,可以通过写文件操作记录。收到的应答报文也可以写文件记录。根据他们的示例。4.文档可能有进一步的改进,请到官网去查询相关的资料。此处只是个人的一个demo的记录。5.欢迎大家交流和指点。