controler
<?php
/**
* @name WxPayController
* @author pangee
* @desc 微信支付功能封装
*/
$qrcodeLibPath = dirname(__FILE__).'/../library/ThirdParty/Qrcode/';
include_once( $qrcodeLibPath.'Qrcode.php' );
class WxpayController extends Yaf_Controller_Abstract {
public function indexAction() {
}
public function createbillAction() {
$itemid = $this->getRequest()->getQuery( "itemid", "" );
if( !$itemid ) {
echo json_encode( array("errno"=>-6001, "errmsg"=>"请传递正确的商品ID") );
return FALSE;
}
/**
* 检查是否登录
*/
session_start();
if( !isset($_SESSION['user_token_time']) || !isset($_SESSION['user_token']) || !isset($_SESSION['user_id'])
|| md5( "salt".$_SESSION['user_token_time'].$_SESSION['user_id'] ) != $_SESSION['user_token'] ) {
echo json_encode( array("errno"=>-6002, "errmsg"=>"请先登录后操作") );
return FALSE;
}
// 调用Model
$model = new WxpayModel();
if ( $data=$model->createbill( $itemid, $_SESSION['user_id'] ) ) {
echo json_encode( array(
"errno"=>0,
"errmsg"=>"",
"data" => $data,
));
} else {
echo json_encode( array(
"errno"=>$model->errno,
"errmsg"=>$model->errmsg,
));
}
return TRUE;
}
/**
* 正常情况下返回二维码
*/
public function qrcodeAction() {
$billId = $this->getRequest()->getQuery( "billid", false );
if( !$billId ) {
echo json_encode( array("errno"=>-6008, "errmsg"=>"账单ID必须传递") );
return FALSE;
}
// 调用Model
$model = new WxpayModel();
if ( $data=$model->qrcode( $billId ) ) {
/**
* 输出二维码
*/
QRcode::png($data);
} else {
echo json_encode( array(
"errno"=>$model->errno,
"errmsg"=>$model->errmsg,
));
}
return TRUE;
}
public function callbackAction(){
$model = new WxpayModel();
$model->callback();
echo json_encode( array(
"errno"=>0,
"errmsg"=>"",
));
return TRUE;
}
}
model:
<?php
/**
* @name WxpayModel
* @desc 微信支付功能封装
* @author pangee
*/
$wxpayLibPath = dirname(__FILE__).'/../library/ThirdParty/WxPay/';
include_once( $wxpayLibPath.'WxPay.Api.php' );
include_once( $wxpayLibPath.'WxPay.Notify.php' );
include_once( $wxpayLibPath.'WxPay.NativePay.php' );
include_once( $wxpayLibPath.'WxPay.Data.php' );
class WxpayModel extends WxPayNotify {
public $errno = 0;
public $errmsg = "";
private $_db;
public function __construct() {
$this->_db = new PDO("mysql:host=127.0.0.1;dbname=test;", "root", "123456");
}
public function createbill( $itemId, $uid ){
$query = $this->_db->prepare("select * from `item` where `id`= ? ");
$query->execute( array($itemId) );
$ret = $query->fetchAll();
if( !$ret || count($ret)!=1 ) {
$this->errno = -6003;
$this->errmsg = "找不到这件商品";
return false;
}
$item = $ret[0];
if( strtotime($item['etime']) <= time() ) {
$this->errno = -6004;
$this->errmsg = "商品已过期,不能购买";
return false;
}
if( intval($item['stock'])<=0 ) {
$this->errno = -6005;
$this->errmsg = "商品库存不够,不能购买";
return false;
}
/**
* 创建bill
*/
$query = $this->_db->prepare("insert into `bill` (`itemid`,`uid`,`price`,`status`) VALUES ( ?, ?, ?, 'unpaid') ");
$ret = $query->execute( array( $itemId, $uid, intval($item['price']) ) );
if ( !$ret ) {
$this->errno = -6006;
$this->errmsg = "创建账单失败";
return false;
}
/**
* 成功创建账单后,需要扣去商品库存1件
* TODO 此处应用用事务
*/
$query = $this->_db->prepare("update `item` set `stock`=`stock`-1 where `id`= ? ");
$ret = $query->execute( array( $itemId ) );
if ( !$ret ) {
$this->errno = -6007;
$this->errmsg = "更新库存失败";
return false;
}
return intval($this->_db->lastInsertId());
}
public function qrcode( $billId ){
$query = $this->_db->prepare("select * from `bill` where `id`= ? ");
$query->execute( array($billId) );
$ret = $query->fetchAll();
if( !$ret || count($ret)!=1 ) {
$this->errno = -6009;
$this->errmsg = "找不到账单信息";
return false;
}
$bill = $ret[0];
$query = $this->_db->prepare("select * from `item` where `id`= ? ");
$query->execute( array($bill['itemid']) );
$ret = $query->fetchAll();
if( !$ret || count($ret)!=1 ) {
$this->errno = -6010;
$this->errmsg = "找不到商品信息";
return false;
}
$item = $ret[0];
/**
* 调用微信支付lib,生成账单二维码
*/
$input = new WxPayUnifiedOrder();
$input->SetBody( $item['name'] );
$input->SetAttach( $billId );
$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));
$input->SetTotal_fee( $bill['price'] );
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis", time()+86400*3));
$input->SetGoods_tag( $item['name'] );
$input->SetNotify_url("http://103.72.145.223:8889/?c=wxpay&a=callback");//回调函数
$input->SetTrade_type("NATIVE");
$input->SetProduct_id( $billId );
$notify = new NativePay();
$result = $notify->GetPayUrl($input);
$url = $result["code_url"];
return $url;
}
public function callback(){
/**
* 订单成功,更新账单
* TODO 因为SK没有,没法与微信支付的服务端做Response确认,只能单方面记账
*/
$xmlData = file_get_contents("php://input");
if( substr_count( $xmlData, "<result_code><![CDATA[SUCCESS]]></result_code>" )==1 &&
substr_count( $xmlData, "<return_code><![CDATA[SUCCESS]]></return_code>" )==1 )
{
preg_match( '/<attach>(.*)\[(\d+)\](.*)<\/attach>/i', $xmlData, $match );
if( isset($match[2])&&is_numeric($match[2]) ) {
$billId = intval( $match[2] );
}
preg_match( '/<transaction_id>(.*)\[(\d+)\](.*)<\/transaction_id>/i', $xmlData, $match );
if( isset($match[2])&&is_numeric($match[2]) ) {
$transactionId = intval( $match[2] );
}
}
if( isset($billId) && isset($transactionId) ) {
$query = $this->_db->prepare("update `bill` set `transaction`=? ,`ptime`=? ,`status`='paid' where `id`=? ");
$query->execute( array( $transactionId, date("Y-m-d H:i:s"), $billId ) );
}
}
}