PHP小程序支付功能完整版【基于thinkPHP】
本文实例讲述了PHP小程序支付功能。分享给大家供大家参考,具体如下:
环境:tp3.2 +小程序微信支付功能开通
Step1: 下载PHP支付SDK(下载地址) 放到Library\Vendor下,取名Wxpay
修改WxPay.Config.php里的appidappsecretkeyMCHID
Step2:小程序js代码:
varurl=getApp().globalData.httpServer+'api/buy/pay';
varuserId=getApp().globalData.userId;
vartotalMoney=this.data.totalMoney;
varcart=this.data.goods;
varparam={
cart:JSON.stringify(cart),
cartamount:totalMoney,
userid:userId,
payment:this.data.payment,
addressid:defaultAddress.id
};
varthat=this;
util.http(url,param,function(ret){
if(ret.data.code==1){
if(that.data.payment=='balance'){//余额支付
that.afterPaySuccess(ret.data.data);
}else{//微信支付
wx.requestPayment({
timeStamp:ret.data.data.timeStamp,
nonceStr:ret.data.data.nonceStr,
package:ret.data.data.package,
signType:ret.data.data.signType,
paySign:ret.data.data.paySign,
'success':function(res){
that.afterPaySuccess(ret.data.data.orderid);
},
'fail':function(res){
console.log(res);
}
})
}
}else{
util.showTip(ret.data.msg,'提交订单失败');
}
});
/**
*网络请求
*/
functionhttp(url,params,callback){
wx.request({
url:url,
data:params,
success:function(res){
callback(res);
},
fail:function(err){
console.log(err);
}
});
}
Step3:接口代码:
publicfunctionpay()
{
$cart=I('cart','','trim');
$cartAmount=I('cartamount');
$addressId=I('addressid',0,'intval');
$payment=I('payment','','trim');
$userId=$this->userid;
$cart=json_decode($cart,true);
if(empty($cart)){
$result['msg']='购物车获取失败';
$result['code']=0;
$this->ajaxReturn($result);
}
$totalMoney=0;
foreach($cartas$goods){
$money=$goods['price'];//price
$selectCount=$goods['selectcount'];//price
$itemAmount=number_format($money*$selectCount,2,'.','');
$totalMoney+=$itemAmount;
}
//检查总金额是否一致
if($totalMoney!=$cartAmount){
$result['msg']='总金额不匹配:'.$totalMoney;
$result['code']=0;
$this->ajaxReturn($result);
}
//获取用户地址
$address=M('MemberAddress')->where('userid='.$userId."andid=".$addressId)->find();
if(empty($address)){
$result['msg']='用户地址不存在';
$result['code']=0;
$this->ajaxReturn($result);
}
//用户信息
$user=M('Member')->where("id=".$userId)->find();
if($payment=='balance'){
if($user['amount']<$cartAmount){
$result['msg']='余额不足';
$result['code']=0;
$this->ajaxReturn($result);
}
}
//生成订单
$order['ordersn']=$this->genOrdersn($user['id']);
$order['price']=$cartAmount;
$order['addressid']=$address['id'];
$order['addressinfo']=serialize($address);//json_encode($address);
$order['longitude']=$address['longitude'];
$order['latitude']=$address['latitude'];
$order['addtime']=time();
$order['status']=0;
$order['userid']=$user['id'];
$order['paytype']=$payment;
$order['paysn']='';
$order['paytime']=time();
$orderId=M("Order")->add($order);
if($orderId==0){
$result['msg']='创建订单失败';
$result['code']=0;
$this->ajaxReturn($result);
}
foreach($cartas$goods){
$orderGoods['orderid']=$orderId;
$orderGoods['goodsid']=$goods['id'];
$orderGoods['title']=$goods['title'];
$orderGoods['price']=$goods['price'];
$orderGoods['attr']=$goods['attr'];
$orderGoods['pic']=$goods['pic'];
$orderGoods['num']=$goods['selectcount'];
M("OrderGoods")->add($orderGoods);
}
if($payment=='balance'){
//余额支付
$this->balancePay($cartAmount,$user['wxopenid'],$orderId);
}elseif($payment=='weixin'){
//微信支付
$this->weixinPay($cartAmount,$user['wxopenid'],$orderId,$order['ordersn']);
}
}
/**
*微信支付
*@author大脸猫脸大
*@param$cart
*@param$cartAmount
*@param$address
*@param$user
*/
privatefunctionweixinPay($cartAmount,$openId,$orderId,$orderSn)
{
import("Vendor.Wxpay.lib.WxPay#Api","",".php");
//订单号
$money=$cartAmount*100;
$openid=$openId;
$input=new\WxPayUnifiedOrder();
$input->SetBody("迪克-商品");
$input->SetOut_trade_no("$orderSn");
$input->SetTotal_fee("$money");
$input->SetNotify_url("https://".$_SERVER['HTTP_HOST']."/api/buy/payNotify");
$input->SetTrade_type("JSAPI");
$input->SetOpenid($openid);
$unifiedOrder=\WxPayApi::unifiedOrder($input);
if($unifiedOrder['result_code']=='SUCCESS'&&$unifiedOrder['return_code']=='SUCCESS'){
$time=time();
$data['timeStamp']="$time";//时间戳
$data['nonceStr']=$unifiedOrder['nonce_str'];//随机字符串
$data['signType']='MD5';//签名算法,暂支持MD5
$data['package']='prepay_id='.$unifiedOrder['prepay_id'];//统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=*
$data['paySign']=$this->genPaySign($unifiedOrder,$time);//之前以为是$unifiedOrder['sign'];后来发现是调用的这种方法.签名方案参见微信公众号支付帮助文档;
$data['out_trade_no']=$orderSn;
$data['orderid']=$orderId;
$return['code']=1;
$return['data']=$data;
}else{
Log::write(var_export($unifiedOrder,true),Log::ERR,'',C('LOG_PATH')."wx_pay_".date('y_m_d').'.log');
$return['code']=0;
$return['msg']='微信支付失败';//$unifiedOrder['RETURN_MSG'];
}
$this->ajaxReturn($return);
}
/*生成支付签名*/
privatefunctiongenPaySign($unifiedOrder,$time)
{
$appId=\WxPayConfig::APPID;
$nonceStr=$unifiedOrder['nonce_str'];
$package='prepay_id='.$unifiedOrder['prepay_id'];
$signType="MD5";
$timeStamp=$time;
$key=\WxPayConfig::KEY;
$sign=md5(sprintf("appId=%s&nonceStr=%s&package=%s&signType=%s&timeStamp=%s&key=%s",$appId,$nonceStr,$package,$signType,$timeStamp,$key));
return$sign;
}
/**
*支付回调
*@author:大脸猫脸大
*/
publicfunctionpayNotify()
{
import("Vendor.Wxpay.lib.WxPay#Data","",".php");
$xml=$GLOBALS['HTTP_RAW_POST_DATA'];
$val=\WxPayResults::Init($xml);
if($val['result_code']=='SUCCESS'&&$val['return_code']=='SUCCESS'){
$orderSn=$val['out_trade_no'];
$transactionId=$val['transaction_id'];
$data=array('paytype'=>'weixin','status'=>'1','paytime'=>time(),'paysn'=>$transactionId);
M("Order")->where("ordersn='$orderSn'")->setField($data);
exit(' ');
}else{
Log::write(var_export($val,true),Log::ERR,'',C('LOG_PATH')."wx_pay_notify_".date('y_m_d').'.log');
exit(' ');
}
}
payNotify回调方法里一定要注意返回
如果不处理,你会发现payNotify 会被执行很多次参见:官方文档
总结一下:注意二点,1.签名的问题2.回调方法的返回处理。
欢迎大家指正。
更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP微信开发技巧汇总》、《phpcurl用法总结》、《PHP网络编程技巧总结》、《php字符串(string)用法总结》、《PHP中json格式数据操作技巧汇总》及《PHP针对XML文件操作技巧总结》
希望本文所述对大家PHP程序设计有所帮助。