第一次集成微信的JSAPI支付,用的是官方的SDK,里面有demo方法,文件有很多,不是所有的文件都可以用得到,相信有很多小伙伴和我一样会遇到各种各样的小问题
官方的下载链接:https://pay.weixin.qq.com/wiki/doc/api/download/WxpayAPI_php.zip
下面是我这次SDK里用到的文件:
把上面的文件放到一个新建的文件夹再放到public目录下,放到public目录后先去修改WxPay.Config.php里的配置,需要修改appid、mchid、key、appsecret四个参数。
然后在入口文件index.php里添加如下代码:
// [ 应用入口文件 ]
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
define("APP_ROOT",dirname(__FILE__));
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
下面是所需的前后端代码:
前端JS方法
function immediately_pay() {
// 这里可以写你onclick事件需要获取传到后台的值
$.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
success: function (result) {
callpay(result);
}
});
}
function callpay(result)
{
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(result);
}
}
function jsApiCall(result) {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
"appId":result.appId, //公众号名称,由商户传入
"timeStamp":result.timeStamp, //时间戳,自1970年以来的秒数
"nonceStr":result.nonceStr, //随机串
"package":result.package,
"signType":result.signType, //微信签名方式:
"paySign":result.paySign //微信签名
},
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") {
alert("支付成功!");
// 支付成功可以进行页面跳转
} else if (res.err_msg == "get_brand_wcpay_request:cancel") {
alert("用户取消支付!");
} else {
alert("支付失败!");
}
});
}
后端Controller方法
public function immediately_pay()
{
ini_set('date.timezone','Asia/Shanghai');
require_once APP_ROOT."/weixin/WxPay.Api.php";
require_once APP_ROOT."/weixin/WxPay.JsApiPay.php";
require_once APP_ROOT."/weixin/log.php";
//初始化日志
//$logHandler= new \CLogFileHandler(APP_ROOT."/logs/".date('Y-m-d').'.log');
//$log = \Log::Init($logHandler, 15);
//①、获取用户openid
$tools = new \JsApiPay();
// 这里是获取openid的方法,因为授权登录后把用户的openid存起来了,所以这里用不到了
//$openId = $tools->GetOpenid();
//②、统一下单
$input = new \WxPayUnifiedOrder();
$input->SetBody("test"); //商品描述
$input->SetAttach("test"); //附加数据
$input->SetOut_trade_no("sdkphp".date("YmdHis")); //商户订单号
$input->SetTotal_fee("1"); //标价金额
$input->SetTime_start(date("YmdHis")); //交易起始时间
$input->SetTime_expire(date("YmdHis", time() + 600)); //交易结束时间
$input->SetGoods_tag("test"); //订单优惠标记
$input->SetNotify_url("http://paysdk.weixin.qq.com/notify.php"); //异步回调通知地址
$input->SetTrade_type("JSAPI"); //交易类型
// 下面是获取授权登录存入数据库里的openid
// ......
$input->SetOpenid($openid);
$config = new \WxPayConfig();
$order = \WxPayApi::unifiedOrder($config, $input);
$jsApiParameters = $tools->GetJsApiParameters($order);
// 把获得的json数据解析成数组
$result = json_decode($jsApiParameters);
return $result;
}
支付成功以后,微信会把相关支付结果和用户信息返回回来,通过回调方法接收处理,进行修改订单状态等业务逻辑,并返回应答。
下面在public下新建一个php页面,写入如下内容:
异步回调方法
require_once "weixin/WxPay.Api.php";
require_once 'weixin/WxPay.Notify.php';
require_once "weixin/WxPay.Config.php";
require_once 'weixin/log.php';
//初始化日志
//$logHandler= new CLogFileHandler("logs/".date('Y-m-d').'.log');
//$log = Log::Init($logHandler, 15);
class PayNotifyCallBack extends WxPayNotify
{
//查询订单
public function Queryorder($transaction_id)
{
$input = new WxPayOrderQuery();
$input->SetTransaction_id($transaction_id);
$config = new WxPayConfig();
$result = WxPayApi::orderQuery($config, $input);
Log::DEBUG("query:" . json_encode($result));
if(array_key_exists("return_code", $result)
&& array_key_exists("result_code", $result)
&& $result["return_code"] == "SUCCESS"
&& $result["result_code"] == "SUCCESS")
{
return true;
}
return false;
}
/**
*
* 回包前的回调方法
* 业务可以继承该方法,打印日志方便定位
* @param string $xmlData 返回的xml参数
*
**/
public function LogAfterProcess($xmlData)
{
Log::DEBUG("call back, return xml:" . $xmlData);
return;
}
//重写回调处理函数
/**
* @param WxPayNotifyResults $data 回调解释出的参数
* @param WxPayConfigInterface $config
* @param string $msg 如果回调处理失败,可以将错误信息输出到该方法
* @return true回调出来完成不需要继续回调,false回调处理未完成需要继续回调
*/
public function NotifyProcess($objData, $config, &$msg)
{
$data = $objData->GetValues();
//TODO 1、进行参数校验
if(!array_key_exists("return_code", $data)
||(array_key_exists("return_code", $data) && $data['return_code'] != "SUCCESS")) {
//TODO失败,不是支付成功的通知
//如果有需要可以做失败时候的一些清理处理,并且做一些监控
$msg = "异常异常";
return false;
}
if(!array_key_exists("transaction_id", $data)){
$msg = "输入参数不正确";
return false;
}
//TODO 2、进行签名验证
try {
$checkResult = $objData->CheckSign($config);
if($checkResult == false){
//签名错误
Log::ERROR("签名错误...");
return false;
}
} catch(Exception $e) {
Log::ERROR(json_encode($e));
}
//TODO 3、处理业务逻辑
Log::DEBUG("call back:" . json_encode($data));
$notfiyOutput = array();
// 这里进行修改订单状态等业务逻辑操作
//查询订单,判断订单真实性
if(!$this->Queryorder($data["transaction_id"])){
$msg = "订单查询失败";
return false;
}
return true;
}
}
$config = new WxPayConfig();
Log::DEBUG("begin notify");
$notify = new PayNotifyCallBack();
$notify->Handle($config, false);
至此就是我这次集成微信支付JSAPI的过程了,可以正常支付,修改订单状态,如果有更好方法的小伙伴欢迎在下面给我留言评论哦!