您的位置:首页 > 编程语言 > PHP开发

支付接口的注意事项

2017-02-15 18:18 169 查看
1、php的ini文件要开启php_openssl的支持

2、微信支付回调成功后要先向微信发起查询订单接口,确保订单是付款的,而不是恶意模拟请求,查询微信后台存在该订单的时候,再处理自己的逻辑

3、支付宝支付成功回调的时候,要判断支付的金额是否和数据库的金额一致,一致才能认为付款成功,避免模拟请求的

4、微信支付的调用方法

(1) 微信api生成随机字符串

function wechatRandomStr()
{
return  md5(time().mt_rand(0,1000));
}


(2)生成微信sign签名

function createWechatSign($arr)
{
ksort($arr);
return strtoupper(md5(urldecode(http_build_query($arr) . '&key='.WECHAT_PARTNER_KEY)));
}


(3)生成xml数组

function createXml($arr)
{
$xml="<xml>\n";
foreach ($arr as $key => $value) {
$xml.="<".$key."><![CDATA[".trim($value)."]]></".$key.">\n";
}
$xml.="</xml>";
return $xml;
}

(4) 数据生成xml格式,返回xml格式的数据

function curlWechatApi($uri,$xmlData)
{
$ch = curl_init();
$header = array('Content-type: text/xml');
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlData);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$res = simplexml_load_string(curl_exec($ch),null, LIBXML_NOCDATA);
curl_close($ch);
return $res;
}


(5)微信查询订单

function orderQuery($wechatOrderID,$orderID)
{
$arr = array(
'appid' => WECHAT_APP_ID,//appid微信开放平台审核通过的应用APPID
'mch_id'=> WECHAT_MCH_ID,//mch_id微信支付分配的商户号
'transaction_id'    =>sprintf('%s',$wechatOrderID),
'out_trade_no'  =>sprintf('%s',$orderID),
'nonce_str' =>wechatRandomStr()
);
$arr['sign'] = createWechatSign($arr);
$dataStr = createXml($arr);
return curlWechatApi(WECHAT_ORDERQUERY_URI,$dataStr);
}


(6)统一下单的接口

function prepayOrder($out_trade_no){
$out_trade_no = $_REQUEST['out_trade_no'];	//接收订单号
订单号的合法合理性判断
//构造一个微信订单
$order=array(
"body" => 商品描述,
"appid" => WECHAT_APP_ID,
'attach'=> 附加数据(店铺名称),
"device_info" => 设备号(APP-001),
"mch_id" => WECHAT_MCH_ID,
"nonce_str" => wechatRandomStr(),
"notify_url" => WECHAT_NOTIFY_URL,
"out_trade_no" => $out_trade_no,
// "spbill_create_ip" => $this->input->ip_address(),  //APP传过来
"spbill_create_ip" => $_SERVER["REMOTE_ADDR"],
"total_fee" => intval(商品价格*100),//注意:前方有坑!!!最小单位是分,跟支付宝不一样。1表示1分钱。只能是整形。
"trade_type" => 'APP'
);
$order['sign'] = createWechatSign($order);
$xml = createXml($order);
$result = curlWechatApi(WECHAT_UNIFIEDORDER_URL,$xml);
//判断是否在微信后台成功生成一个订单
if($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){
$prepay=array(
"noncestr" => $result->nonce_str,
"prepayid" => $result->prepay_id,//上一步请求微信服务器得到nonce_str和prepay_id参数。
"appid"=>WECHAT_APP_ID,
"package"=>"Sign=WXPay",
"partnerid"=>WECHAT_MCH_ID,
"timestamp"=>sprintf('%s',time()),
);
$prepay['sign'] = createWechatSign($prepay);
$prepay['success'] = true;
}
else{

$prepay=array(
"success" => false,
"noncestr"=>"",
"prepayid"=>"",
"appid"=>WECHAT_APP_ID,
"package"=>"Sign=WXPay",
"partnerid"=>WECHAT_MCH_ID,
"timestamp"=>"".time(),
"sign" => "",
"return_msg"=>sprintf('%s',$result->return_msg)
);

}
return $prepay;
}


(7)微信支付通知回调

function notify(){
$xml = file_get_contents('php://input');
$result = simplexml_load_string($xml,null,LIBXML_NOCDATA);
//判断参数是否合理,微信订单是否存在
if(is_object($result) && property_exits($result,'transaction_id') && property_exists($result,'out_trade_no')
{
$wechatOrderInfo = orderOquery($result->transaction_id,$result->out_trade_no);
//微信订单不存在,终止执行,并进行日志记录
if($wechatOrderInfo->return_code != 'SUCCESS' || $wechatChatOrderInfo->trade_state != 'SUCCESS')
{
addLog($xml,'微信订单不存在',json_encode($wechetOrderInfo));
$str = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
echo $str;
exit();
}
}
//判断订单在数据库中是否已经付款,付款终止(省略)
if($wechatOrderInfo->return_code == 'SUCCESS' && $wechatOrderInfo->result_code == 'SUCCESS'){
//处理业务逻辑
}
//失败处理
}


参考微信支付统一下单接口和支付回调:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php api 支付