准备工作
1. WxPay.Config.php 文件不在lib中, 在example目录,将其复制到lib中.并依次设置相关账号
2.laravel 项目载入sdk,修改composer.json
> 适用于没有命名空间的sdk
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
//加载该目录的类
"app/Libs/wxpay"
]
},
正式代码
1.支付接口
//支付接口入口
public function wxpay(Request $request)
{
try{
//②、统一下单
$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");
$input->SetOpenid('xxx');
$config = new \WxPayConfig();
$order = \WxPayApi::unifiedOrder($config, $input);
//需要把统一下单接口服务器端返回的数据处理为前端需要的格式
$signature=$this->sign($config,$order);
return $signature;
} catch(Exception $e) {
Log::ERROR(json_encode($e));
}
}
/*
* 根据服务器端的参数封装成前台需要的格式
*/
private function sign($wxConfig,$wxOrder){
$jsApiPayData=new \WxPayJsApiPay();
//$appid从配置文件中读取
$appid="xxx";
$jsApiPayData->SetAppid($appid);
$jsApiPayData->SetTimeStamp((string)time());
$rand=md5(time().mt_rand(0,1000));
$jsApiPayData->SetNonceStr($rand);
$jsApiPayData->SetPackage("prepay_id=".$wxOrder['prepay_id']);
$jsApiPayData->SetSignType('MD5');
$sign=$jsApiPayData->MakeSign($wxConfig);
//生成数组方式
$rawData=$jsApiPayData->GetValues();
$rawData['paySign']=$sign;
//删除返回的appid,因为没用
unset($rawData['appId']);
return $rawData;
}
2.回调处理
回调接口: 接口类型必须为POST, 携带的数据格式为xml格式,回调路由里面不支持?params=xxx参数,会自动过滤掉.
//微信支付异步回调接口
public function wxnotify()
{
//通知频率为15/15/30/180/1800/1800/1800/3600 单位:秒
//这里使用的微信支付的sdk,对WxPayNotify的NotifyProcess进行继承和重写
$config = new \WxPayConfig();
$notify=new WxNotify();
//这里面不能调用重写的NotifyProcess方法,而是调用类的handle方法
$notify->Handle($config);
}
对sdk的NotifyProcess 进行继承和重写
class WxNotify extends \WxPayNotify
{
//重写微信回调通知函数
//用ngrox软件进行测试使用
public function NotifyProcess($objData, $config, &$msg)
{
//返回结果里面result_code为业务结果,return_code为通信结果,所以这里判断要用result_code判断
if ($objData['return_code'] == "SUCCESS") {
//获取订单号
$orderNo=$objData['out_trade_no'];
/*业务逻辑
1.检查库存量,超卖
2.更新这个订单的status状态
3.减库存*/
DB::beginTransaction(); //开启事务
try{
//获取数据库查询的订单号,伪代码
$order=Order::where('order_no',$orderNo)->get();
//因为微信的回调是不断进行的,需要判断哪些情况进行处理.
//这里需要加一个判断,只处理订单状态为未支付的,避免重复操作
if($order->status==1){
//1更新订单状态
//2消减库存量
}
DB::commit(); //提交
return true;
}catch (\Exception $e)
{
//日志记录错误
DB::rollback(); //回滚
return false;
}
}else{
//这里控制微信是否继续发送异步通知
return true;
}
}
}