您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
微信app支付thinphp整合统一下单与异步通知
发布时间:2017-06-24 17:56:22编辑:雪饮阅读()
统一下单示例:
//微信支付app支付-统一下单
public function wxpayUnifiedorder(){
$msg=1;
$error="";
$body=I("post.body");
$out_trade_no=I("post.out_trade_no")."_".time();
$total_fee=I("post.total_fee");
$appid=C("wxAppid");//微信appid
$mch_id=C("wxMch_id");//微信商户id
$wxMchKey=C("wxMchKey");//微信商户秘钥
$nonce_str=getNonceStr();//获取随机字符串
$spbill_create_ip=$_SERVER["REMOTE_ADDR"];
$trade_type="APP";
//异步通知地址
$notify_url="http://".$_SERVER["SERVER_NAME"]."/wxpay/notify_url.php";
$params=array(
"appid"=>$appid,
"mch_id"=>$mch_id,
"notify_url"=>$notify_url,
"nonce_str"=>$nonce_str,
"body"=>$body,
"out_trade_no"=>$out_trade_no,
"total_fee"=>$total_fee,
"spbill_create_ip"=>$_SERVER["REMOTE_ADDR"],
"trade_type"=>$trade_type,
);
$sign=getSign($params,$wxMchKey);//获取签名
$xmlData = "
<xml>
<appid><![CDATA[$appid]]></appid>
<mch_id><![CDATA[$mch_id]]></mch_id>
<nonce_str><![CDATA[$nonce_str]]></nonce_str>
<notify_url><![CDATA[$notify_url]]></notify_url>
<body><![CDATA[$body]]></body>
<out_trade_no><![CDATA[$out_trade_no]]></out_trade_no>
<total_fee><![CDATA[$total_fee]]></total_fee>
<spbill_create_ip><![CDATA[$spbill_create_ip]]></spbill_create_ip>
<trade_type><![CDATA[$trade_type]]></trade_type>
<sign><![CDATA[$sign]]></sign>
</xml>";
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$returnData=xmlSend($url,$xmlData);
$xml=$returnData;
$dom=new DOMDocument('1.0','utf-8');
$dom->loadXML($xml);
$return_code=$dom->getElementsByTagName("return_code")->item(0)->firstChild;
if($return_code->wholeText=="FAIL"){
$msg=0;
$return_msg=$dom->getElementsByTagName("return_msg")->item(0)->firstChild;
$error=$return_msg->wholeText;
}
else{
//如果上一次请求成功,那么我们将返回的数据重新拼装,进行第二次签名
$prepayId=$dom->getElementsByTagName("prepay_id")->item(0)->firstChild->wholeText;
$sj=time();
$nonce_str=getNonceStr();
$resignData = array(
'appid'=>$appid,
'partnerid'=>$mch_id,
'prepayid'=>$prepayId,
'noncestr'=>$nonce_str,
'timestamp'=>$sj,
'package'=>'Sign=WXPay',
);
$sign=getSign($resignData,$wxMchKey);
$appArray["appid"]=$appid;
$appArray["partnerid"]=$mch_id;
$appArray["prepayid"]=$prepayId;
$appArray["package"]='Sign=WXPay';
$appArray["noncestr"]=$nonce_str;
$appArray["timestamp"]=$sj;
$appArray["sign"]=$sign;
}
$hc=1;
echo json_encode(array("msg"=>$msg,"error"=>$error,"data"=>$appArray,"hc"=>2));
}
统一下单涉及的函数:
//随机数获取(微信app支付接口使用)
function getNonceStr() {
$code = "";
for ($i=0; $i > 10; $i++) {
$code .= mt_rand(1000); //获取随机数
}
$nonceStrTemp = md5($code);
$nonce_str = mb_substr($nonceStrTemp, 5,37); //MD5加密后截取32位字符
return $nonce_str;
}
//签名获取(微信app支付接口使用)
function getSign($params,$keyer) {
ksort($params); //将参数数组按照参数名ASCII码从小到大排序
foreach ($params as $key => $item) {
if (!empty($item)) { //剔除参数值为空的参数
$newArr[] = $key.'='.$item; // 整合新的参数数组
}
}
$stringA = implode("&", $newArr); //使用 & 符号连接参数
$stringSignTemp = $stringA."&key=".$keyer; //拼接key
// key是在商户平台API安全里自己设置的
$stringSignTemp = MD5($stringSignTemp); //将字符串进行MD5加密
$sign = strtoupper($stringSignTemp); //将所有字符转换为大写
return $sign;
}
//发送xml数据
function xmlSend($url,$xmlData){
$header[] = "Content-type: text/xml"; //定义content-type为xml,注意是数组
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlData);
$response = curl_exec($ch);
if(curl_errno($ch)){
print curl_error($ch);
}
curl_close($ch);
return $response;
}
异步通知示例:
<?php
$tpConfig=require_once ($_SERVER["DOCUMENT_ROOT"]."/App/Conf/config.php");
function curlPost($post_data,$curlstr){
$ch=curl_init();//初始化
curl_setopt($ch,CURLOPT_URL,$curlstr);//设置访问网页的URL
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);//执行之后不直接打印出来
curl_setopt($ch, CURLOPT_POST, 1);//允许post
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);//设置post传递
$output=curl_exec($ch);//执行
curl_close($ch);
return $output;
}
function pdo_ping($dbconn){
try{$dbconn->getAttribute(PDO::ATTR_SERVER_INFO);}
catch(PDOException $e) {
if(strpos($e->getMessage(), 'MySQL server has gone away')!==false){return false;}
}
return true;
}
//签名获取(微信app支付接口使用)
function getSign($params,$keyer) {
ksort($params); //将参数数组按照参数名ASCII码从小到大排序
foreach ($params as $key => $item) {
if (!empty($item)) { //剔除参数值为空的参数
$newArr[] = $key.'='.$item; // 整合新的参数数组
}
}
$stringA = implode("&", $newArr); //使用 & 符号连接参数
$stringSignTemp = $stringA."&key=".$keyer; //拼接key
// key是在商户平台API安全里自己设置的
$stringSignTemp = MD5($stringSignTemp); //将字符串进行MD5加密
$sign = strtoupper($stringSignTemp); //将所有字符转换为大写
return $sign;
}
$pdo=new PDO("mysql:host=localhost;dbname=".$tpConfig["DB_NAME"],$tpConfig["DB_USER"],$tpConfig["DB_PWD"]);
if(!pdo_ping($pdo)){exit();}
$postXml = $GLOBALS["HTTP_RAW_POST_DATA"];
$dom=new DOMDocument('1.0','utf-8');
$dom->loadXML($postXml);
$appid=$dom->getElementsByTagName("appid")->item(0)->firstChild->wholeText;
$bank_type=$dom->getElementsByTagName("bank_type")->item(0)->firstChild->wholeText;
$cash_fee=$dom->getElementsByTagName("cash_fee")->item(0)->firstChild->wholeText;
$fee_type=$dom->getElementsByTagName("fee_type")->item(0)->firstChild->wholeText;
$is_subscribe=$dom->getElementsByTagName("is_subscribe")->item(0)->firstChild->wholeText;
$mch_id=$dom->getElementsByTagName("mch_id")->item(0)->firstChild->wholeText;
$nonce_str=$dom->getElementsByTagName("nonce_str")->item(0)->firstChild->wholeText;
$openid=$dom->getElementsByTagName("openid")->item(0)->firstChild->wholeText;
$out_trade_no=$dom->getElementsByTagName("out_trade_no")->item(0)->firstChild->wholeText;
$result_code=$dom->getElementsByTagName("result_code")->item(0)->firstChild->wholeText;
$return_code=$dom->getElementsByTagName("return_code")->item(0)->firstChild->wholeText;
$sign=$dom->getElementsByTagName("sign")->item(0)->firstChild->wholeText;
$time_end=$dom->getElementsByTagName("time_end")->item(0)->firstChild->wholeText;
$total_fee=$dom->getElementsByTagName("total_fee")->item(0)->firstChild->wholeText;
$trade_type=$dom->getElementsByTagName("trade_type")->item(0)->firstChild->wholeText;
$transaction_id=$dom->getElementsByTagName("transaction_id")->item(0)->firstChild->wholeText;
$data=array(
'appid'=>$appid,
'mch_id'=>$mch_id,
'nonce_str'=>$nonce_str,
'result_code'=>$result_code,
'return_code'=>$return_code,
'openid'=>$openid,
'trade_type'=>$trade_type,
'bank_type'=>$bank_type,
'total_fee'=>$total_fee,
'cash_fee'=>$cash_fee,
'fee_type'=>$fee_type,
'is_subscribe'=>$is_subscribe,
'transaction_id'=>$transaction_id,
'out_trade_no'=>$out_trade_no,
'time_end'=>$time_end,
);
$sign3=getSign($data,$tpConfig["wxMchKey"]);
if($sign3==$sign){
//是微信发来的异步通知
if($result_code=="SUCCESS"){
//支付业务支付成功
$total_fee=explode("_",$total_fee);
$total_fee=$total_fee[0];
$rows = $pdo->query("select money,pay,businesses_id from s_order where id =".$out_trade_no)->fetch();
if($rows["money"]==$total_fee){
if($rows["pay"]==0){
//验证金额
$stmt=$pdo->prepare("update s_order set pay=:pay where id=:id");
$stmt->bindParam(":pay",$pay);
$stmt->bindParam(":id",$id);
$pay=1;
$id=$out_trade_no;
if($stmt->execute()){
$res = $stmt->rowCount();
if($res>0){
//订单更新成功
$reply = "<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
</xml>";
echo $reply;
$jpres = $pdo->query("select phone from business where id =".$rows["businesses_id"])->fetch();
//给商家推送
$url="http://".$_SERVER["SERVER_NAME"]."/index.php?s=/Index/Index/jpushAll/";
$returnData=curlPost(array("phones"=>$jpres["phone"],"jpushType"=>"defautl","title"=>"微信支付下单提醒","content"=>"请尽快处理"),$url);
$returnData=json_decode($returnData);
//推送检查
if($returnData->msg!=1){
$stmt=$pdo->prepare("update s_order set jpushStatus=:jpushStatus where id=:id");
$jpushStatus=0;
$id=$out_trade_no;
$stmt->execute();
}
}
}
}
else{
//订单更新成功
$reply = "<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
</xml>";
echo $reply;
}
}
}
}
?>
关键字词:微信app支付,php,统一下单