微信开发配置:
一:配置支付授权目录
公众平台->微信支付->开发配置->支付配置
三个地址微信都解释的很清楚,不再赘述
注意:支付授权目录最好写到js_call_api.php的上一级
我的目录结构:
二:获得开发所需数据
打开weiXinPay/GeneralType/WxPayPubHelper/WxPay.pub.config.php
上面的参数值说明下
MCHID 即 下图的商户号 (微信支付通过申请之后所下发的两封邮件中的一)
KEY 即 下图中的初始密钥 (建议到财付通后台取更改 更改之后这个KEY就是你更改的那个key【md5加密一段字符即可】)
后面说明证书的使用
这里先说明微信支付通过后下发的两封邮件,上图便是其中一封,下图是第二封, 特别说明:微信支付版本在3之后便不再使用下图的PaySignKey,所以如果你是从3以上版本开发的,则不用管此封邮件
下面说一下生成签名(此处未测试,听说可以不用自己生成签名,我配置的时候是按照支付宝的思维来配置的,所以一并写上,万一有谁用上了呢,反正我这样配置可以成功支付)
上上图中有个安全证书,下载下来再windows里面导入,根据文档可以导出需要的两个文件(我按照文档上的没成功,后来到linux下去导出的,这个可能是我在win下的操作不对,我的是win10)
证书后缀是.pfx
生成 apiclient_cert.pem
openssl pkcs12 -clcerts -nokeys -in xxx0625183314.pfx -out apiclient_cert.pem
生成 apiclient_key.pem
openssl pkcs12 -nocerts -in xxx0625183314.pfx -out apiclient_key.pem
Enter Import Password: 输入生成.p12文件时候的密码
MAC verified OK这是提示信息,正确的话会出现这个
Enter PEM pass phrase: 这句话的含义是输入一个加密密码
Verifying – Enter PEM pass phrase: 这是确认加密密码
这样可以得到两个签名文件了,大伙可以绕过生成步骤试试,如果可以麻烦通知一下,现在我的项目已经上线,测试不大容易
三:微信支付对接
<?php
/**
* JS_API支付demo
* ====================================================
* 在微信浏览器里面打开H5网页中执行JS调起支付。接口输入输出数据格式为JSON。
* 成功调起支付需要三个步骤:
* 步骤1:网页授权获取用户openid
* 步骤2:使用统一支付接口,获取prepay_id
* 步骤3:使用jsapi调起支付
*/
// include_once("./log_.php");//用写日志来代替断点
// $log_ = new Log_();
include_once("../WxPayPubHelper/WxPayPubHelper.php");
$agent = isset($_SERVER['HTTP_USER_AGENT']) ? strtolower($_SERVER['HTTP_USER_AGENT']) : '';//检测微信浏览器版本,5.0一下无微信支付
if (stripos($agent, 'micromessenger')) {
preg_match('/.*MicroMessenger\/(\d+\.\d+)\s?/i',$agent,$version);
if($version[1] < 5.0) return ;
}
if (!isset($_SESSION)) session_start();
$out_trade_no = isset($_GET['order_sn']) ? $_GET['order_sn'] : 1;//商户数据
$total_fee = isset($_GET['total_fee']) ? $_GET['total_fee'] : 1;
$result_url = 'http://xxx';
$error_url = 'http://xxx';
//使用jsapi接口
$jsApi = new JsApi_pub();
if (isset($_SESSION['openID']) && !empty($_SESSION['openID'])) {
$openid = $_SESSION['openID'];
}else{
//通过code获得openid
if (!isset($_GET['code'])) {
//$url = $jsApi->createOauthUrlForCode(WxPayConf_pub::JS_API_CALL_URL);
$redirectUrl = urlencode(WxPayConf_pub::JS_API_CALL_URL.'?total_fee='.$total_fee.'&order_sn='.$out_trade_no);//带上商户数据,否则跳转之后没有数据
//这里我用demo上的<span style="font-family: Arial, Helvetica, sans-serif;">createOauthUrlForCode 不能正常使用,所以我自己写拼装了一个url</span>
$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.WxPayConf_pub::APPID.'&redirect_uri='.$redirectUrl.'&response_type=code&scope=snsapi_base&state=1#wechat_redirect';
Header("Location: $url");
}else{
//获取code码,以获取openid
$code = $_GET['code'];
$jsApi->setCode($code);
$openid = $jsApi->getOpenId();
$_SESSION['openID'] = $openid;
}
}
//使用统一支付接口
$unifiedOrder = new UnifiedOrder_pub();
//设置统一支付接口参数
//设置必填参数
$unifiedOrder->setParameter("openid","$openid");//商品描述
$unifiedOrder->setParameter("body","wxPay");//商品描述
$unifiedOrder->setParameter("out_trade_no","$out_trade_no");//商户订单号
$unifiedOrder->setParameter("total_fee","$total_fee");//总金额
$unifiedOrder->setParameter("notify_url",WxPayConf_pub::NOTIFY_URL);//通知地址
$unifiedOrder->setParameter("trade_type","JSAPI");//交易类型
$prepay_id = $unifiedOrder->getPrepayId();
//=========步骤3:使用jsapi调起支付============
$jsApi->setPrepayId($prepay_id);
$jsApiParameters = $jsApi->getParameters();
?>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<title>微信安全支付</title>
<script type="text/javascript">
//调用微信JS api 支付
function jsApiCall()
{
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
<?php echo $jsApiParameters; ?>,
function(res){
//WeixinJSBridge.log(res.err_msg);
//alert(res.err_code+' >> '+res.err_desc+' >> '+res.err_msg);
if(res.err_msg == "get_brand_wcpay_request:ok"){
window.location.href = '<?php echo $result_url; ?>';
}
else window.location.href = '<?php echo $error_url; ?>';
}
);
}
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();
}
}
setTimeout('callpay()',1000);
/*
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady();
}
*/
</script>
</head>
<body>
<br/><br/><br/>
<div align="center">
正在跳转...
<!-- <button style="width:210px; height:30px; background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" οnclick="callpay()" >贡献一下</button>-->
</div>
</body>
</html>
以上是我根据官方js_call_api.php做了一些修改,这里根据自己需要编码
调试:
1. 使用log代替平时的断点
2. 一步步跟踪 在文件WxPayPubHelper.php
/**
* 获取prepay_id
*/
function getPrepayId()
{
$this->postXml();
$this->result = $this->xmlToArray($this->response);
//var_dump($this->result);//他会报告比较准确的信息 根据这个提示修改
$prepay_id = $this->result["prepay_id"];
return $prepay_id;
}
}
注意:
微信支付的总金额单位是分,支付宝是元 文档上有说明 我看的时候没仔细 吃亏了下面简单说下最后一环 回掉处理
四:回调处理
<?php
/**
* 通用通知接口demo
* ====================================================
* 支付完成后,微信会把相关支付和用户信息发送到商户设定的通知URL,
* 商户接收回调信息后,根据需要设定相应的处理流程。
*
* 这里举例使用log文件形式记录回调信息。
*/
$log_ = new WechatApi();//自己写的一个类,这里只是使用了日志功能 也可以使用官方的
$log_name="notify_url.log";//log文件路径
require_once("weiXinPay/GeneralType/WxPayPubHelper/WxPayPubHelper.php");
require_once("weiXinPay/GeneralType/WxPayPubHelper/WxPay.pub.config.php");
//使用通用通知接口
$notify = new Notify_pub();
//存储微信的回调
$xml = $GLOBALS['HTTP_RAW_POST_DATA'];<span style="white-space:pre"> </span>
$notify->saveData($xml);
//验证签名,并回应微信。
//对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,
//微信会通过一定的策略(如30分钟共8次)定期重新发起通知,
//尽可能提高通知的成功率,但微信不保证通知最终能成功。
if($notify->checkSign() == FALSE){
$notify->setReturnParameter("return_code","FAIL");//返回状态码
$notify->setReturnParameter("return_msg","签名失败");//返回信息
}else{
$notify->setReturnParameter("return_code","SUCCESS");//设置返回码
}
$returnXml = $notify->returnXml();
echo $returnXml;
if($notify->checkSign() == TRUE)
{
if ($notify->data["return_code"] == "FAIL") {
//此处应该更新一下订单状态,商户自行增删操作
$log_->writeLogInFile($log_name,"【通信出错】:\n".$xml."\n");
} elseif($notify->data["result_code"] == "FAIL"){
//此处应该更新一下订单状态,商户自行增删操作
$log_->writeLogInFile($log_name,"【业务出错】:\n".$xml."\n");
} else{
$wxpayName = $notify->data['trade_type'];
if(WxPayConf_pub::APPID == $notify->data['appid'] && WxPayConf_pub::MCHID == $notify->data['mch_id']) {
$total_fee = $notify->data['total_fee'];
$out_trade_no = $notify->data['out_trade_no'];
/*...*/
//校验支付信息
if ($pay_info['order_amount']*100 == $total_fee) {//单位
/*....*/
}else $log_->writeLogInFile($log_name,date(DATE_FORMAT).' 意外情况导致订单状态修改失败('.$wxpayName.'支付) 但用户可能已付款成功 需核对 订单号: '.$out_trade_no.' 用户id: '.$user_id);
}
}
//商户自行增加处理流程,
//例如:更新订单状态
//例如:数据库操作
//例如:推送支付完成信息
}
?>
以上便是微信支付 native与此类似
下图是微信发过来的数据截图
如有错误 多谢指正