PHP后台微信支付和支付宝支付开发


Posted in PHP onApril 28, 2017

关于支付的流程之类的就不做解释,大家可以自行搜索!

微信支付

项目前提:本人用的是tp框架,PHP语言
下载到微信平台提供的微信支付接口文件,放在了tp第三方类库vendor,命名为WxpayAPI

PHP后台微信支付和支付宝支付开发

WxpayAPI/lib/WxPay.Api.php 接口访问类;
WxpayAPI/lib/WxPay.Config.php 配置账号信息;
WxpayAPI/lib/WxPay.Data.php 数据对象基础类;
WxpayAPI/lib/WxPay.Exception.php 微信支付API异常类;
WxpayAPI/lib/WxPay.Notify.php 回调基础类
WxpayAPI/example/WxPay.JsApiPay.php JSAPI支付实现类

PHP后台微信支付和支付宝支付开发

1.对源码进行了部分修改

(1)WxPay.Api.php 里注释掉
        //require_once "WxPay.Exception.php";
        //require_once "WxPay.Config.php";
        //require_once "WxPay.Data.php"; 

(2)WxPay.Config.php里
        需要根据商户信息对APPID , MCHID ,KEY , APPSECRET 进行配置。 

(3)WxPay.Data.php 里注释掉
        //require_once "WxPay.Config.php";
        //require_once "WxPay.Exception.php"; 

(4)WxPay.JsApiPay.php 里注释掉
        //require_once "../lib/WxPay.Api.php";

配置好这些,接下来就是我们的重点部分了。

2.在订单控制器GoodsController.class.php有订单函数sure()和回调信息函数 Callback_url()

/**
* 提交订单函数
*/
public function sure() {
  $o_model = D("Wine/Orders");
 
  if (IS_AJAX) {
   $data = I("post.");
   if ($o_model->create($data)) {
 
    if (!sp_check_verify_code()) {
     $this->error("验证码错误!");
    }
 
    #生成随机订单号
    $order_code = 'O' . date('YmdHis') . $o_model->get_order_code(4);
    while ($o_model->findone(array("order_code" => $order_code))) {
     $order_code = 'O' . date('YmdHis') . $o_model->get_order_code(4);
    }
    $data['order_code'] = $order_code;
    $addr[0] = $_POST['prov'];
    $addr[1] = $_POST['city'];
    $addr[2] = $_POST['dist'];
    $addr[3] = $_POST['area'];
    $data['area'] = serialize($addr);
    $data['create_time'] = time();
    $data['update_time'] = time();
 
    if ($data['pay_id'] == 1) {
     $data['order_status'] = 11; //已付款
     $data['status'] = '1';
    } else {
     $data['order_status'] = 10; //待付款
     $data['status'] = '1';
    }
    //函数调用 返回信息
    $this->Callback_url($data);
   } else {
    $this->error($o_model->getError());
   }
  } else {
   $this->error($o_model->getError());
  }
 }
 
 /**
 * 回调信息函数
 * @param type $data
 */
 public function Callback_url($data) {
  $o_model = D("Wine/Orders");
  $add_id = $o_model->add($data);
  if (!$add_id) {
   $this->error("订单提交失败,请稍后重试!");
  }
  if ('4' == $data['pay_id']) {
   if ('4' == $data['pay_id']) {
   //微信支付
   $msg = '正在为您跳转到微信支付页面,请等待……';
   $url = "/index.php/wine/wxpay/index/?o_id=$add_id";
  }
  $this->success("订单提交成功!" . $msg, $url);
 }

3.[重点!!!] WxpayController .class.php微信支付控制器,实现对微信接口的调用

<?php
 
/**
 * 微信支付接口调用
 */
 
namespace Wine\Controller;
 
use Common\Controller\HomebaseController;
 
class WxpayController extends HomebaseController {
 
 public function _initialize() {
  parent::_initialize();
 
  Vendor("WxpayAPI/example/log");//订单数据写入日志
  //注: 引入第三方类库中的微信接口文件,对于文件名含有.的,皆用#代替连接才能引入,后缀名不写。
  Vendor("WxpayAPI/example/WxPay#JsApiPay");
  Vendor("WxpayAPI/lib/WxPay#Config");
  Vendor("WxpayAPI/lib/WxPay#Data");
  Vendor("WxpayAPI/lib/WxPay#Exception");
  Vendor("WxpayAPI/lib/WxPay#Notify");
  Vendor("WxpayAPI/lib/WxPay#Api");
  //初始化日志
  $logHandler = new \CLogFileHandler("/projects/wine.huishuocs.com/data/pay_log/" . date('Y-m-d') . '.log');
  $log = \Log::Init($logHandler, 15);
  $this->model = D("Wine/Orders");
  $this->url = MODULE_NAME . '/' . CONTROLLER_NAME . '/index';
 }
 
 /**
  * 显示支付页面
  *
  */
 public function index() {
  // 判断当前订单是否被支付
  $orderid = I("get.o_id", 0, "intval");
  $orderid || $this->error("非法操作!");
  $this->assign('orderid',$orderid);
  $info = $this->model->findone(array("a.id" => $orderid, 'a.status' => array('neq', '-1')));
  $info || $this->error("暂未查询到该订单!");
  //10代表订单待支付的状态
  if ($info['order_status'] != 10) {
   $this->error("订单已支付!");
  }
  //①、获取用户openid
  $tools = new \JsApiPay();
  $openId = $tools->GetOpenid(); #无法使用
  //初始化日志
  \Log::INFO('订单' . var_export($info, true));
  $out_trade_no = \WxPayConfig::MCHID . date("YmdHis");
  $this->model->where(array("id" => $orderid))->save(array('out_trade_no' => $out_trade_no));
//  $openId ="123"; #无法使用
  //②、统一下单
  $input = new \WxPayUnifiedOrder();
  $input->SetBody($info['mode_name']);
  $input->SetAttach($orderid);
  $input->SetOut_trade_no($out_trade_no);
//  $input->SetTotal_fee($orderArr['total_price']*100);实际支付价格
  $input->SetTotal_fee($info['pay_price']*100); //测试时请将支付价格改为0.01,土豪请避开此注释
  $this->assign('pay_price',$info['pay_price']);
  $input->SetTime_start(date("YmdHis"));
  $input->SetTime_expire(date("YmdHis", time() + 600));
//  $input->SetGoods_tag("test");# 优惠券
  $input->SetNotify_url('http://' . $_SERVER['HTTP_HOST'] . "/index.php/Wine/Wxpay/callback"); //回调地址
  $input->SetTrade_type("JSAPI");
  $input->SetOpenid($openId);
  $order = \WxPayApi::unifiedOrder($input);
//  echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>';
//  $this->printf_info($order);//打印参数
    $this->assign('o_id',$orderid);
  $this->assign('jsApiParameters', $tools->GetJsApiParameters($order));
  //获取共享收货地址js函数参数
//  $this->assign('editAddress', $tools->GetEditAddressParameters());
  $this->display('wxpay');
  exit;
 }
 
 /**
  * 打印输出数组信息
  * @param type $data
  */
 public function printf_info($data) {
  foreach ($data as $key => $value) {
   echo "<font color='#00ff55;'>$key</font> : $value <br/>";
  }
 }
 
 /* 支付成功回调函数 */
 
 public function callback() {
  /* 返回给微信服务器 */
//  $mes = array(
//   'return_code' => 'SUCCESS',
//   'return_msg' => 'OK'
//  );
//  $this->ajaxReturn($mes, 'XML');
  $logHandler = new \CLogFileHandler("/projects/wine.huishuocs.com/data/pay_log/" . date('Y-m-d') . '.log');
  $log = \Log::Init($logHandler, 15);
  //$streamData = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
 
  $streamData = file_get_contents('php://input');
  if ($streamData != '') {
   $arr = $this->xmlToArray($streamData);
   \Log::INFO('支付' . var_export($arr, true));
  } else {
   $ret = false;
  }
  // 回调值
  if (!empty($arr)) {
   # 数据
    \Log::INFO('数据1' . var_export($arr, true));
   #修改订单状态
   $out_trade_no = $arr['out_trade_no'];
   $newArr = array('order_status' => 11,'status'=>1);
   $this->model->where(array("out_trade_no" => $out_trade_no))->save($newArr);
   $info = $this->model->findone(array("a.out_trade_no" => $out_trade_no, 'a.status' => array('neq', '-1')));
   $sql = $this->model->getLastSql();
   \Log::INFO('数据2' . $sql);
   #添加支付记录pay
   $pay = array(
    'payment_code' => 'wxpay',
    'trade_no'=>$info['order_code'],
    'out_trade_no'=>$out_trade_no,
    'order_id'=>$info['id'],
    'create_time'=>time()
   );
   M('payment_record')->add($pay);   
  }
 
  /* 返回给微信服务器 */
  $mes = array(
   'return_code' => 'SUCCESS',
   'return_msg' => 'OK'
  );
  $this->ajaxReturn($mes, 'XML');
 }
 
 //将XML转为array
 public function xmlToArray($xml) {
  //禁止引用外部xml实体
  libxml_disable_entity_loader(true);
  $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  return $values;
 }
 
}
 
?>

4.前端微信支付页面wxpay.html

<html>
 <head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <link href="__TMPL__Public/css/weui.css" rel="external nofollow" type="text/css" rel="stylesheet"/>
  <title>微信订单支付</title>
  <script type="text/javascript">
   //调用微信JS api 支付
   function jsApiCall()
   {
    WeixinJSBridge.invoke(
      'getBrandWCPayRequest',
      <php> echo $jsApiParameters; </php>,
      function(res) {
       WeixinJSBridge.log(res.err_msg);
       if (res.err_msg == "get_brand_wcpay_request:ok") {
//       alert(res.err_code + res.err_desc + res.err_msg);
        // 成功跳转页面
        window.location.href = '{:U("Orders/pay_ok",array("o_id"=>$o_id))}';
       } else {
        // 统一跳转
       }
 
      }
    );
   }
 
   function callpay()
   {
    if (typeof WeixinJSBridge == "undefined") {
     if (document.addEventListener) {
      document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
     } else if (document.attachEvent) {
      document.attachEvent('WeixinJSBridgeReady', jsApiCall);
      document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
     }
    } else {
     jsApiCall();
    }
   }
  </script>
 </head>
 <body>
  <br/>
  <div class="container" id="container"><div class="msg">
    <div class="weui_msg">
     <div class="weui_icon_area"><i class="weui_icon_success weui_icon_msg"></i></div>
     <div class="weui_text_area">
      <h2 class="weui_msg_title">订单已生成</h2>
      <p class="weui_msg_desc">该笔订单支付金额为:<php> echo $pay_price;</php></p>
     </div>
     <div class="weui_opr_area">
      <p class="weui_btn_area">
       <a href="javascript:;" rel="external nofollow" class="weui_btn weui_btn_primary" onclick="callpay()">立即支付</a>
       <!--<a href="{:U('Order/pay_ok',array('o_id'=>$_GET['o_id']))}" rel="external nofollow" class="weui_btn weui_btn_default">取消支付</a>-->
      </p>
     </div>
     <!--     <div class="weui_extra_area">
           <a href="/wap/order/order_det/<?php echo $order['id']?>.html" rel="external nofollow" >查看详情</a>
          </div>-->
    </div>
   </div>
  </div>
 </body>
</html>

5.支付成功跳转到OrderController.class.php ,订单支付完成

/**
* 支付页面
*/
 public function pay_ok() {
  $o_id = I("get.o_id", 0, "intval");
  $info = $this->model->findone(array("a.id" => $o_id, 'a.status' => array('neq', '-1')));
  if (empty($info)) {
   # 获取最新可用的商品编号
   $goods = D('Goods')->where(array('status' => '1'))->order('id desc')->find();
   $this->error("该订单不存在,请重新正确进入", U('Goods/sale', array('id' => $goods['id'])));
  }
  $this->assign('imgurl', "/wine/img/ok.png");
  $this->assign('tips', "订购成功");
  if ('4' == $info['pay_id']) {
   //微信支付成功
   $this->assign($info);
   $this->display();
  } else {
   $this->assign($info);
   $this->assign('tips', "订购失败");
   $this->assign('imgurl', "/wine/img/nook.png");
   $this->display();
  }
 }

到此,微信支付流程结束。

支付宝支付

话不多说,直接上代码!

注:
1.支付文件是从支付宝上直接拿过来的
2.依旧是TP框架

【1】将文件放入第三方类库:

(1)
  * 类名:AlipayConfig.php 
  * 功能:支付宝配置文件 
  * 修改配置:  

// MD5密钥,安全检验码,由数字和字母组成的32位字符串,查看地址:https://b.alipay.com/order/pidAndKey.htm
  $alipay_config['key'] = '';//(**从支付宝中获取**)
 
 // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
  $alipay_config['notify_url'] = 'http://' . $_SERVER['SERVER_NAME'] . '/index.php/Wine/PayCallback/alipay_notify';
 
 // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
  $alipay_config['return_url'] = 'http://' . $_SERVER['SERVER_NAME'] . '/index.php?g=Wine&m=Orders&a=alipay_return';

 (2)
 * 类名:AlipayNotify.php
 * 功能:支付宝通知处理类 
 * 详细:处理支付宝各接口通知返回 

(3)
 * 类名:Alipay.php
 * 功能:手机网站支付接口接入页 
 * 详细:处理支付宝各接口通知返回

class Alipay {
 
 public function submit($params) {
//建立请求
  $alipaySubmit = new AlipaySubmit($alipay_config);
  $html_text = $alipaySubmit->buildRequestForm($parameter, "get", "确认");
  return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html>
  <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   <title>支付宝支付</title>
  </head>' . $html_text . '
  </body>
  </html>';
 }
}

(4)
 * 类名:notify_url.php
 * 功能:支付宝服务器异步通知页面
 * 详细:处理支付宝各接口通知返回

PHP后台微信支付和支付宝支付开发

【2】支付业务逻辑
(1)GoodsController.class.php 下提交订单 ajax_sure()

public function ajax_sure() {<br>
 $data['order_code'] = $order_code;
 $addr[0] = $_POST['prov'];
 $addr[1] = $_POST['city'];
 $addr[2] = $_POST['dist'];
 $addr[3] = $_POST['area'];
 $data['area'] = serialize($addr);
 $data['create_time'] = time();
 $data['update_time'] = time();
 $data['ip'] = $_SERVER['REMOTE_ADDR'];
 if ($data['pay_id'] == 1) {
   $data['order_status'] = 11; //已付款
   $data['status'] = '1';
 } else {
   $data['order_status'] = 10; //待付款
   $data['status'] = '1';
 }
 //函数调用 返回信息
 $this->Callback_url($data);
}
/**
  * 回调信息函数
  * @param type $data
  */
 public function Callback_url($data) {
  $o_model = D("Wine/Orders");
  $add_id = $o_model->add($data);
  if (!$add_id) {
   $this->error("订单提交失败,请稍后重试!");
  }<br>
  if ('3' == $data['pay_id']) {
   //支付宝支付
   $msg = '正在为您跳转到支付宝支付页面,请等待……';
   $url = U("Pay/doalipay", array('o_id' => $add_id));
  }
  $this->success("订单提交成功!" . $msg, $url);
 }

 (2)PayController.class.php 下

/**
  * 支付页面
  */
 public function doalipay() {
  $o_id = I("get.o_id", 0, "intval");
  $info = $this->model->findone(array("a.id" => $o_id, 'a.status' => array('neq', '-1')));
  //10代表订单待支付的状态
  if ($info['order_status'] != 10) {
   $this->error("订单已支付!");
  }
  vendor("Payment.Alipay.Alipay");
  $alipay = new \Alipay();
  $param['order_sn'] = $info['order_code'];
//  $param['order_amount'] = $info['pay_price'];
  $param['order_amount'] = 0.01;//测试支付时,将支付价格设为0.01元,土豪朋友忽略此提示O(∩_∩)O~
  $param['order_subject'] = '支付宝支付测试';
  $param['return_url'] = 'http://' . $_SERVER['SERVER_NAME'] . '/index.php/Wine/Orders/pay_ok/o_id/'.$o_id;
  $return = $alipay->submit($param);
  echo $return;
  exit;
 }

就是这么简单几步,到此,支付宝支付的流程就已经结束了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
删除无限级目录与文件代码共享
Jul 12 PHP
vBulletin HACK----显示话题大小和打开新窗口于论坛索引页
Oct 09 PHP
PHP 引用文件技巧
Mar 02 PHP
PHP中用接口、抽象类、普通基类实现“面向接口编程”与“耦合方法”简述
Mar 23 PHP
比较简单实用的PHP无限分类源码分享(思路不错)
Oct 13 PHP
redis 队列操作的例子(php)
Apr 12 PHP
PHP 安全检测代码片段(分享)
Jul 05 PHP
PHP实现根据浏览器跳转不同语言页面代码
Aug 02 PHP
PHP英文字母大小写转换函数小结
May 03 PHP
php导出csv文件,可导出前导0实例代码
Nov 16 PHP
php生成无限栏目树
Mar 16 PHP
laravel model模型处理之修改查询或修改字段时的类型格式案例
Oct 17 PHP
ThinkPHP中create()方法自动验证表单信息
Apr 28 #PHP
ThinkPHP实现简单登陆功能
Apr 28 #PHP
ThinkPHP实现分页功能
Apr 28 #PHP
ThinkPHP实现附件上传功能
Apr 27 #PHP
使用ThinkPHP生成缩略图及显示
Apr 27 #PHP
php实现头像上传预览功能
Apr 27 #PHP
php文件上传及下载附带显示文件及目录功能
Apr 27 #PHP
You might like
php读取csv文件后,uft8 bom导致在页面上显示出现问题的解决方法
2013/08/10 PHP
PHP的preg_match匹配字符串长度问题解决方法
2014/05/03 PHP
学习php设计模式 php实现访问者模式(Visitor)
2015/12/07 PHP
Javascript与vbscript数据共享
2007/01/09 Javascript
基于jQuery的Tab选项框效果代码(插件)
2011/03/01 Javascript
结合JQ1.9通过js正则判断各种浏览器版本的方法
2013/12/30 Javascript
javascript复制粘贴与clipboardData的使用
2014/10/16 Javascript
js实现下拉列表选中某个值的方法(3种方法)
2015/12/17 Javascript
JS构造函数与原型prototype的区别介绍
2016/07/04 Javascript
jQuery Validate验证表单时多个name相同的元素只验证第一个的解决方法
2016/12/24 Javascript
js仿QQ邮箱收件人选择与搜索功能
2017/02/10 Javascript
使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能
2018/03/22 Javascript
Mac下通过brew安装指定版本的nodejs教程
2018/05/17 NodeJs
JavaScript设计模式之工厂模式和抽象工厂模式定义与用法分析
2018/07/26 Javascript
Nest.js 授权验证的方法示例
2021/02/22 Javascript
pymongo实现多结果进行多列排序的方法
2015/05/16 Python
定制FileField中的上传文件名称实例
2017/08/23 Python
Python编程之黑板上排列组合,你舍得解开吗
2017/10/30 Python
python模块导入的细节详解
2018/12/10 Python
Python Django框架单元测试之文件上传测试示例
2019/05/17 Python
Python浮点型(float)运算结果不正确的解决方案
2020/09/22 Python
matplotlib 使用 plt.savefig() 输出图片去除旁边的空白区域
2021/01/05 Python
德国网上药房:Apotal
2017/04/04 全球购物
好莱坞百老汇御用王牌美妆:Koh Gen Do 江原道
2018/04/03 全球购物
英国地毯卖家:The Rug Seller
2019/07/18 全球购物
什么是servlet
2012/05/08 面试题
工程专业毕业生自荐信范文
2013/12/25 职场文书
生物制药自我鉴定
2014/01/25 职场文书
怎样拟定创业计划书
2014/05/01 职场文书
机械工程学院大学生求职信
2014/05/25 职场文书
三月法制宣传月活动总结
2014/07/03 职场文书
观看信仰心得体会
2014/09/04 职场文书
四风个人对照检查材料思想汇报(办公室通用版)
2014/10/07 职场文书
汽车转让协议书
2015/01/29 职场文书
社区党务工作总结2015
2015/05/19 职场文书
nginx 多个location转发任意请求或访问静态资源文件的实现
2021/03/31 Servers