微信支付
項目前提:本人用的是tp框架枣氧,PHP語言
下載到微信平臺提供的微信支付接口文件溢十,放在了tp第三方類庫vendor,命名為WxpayAPI达吞,
WxpayAPI/lib/WxPay.Api.php?接口訪問類;
WxpayAPI/lib/WxPay.Config.php?配置賬號信息;
WxpayAPI/lib/WxPay.Data.php?數(shù)據(jù)對象基礎(chǔ)類;
WxpayAPI/lib/WxPay.Exception.php?微信支付API異常類;
WxpayAPI/lib/WxPay.Notify.php?回調(diào)基礎(chǔ)類
WxpayAPI/example/WxPay.JsApiPay.php?JSAPI支付實現(xiàn)類
1.對源碼進行了部分修改
(1)WxPay.Api.php?里注釋掉
//require_once?"WxPay.Exception.php";
//require_once?"WxPay.Config.php";
//require_once?"WxPay.Data.php";
(2)WxPay.Config.php里
需要根據(jù)商戶信息對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有訂單函數(shù)sure()和回調(diào)信息函數(shù) Callback_url()
/**
*?提交訂單函數(shù)
*/
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';
}
//函數(shù)調(diào)用?返回信息
$this->Callback_url($data);
}?else?{
$this->error($o_model->getError());
}
}?else?{
$this->error($o_model->getError());
}
}
/**
*?回調(diào)信息函數(shù)
*?@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?=?'正在為您跳轉(zhuǎn)到微信支付頁面透敌,請等待……';
$url?=?"/index.php/wine/wxpay/index/?o_id=$add_id";
}
$this->success("訂單提交成功盯滚!"?.?$msg,?$url);
}
3.[重點!P锏纭魄藕!]?WxpayController .class.php微信支付控制器,實現(xiàn)對微信接口的調(diào)用
/**
*?微信支付接口調(diào)用
*/
namespace?Wine\Controller;
use?Common\Controller\HomebaseController;
class?WxpayController?extends?HomebaseController?{
public?function?_initialize()?{
parent::_initialize();
Vendor("WxpayAPI/example/log");//訂單數(shù)據(jù)寫入日志
//注:?引入第三方類庫中的微信接口文件撵术,對于文件名含有.的背率,皆用#代替連接才能引入,后綴名不寫嫩与。
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代表訂單待支付的狀態(tài)
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";?#無法使用
//②、統(tǒng)一下單
$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");#?優(yōu)惠券
$input->SetNotify_url('http://'?.?$_SERVER['HTTP_HOST']?.?"/index.php/Wine/Wxpay/callback");?//回調(diào)地址
$input->SetTrade_type("JSAPI");
$input->SetOpenid($openId);
$order?=?\WxPayApi::unifiedOrder($input);
//echo?'統(tǒng)一下單支付單信息
';
//$this->printf_info($order);//打印參數(shù)
$this->assign('o_id',$orderid);
$this->assign('jsApiParameters',?$tools->GetJsApiParameters($order));
//獲取共享收貨地址js函數(shù)參數(shù)
//$this->assign('editAddress',?$tools->GetEditAddressParameters());
$this->display('wxpay');
exit;
}
/**
*?打印輸出數(shù)組信息
*?@param?type?$data
*/
public?function?printf_info($data)?{
foreach?($data?as?$key?=>?$value)?{
echo?"$key?:?$value?
";
}
}
/*?支付成功回調(diào)函數(shù)?*/
public?function?callback()?{
/*?返回給微信服務(wù)器?*/
//??$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;
}
//?回調(diào)值
if?(!empty($arr))?{
#?數(shù)據(jù)
\Log::INFO('數(shù)據(jù)1'?.?var_export($arr,?true));
#修改訂單狀態(tài)
$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('數(shù)據(jù)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);
}
/*?返回給微信服務(wù)器?*/
$mes?=?array(
'return_code'?=>?'SUCCESS',
'return_msg'?=>?'OK'
);
$this->ajaxReturn($mes,?'XML');
}
//將XML轉(zhuǎn)為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
微信訂單支付
//調(diào)用微信JS?api?支付
function?jsApiCall()
{
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
?echo?$jsApiParameters;?,
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);
//?成功跳轉(zhuǎn)頁面
window.location.href?=?'{:U("Orders/pay_ok",array("o_id"=>$o_id))}';
//?統(tǒng)一跳轉(zhuǎn)
}
);
}
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();
}
}
訂單已生成
該筆訂單支付金額為:?echo?$pay_price;
立即支付
.html">查看詳情
-->
5.支付成功跳轉(zhuǎn)到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();
}
}
到此同窘,微信支付流程結(jié)束玄帕。
支付寶支付
話不多說,直接上代碼想邦!
注:1.支付文件是從支付寶上直接拿過來的2.依舊是TP框架
【1】將文件放入第三方類庫:
(1)
*?類名:AlipayConfig.php
*?功能:支付寶配置文件
*?修改配置:
//?MD5密鑰裤纹,安全檢驗碼,由數(shù)字和字母組成的32位字符串丧没,查看地址:https://b.alipay.com/order/pidAndKey.htm
$alipay_config['key']?=?'';//(**從支付寶中獲取**)
//?服務(wù)器異步通知頁面路徑??需http://格式的完整路徑鹰椒,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
$alipay_config['notify_url']?=?'http://'?.?$_SERVER['SERVER_NAME']?.?'/index.php/Wine/PayCallback/alipay_notify';
//?頁面跳轉(zhuǎn)同步通知頁面路徑?需http://格式的完整路徑骂铁,不能加?id=123這類自定義參數(shù)吹零,必須外網(wǎng)可以正常訪問
$alipay_config['return_url']?=?'http://'?.?$_SERVER['SERVER_NAME']?.?'/index.php?g=Wine&m=Orders&a=alipay_return';
(2)
*?類名:AlipayNotify.php
*?功能:支付寶通知處理類
*?詳細:處理支付寶各接口通知返回
(3)
*?類名:Alipay.php
*?功能:手機網(wǎng)站支付接口接入頁
*?詳細:處理支付寶各接口通知返回
class?Alipay?{
public?function?submit($params)?{
//建立請求
$alipaySubmit?=?new?AlipaySubmit($alipay_config);
$html_text?=?$alipaySubmit->buildRequestForm($parameter,?"get",?"確認");
return?'
支付寶支付
'?.?$html_text?.?'
';
}
}
(4)
*?類名:notify_url.php
*?功能:支付寶服務(wù)器異步通知頁面
*?詳細:處理支付寶各接口通知返回
Paste_Image.png
【2】支付業(yè)務(wù)邏輯
(1)GoodsController.class.php?下提交訂單?ajax_sure()
public?function?ajax_sure()?{
$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';
}
//函數(shù)調(diào)用?返回信息
$this->Callback_url($data);
}
/**
*?回調(diào)信息函數(shù)
*?@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?('3'?==?$data['pay_id'])?{
//支付寶支付
$msg?=?'正在為您跳轉(zhuǎn)到支付寶支付頁面灿椅,請等待……';
$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代表訂單待支付的狀態(tài)
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;//測試支付時茫蛹,將支付價格設(shè)為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;
}
就是這么簡單幾步,到此婴洼,支付寶支付的流程就已經(jīng)結(jié)束了骨坑。