探索:CodeIgniter集成微信扫码支付方案
2016-07-06 本文已影响995人
三天大愚
微信扫码支付API文档下载地址:微信扫码支付API文档下载
1. 集成微信扫码支付的CI目录结构
├─config 配置文件目录
│ ├─wxpay.php 微信支付配置文件
│ └─...
├─...
├─libraries 扩展类库目录
│ ├─MY_WxPay.php 微信支付
│ ├─MY_WxPayNotify.php 微信支付通知回调
│ ├─Payment 各种支付类库目录
│ │ ├─Wxpaylib 微信支付类库包目录
│ │ │ ├─WxPay.Api.php
│ │ │ ├─WxPay.Config.php
│ │ │ ├─WxPay.Data.php
│ │ │ ├─WxPay.Exception.php
│ │ │ ├─WxPay.Notify.php
│ │ │ ├─apiclient_cert.pem
│ │ │ └─apiclient_key.pem
│ │ └─... 更多支付类库目录
│ └─... 更多第三方类库目录
└─...
2. wxpay.php 微信支付配置文件
<?php defined('BASEPATH') OR exit('No direct script access allowed');
//=======【基本信息设置】=====================================
/**
* TODO: 修改这里配置为您自己申请的商户信息
* 微信公众号信息配置
*
* APPID:绑定支付的APPID(必须配置,开户邮件中可查看)
*
* MCHID:商户号(必须配置,开户邮件中可查看)
*
* KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置)
* 设置地址:https://pay.weixin.qq.com/index.php/account/api_cert
*
* APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置),
* 获取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
* @var string
*/
$config['APPID'] = '';
$config['MCHID'] = '';
$config['KEY'] = '';
$config['APPSECRET'] = '';
//=======【证书路径设置】=====================================
/**
* TODO:设置商户证书路径
* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,
* API证书下载地址:https://pay.weixin.qq.com/index.php/account/api_cert,下载之前需要安装商户操作证书)
* @var path
*/
$config['SSLCERT_PATH'] = './apiclient_cert.pem';
$config['SSLKEY_PATH'] = './apiclient_key.pem';
//=======【curl代理设置】===================================
/**
* TODO:这里设置代理机器,只有需要代理的时候才设置,不需要代理,请设置为0.0.0.0和0
* 本例程通过curl使用HTTP POST方法,此处可修改代理服务器,
* 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0,此时不开启代理(如有需要才设置)
* @var unknown_type
*/
$config['CURL_PROXY_HOST'] = "0.0.0.0";//"10.152.18.220";
$config['CURL_PROXY_PORT'] = 0;//8080;
//=======【上报信息配置】===================================
/**
* TODO:接口调用上报等级,默认紧错误上报(注意:上报超时间为【1s】,上报无论成败【永不抛出异常】,
* 不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少
* 开启错误上报。
* 上报等级,0.关闭上报; 1.仅错误出错上报; 2.全量上报
* @var int
*/
$config['REPORT_LEVENL'] = 1;
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
$config['NOTIFY_URL'] = site_url('pay/wxpaynotify');
3. 修改 WxPay.Data.php
当然你也可以直接将这些参数写在这里,而不需要wxpay.php配置文件
<?php defined('BASEPATH') OR exit('No direct script access allowed');
$_CI = & get_instance();
$_CI->load->config('wxpay');
define('WX_APPID', $_CI->config->item('APPID'));
define('WX_MCHID', $_CI->config->item('MCHID'));
define('WX_KEY', $_CI->config->item('KEY'));
define('WX_APPSECRET', $_CI->config->item('APPSECRET'));
define('WX_SSLCERT_PATH', $_CI->config->item('SSLCERT_PATH'));
define('WX_SSLKEY_PATH', $_CI->config->item('SSLKEY_PATH'));
define('WX_NOTIFY_URL', $_CI->config->item('NOTIFY_URL'));
unset($_CI);
/**
* 配置账号信息
*/
class WxPayConfig {
//=======【基本信息设置】=====================================
//
/**
* TODO: 修改这里配置为您自己申请的商户信息
* 微信公众号信息配置
*
* APPID:绑定支付的APPID(必须配置,开户邮件中可查看)
*
* MCHID:商户号(必须配置,开户邮件中可查看)
*
* KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置)
* 设置地址:https://pay.weixin.qq.com/index.php/account/api_cert
*
* APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置),
* 获取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
* @var string
*/
const APPID = WX_APPID;
const MCHID = WX_MCHID;
const KEY = WX_KEY;
const APPSECRET = WX_APPSECRET;
//=======【证书路径设置】=====================================
/**
* TODO:设置商户证书路径
* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,
* API证书下载地址:https://pay.weixin.qq.com/index.php/account/api_cert,下载之前需要安装商户操作证书)
* @var path
*/
const SSLCERT_PATH = WX_SSLCERT_PATH;
const SSLKEY_PATH = WX_SSLKEY_PATH;
//=======【curl代理设置】===================================
/**
* TODO:这里设置代理机器,只有需要代理的时候才设置,不需要代理,请设置为0.0.0.0和0
* 本例程通过curl使用HTTP POST方法,此处可修改代理服务器,
* 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0,此时不开启代理(如有需要才设置)
* @var unknown_type
*/
const CURL_PROXY_HOST = "0.0.0.0";//"10.152.18.220";
const CURL_PROXY_PORT = 0;//8080;
//=======【上报信息配置】===================================
/**
* TODO:接口调用上报等级,默认紧错误上报(注意:上报超时间为【1s】,上报无论成败【永不抛出异常】,
* 不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少
* 开启错误上报。
* 上报等级,0.关闭上报; 1.仅错误出错上报; 2.全量上报
* @var int
*/
const REPORT_LEVENL = 1;
const NOTIFY_URL = WX_NOTIFY_URL;
}
4. MY_WxPay.php 自定义微信支付类
<?php defined('BASEPATH') OR exit('No direct script access allowed');
// 加载微信支付接口类
require_once APPPATH.'libraries/Payment/Wxpaylib/WxPay.Api.php';
/**
* MY_WxPay 自定义微信支付类
* @author Mike Lee
*/
class MY_WxPay {
private $_CI;
public function __construct(){
// 获得 CI 超级对象 使得自定义类可以使用Controller类的方法
$this->_CI = & get_instance();
}
/**
* createPayQRcode2
* 生成直接支付url 支付url有效期为2小时 模式二
* @param array $params 统一下单参数组
* @return void
* @author Mike Lee
*/
public function createPayQRcode2($params){
$input = $this->getUnifiedOrderInput($params);
if ($input->GetTrade_type() == 'NATIVE') {
$result = WxPayApi::unifiedOrder($input);
// 这里也可以直接返回code_url 然后直接使用demo中生成二维码的方式
// return urlencode($result['code_url']);
$this->_CI->load->library('MY_QRcode');
$this->_CI->my_qrcode->createQRcode($result['code_url']);
}
}
/**
* getUnifiedOrderInput 获取统一下单输入对象
* @access public
* @param array $params
* @return UnifiedOrderInput $input
* @author Mike Lee
*/
public function getUnifiedOrderInput($params){
$input = new WxPayUnifiedOrder();
$input->SetOut_trade_no($params['out_trade_no']);
$input->SetBody($params['body']);
// $input->SetAttach("test");
// $input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));
$input->SetTotal_fee($params['total_fee']);
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis", time() + 600));
// $input->SetGoods_tag("test");
// $input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");
$input->SetTrade_type($params['trade_type']);
$input->SetProduct_id($params['product_id']);
// $input->SetSpbill_create_ip($params['spbill_create_ip']);
return $input;
}
/**
* wxPayOrderQuery 微信支付订单查询
* @access public
* @param string $order_code
* @param bool $mode
* @return array
* @author Mike Lee
*/
public function getWxPayOrderInfo($order_code, $mode = false){
if ( ! $order_code) return false;
$input = new WxPayOrderQuery();
if ($mode) {
// 微信订单号
$input->SetTransaction_id($order_code);
} else {
// 商户订单号
$input->SetOut_trade_no($order_code);
}
return WxPayApi::orderQuery($input);
}
}
/* End of file MY_Wxpay.php */
/* Location: ./application/libraries/MY_WxPay.php */
5. MY_WxPayNotify.php 自定义微信支付通知类
<?php defined('BASEPATH') OR exit('No direct script access allowed');
// 加载微信支付接口类
require_once APPPATH.'libraries/Payment/Wxpaylib/WxPay.Api.php';
require_once APPPATH.'libraries/Payment/Wxpaylib/WxPay.Notify.php';
/**
* MY_WxPayNotify 自定义微信支付类
* @author Mike Lee
*/
class MY_WxPayNotify extends WxPayNotify {
private $_CI;
public function __construct(){
// 获得 CI 超级对象 使得自定义类可以使用Controller类的方法
$this->_CI = & get_instance();
}
/**
* NotifyProcess 微信回调处理
* @access public
*/
public function NotifyProcess($data, &$msg){
//echo "处理回调";
log_message('error', json_encode($data));
if ($data['return_code'] == 'SUCCESS' && $data['result_code'] == 'SUCCESS') {
$this->updateOrderPay($data);
return true;
}
return false;
}
/**
* updateOrderPay 更新订单支付信息
* @access private
* @param string $order_code
* @return mixed
* @author Mike Lee
*/
public function updateOrderPay($wxpay_data){
$this->_CI->load->model('order_model');
// 根据订单号获取订单信息
$order_code = $wxpay_data['out_trade_no'];
$order_info = $this->_CI->order_model->getOrderByID($order_code, true);
if ($order_info['order_status'] == 0 && $order_info['pay_status'] != '1') {
// 更新订单的支付状态及支付方式
// pay_status => 1 表示支付成功
// pay_method => 2 表示支付方式为微信支付
$pay_info = array('pay_status' => '1', 'pay_method' => 2);
$pay_result = $this->_CI->order_model->updateOrderPayStatus($order_code, $pay_info, true);
// 添加订单支付信息
// user_id 用户ID
// order_id 订单ID
// total_fee 支付总额
// openid 用户微信唯一ID
$order_pay_info = array(
'user_id' => $order_info['user_id'],
'order_id' => $order_info['id'],
'total_fee' => $wxpay_data['cash_fee'] / 100,
'openid' => $wxpay_data['openid'],
'time' => time()
);
$this->_CI->order_model->addOrderWxPayLog($order_pay_info);
// 添加用户收支日志
// correlation_id 关联ID 这里为订单ID
// action_type => 1 表示为商品购买事件
// point_type => 4 表示为微信支付
$payment_log = array(
'user_id' => $order_info['user_id'],
'correlation_id' => $order_info['id'],
'action_type' => 1,
'pay_type' => 4,
'total_fee' => $wxpay_data['cash_fee'] / 100,
'remark' => 'XXXX商品购买:微信支付'.$wxpay_data['cash_fee'] / 100,
'action_ip' => $_SERVER['REMOTE_ADDR'],
'add_time' => time()
);
$this->_CI->order_model->addUserPayLog($payment_log);
}
return true;
}
}
/* End of file MY_WxPayNotify.php */
/* Location: ./application/libraries/MY_WxPayNotify.php */
6. pay.php 支付控制器
<?php defined('BASEPATH') OR exit('No direct script access allowed');
/**
* pay 支付控制器
*/
class Pay extends MY_Controller {
public function __construct(){
$this->isNeedLogin = FALSE;
parent::__construct();
}
/**
* generateQRcode 生成微信支付二维码
* @access public
* @param void
* @return void
* @author Mike Lee
*/
public function generateWxPayQRcode($order_code = false){
if ( ! $order_code) {
$order_code = $this->uri->segment(3, false);
if ( ! $order_code) return false;
}
$this->load->model('order_model');
$order_info = $this->order_model->getOrderByID($order_code, true);
if ( ! is_array($order_info) || ! $order_info) {
return false;
}
// 准备微信支付参数数组
$params = array(
'out_trade_no' => $order_code,
'body' => 'XXXX网商品购买',
'total_fee' => $order_info['order_amount'] * 100,
'trade_type' => 'NATIVE',
'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
'product_id' => 1
);
$this->load->library('MY_WxPay');
$this->my_wxpay->createPayQRcode2($params);
}
/**
* wxPayNotify 微信回调
* @access public
* @param void
* @return void
* @author Mike Lee
*/
public function wxPayNotify(){
$this->load->library('MY_WxPayNotify');
$result = $this->my_wxpaynotify->Handle(true);
}
/**
* wxPayResult 微信支付结果查询
* @access public
* @param void
* @return void
* @author Mike Lee
*/
public function wxPayResult(){
$order_code = $this->input->post('order_code', true);
$pay_method = $this->input->post('pay_method', true);
$this->load->model('order_model');
$order_info = $this->order_model->getOrderByID($order_code, true);
if ($order_info['is_pay'] == '1') {
$this->ajaxReturn('SUCCESS');
} else {
$this->ajaxReturn('WAITING');
}
// sleep(1);
}
}
/* End of file pay.php */
/* Location: ./application/controllers/pay.php */