thinkphp之支付宝支付接口;
下面是支付下单接口
<?php namespace App\Controller; use Common\Controller\AppbaseController; Vendor('Alipay.AopClient'); //Vendor('Wxpay.JsApiPay'); class PayController extends AppbaseController{ function __controller(){ parent::__controller(); } public function aliPay(){ //获取POST信息 $s = rand(100000,999999); $data['dsn'] = "KX".date("YmdHis").$s.I('post.uid'); $data['uid'] = I("post.uid"); $data['addtime']=date("Y-m-d H:i:s",time()); $data['status']=0; $data['num']=I('post.num'); $data['yunfei']=I('post.yunfei'); $data['pstime']=I('post.pstime'); $data['yhqid']=$_POST['yhqid']; //新增优惠金额 $data['yhqnum']=$_POST['yhqnum']; //将收货地址改为收货地址id $data['addrid']=I('post.addrid'); $data['pstype']=I('post.pstype'); $data['acount']=I('post.acount'); // $data['paytype']=I('post.paytype');//新增字段 0 微信 //修改字段paytype为字符串类型 $data['paytype']='支付宝'; $data['gid']=I('post.gid'); $data['count']=I('post.count'); // $data['shouhuoren']=I('post.shouhuoren'); $price=$data['acount']; // $price=1; $st = json_encode($data); file_put_contents('1.txt',$st); $aop = new \AopClient; $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do"; $aop->appId = ""; $aop->rsaPrivateKey = 'key' ; $aop->format = "json"; $aop->charset = "UTF-8"; $aop->signType = "RSA2"; $aop->alipayrsaPublicKey = '';//对应填写 //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay $request = new \AlipayTradeAppPayRequest(); //SDK已经封装掉了公共参数,这里只需要传入业务参数 //********注意*************************下面除了body描述不是必填,其他必须有,否则失败 $bizcontent = json_encode(array( 'body'=>'商品下单', 'subject' => 'App',//支付的标题, 'out_trade_no' => $data['dsn'],//支付宝订单号必须是唯一的,不能在支付宝再次使用,必须重新生成,哪怕是同一个订单,不能重复。否则二次支付时候会失败,订单号可以在自己订单那里保持一致,但支付宝那里必须要唯一,具体处理自己操作! 'timeout_express' => '30m',//過期時間(分钟) 'total_amount' => $price,//金額最好能要保留小数点后两位数 'product_code' => 'QUICK_MSECURITY_PAY' )); $request->setNotifyUrl("http://a.ikuaixiang.cn/index.php/app/Alipay/NotifyProcess");//你在应用那里设置的异步回调地址 $request->setBizContent($bizcontent); //这里和普通的接口调用不同,使用的是sdkExecute $response = $aop->sdkExecute($request); if(!empty($response)){ // $data['nonce_str'] = $order['nonce_str']; $data['out_trade_no'] = $data['dsn']; //添加操作 $orderInfo = M('shop_order')->add($data); if($data['yhqid']!=null){ M('shop_user_yhq')->where("uid={$data['uid']} and yhqid={$data['yhqid']}")->save(array('ystatus'=>1)); } //执行判断操作 $arr = explode(';',$data['gid']); $c = explode(';',$data['count']); foreach ($arr as $key => $value){ $arr1['count']=$c[$key]; $arr1['gid']=$value; $arr1['oid']=$orderInfo; M('shop_order_goods')->add($arr1); } } //htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义,实际打印到日志以及http传输不会有这个问题 $a['data']= $response;//就是orderString 可以直接给客户端请求,无需再做处理。这里就是方便打印给你看,具体你直接可以在方法那里return出去,不用加htmlspecialchars,或者响应给app端让他拿着这串东西调起支付宝支付 $this->ajaxReturn($a); } }
下面是支付回调接口 + 对接下单 打印机 易连云
<?php namespace App\Controller; use Think\Controller; //Vendor('Wxpay.WxPayApi'); class AlipayController extends Controller{ /** * * 回调方法入口,子类可重写该方法 * 注意: * 1、微信回调超时时间为2s,建议用户使用异步处理流程,确认成功之后立刻回复微信服务器 * 2、微信服务器在调用失败或者接到回包为非确认包的时候,会发起重试,需确保你的回调是可以重入 * @param array $data 回调解释出的参数 * @param string $msg 如果回调处理失败,可以将错误信息输出到该方法 * @return true回调出来完成不需要继续回调,false回调处理未完成需要继续回调 */ public function NotifyProcess() { if($_POST['trade_status']=='TRADE_SUCCESS'){ $aa = json_encode($_POST); $aa .=time(); file_put_contents('支付宝.txt',$aa); $pay_no = $_POST['out_trade_no']; $pay_no1 = $_POST['nonce_str']; $order['out_trade_no'] = $_POST["out_trade_no"];//订单号 $order['transaction_id'] = $_POST["trade_no"]; $order['paytime'] = $_POST['gmt_payment']; $order['status'] = 1; $data1['status']=1; $data1['aacount']=$_POST['total_amount']; $a = D("shop_order")->where("dsn like '".$pay_no."'")->find(); if($a['status']==0){ $this->startPrint($pay_no); } $result = D("pay_log")->add($order); $result1 = D("shop_order")->where("dsn like '".$pay_no."'")->save($data1); $result2 = D("shop_order")->where("dsn like '".$pay_no."'")->find(); $list = M('shop_order_goods')->where("oid={$result2['id']}")->select(); foreach ($list as $k => $v){ $row = M('shop_goods')->where("id={$v['gid']}")->find(); $arr['stock'] = $row['stock']-$v['count']; M('shop_goods')->where("id={$v['gid']}")->save($arr); } } } public function startPrint($pay_no){ header("Content-type: text/html;charset=utf-8"); $list = D("shop_order")->where("dsn like '".$pay_no."'")->find(); if(!empty($list)) { $goodList = M('shop_order_goods as og') ->join("cmf_shop_goods as g on og.gid = g.id") ->field("og.*,g.name,g.price,g.photo,g.limit_price") ->where("og.oid={$list['id']}") ->select(); $userinfo = M('shop_users')->where("id = {$list['uid']}")->find(); $person = M('shop_address')->where("id = {$list['addrid']}")->find(); if($list['pstype'] == '自取'){ $str = "手机号:{$userinfo['username']}"; $str .= "\r"; $str .= "到店自取"; $str .= "\r"; }else{ $str = "订单编号:{$list['dsn']}"; $str .= "\r"; $str .= "收货人:{$person['name']}"; $str .= "\r"; $str .= "手机号:{$person['phone']}"; $str .= "\r"; $str .= "收货地址:{$person['address']}"; $str .= "\r"; } foreach ($goodList as $v) { $str .= "商品名称:\r"; $str .= "{$v['name']}\r"; $str .= "\t {$v['price']} * {$v['count']} 件\r"; } // $str .="商品名称:\r"; // $str .="美的智能家用多功能双胆电压力锅高压锅饭煲正品WCS5025 5L小家电 \r"; // $str .="\t * 3 件\r"; $str .= "总金额:{$list['num']}元\r"; $str .= "支付金额:{$list['num']}元\r"; // var_dump($list);exit; $time = date('Y-m-d H:i:s',time()); $str .="打印时间:{$time}"; $content = $str; $apiKey = "2c2a9ce6e275de56cfa0f9cffb0f4da862017ff7"; $msign = 'm6bv724uszc7'; //打印 $this->action_print(12100, '4004531638', $content, $apiKey, $msign); } } /** * 打印接口 * @param int $partner 用户ID * @param string $machine_code 打印机终端号 * @param string $content 打印内容 * @param string $apiKey API密钥 * @param string $msign 打印机密钥 */ public function action_print($partner,$machine_code,$content,$apiKey,$msign) { $param = array( "partner"=>$partner, 'machine_code'=>$machine_code, 'time'=>time(), ); //获取签名 $param['sign'] = $this->generateSign($param,$apiKey,$msign); $param['content'] = $content; $str = $this->getStr($param); $this->sendCmd('http://open.10ss.net:8888',$str); } /** * 发起请求 * @param string $url 请求地址 * @param string $data 请求数据包 * @return string 请求返回数据 */ public function sendCmd($url,$data) { $curl = curl_init(); // 启动一个CURL会话 curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检测 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查SSL加密算法是否存在 curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:')); //解决数据包大不能提交 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转 curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求 curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包 curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循 curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回 $tmpInfo = curl_exec($curl); // 执行操作 if (curl_errno($curl)) { echo 'Errno'.curl_error($curl); } curl_close($curl); // 关键CURL会话 return $tmpInfo; // 返回数据 } /** * 生成字符串参数 * @param array $param 参数 * @return string 参数字符串 */ public function getStr($param) { $str = ''; foreach ($param as $key => $value) { $str=$str.$key.'='.$value.'&'; } $str = rtrim($str,'&'); return $str; } /** * 生成签名sign * @param array $params 参数 * @param string $apiKey API密钥 * @param string $msign 打印机密钥 * @return string sign */ public function generateSign($params, $apiKey,$msign) { //所有请求参数按照字母先后顺序排 ksort($params); //定义字符串开始所包括的字符串 $stringToBeSigned = $apiKey; //把所有参数名和参数值串在一起 foreach ($params as $k => $v) { $stringToBeSigned .= urldecode($k.$v); } unset($k, $v); //定义字符串结尾所包括的字符串 $stringToBeSigned .= $msign; //使用MD5进行加密,再转化成大写 return strtoupper(md5($stringToBeSigned)); } } ?>