**
thinkphp3/5 调用微信支付和退款
**
下载
链接:https://pan.baidu.com/s/1C1HjPXWsI_CvdEHP8hJz7Q 密码:e1u5
下载好WxpayV3放在vendor下
1.打开WxPayConfig。修改appid,mchid,key,APPSECRET
2.新建Wx.php类文件
<?php
namespace app\index\controller;
use think\Controller;
use think\Config;
use think\Db;
class Wx extends Controller
{
protected function _initialize(){
//全局引入微信支付类
Vendor('WxpayV3.WxPayPubHelper');
}
public function makeWxPreOrder(){
//传递过来的参数为订单商品总价格
/**
*
* 统一下单,WxPayUnifiedOrder中out_trade_no、body、total_fee、trade_type必填
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayUnifiedOrder $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
//$orderNo = "QDL2019092648565410";
//$totalPrice = 0.01;
//$openid = "";
//接收参数
$orderData = $this->request->param();
//记录日志
$wxOrderData = new \WxPayUnifiedOrder();
//唯一订单号
$wxOrderData->SetOut_trade_no($orderData['orderNo']);
//代表JSAPI模式,不要修改,公众号支付,H5,小程序都是这个
$wxOrderData->SetTrade_type('JSAPI');
//价格,单位为分
$wxOrderData->SetTotal_fee($orderData['totalPrice'] * 100);
//商品简介
$wxOrderData->SetBody('测试订单');//导阅订单
//使用小程序用户的openid
$wxOrderData->SetOpenid($orderData['openid']);
//异步回调验证路径,开发者自定义
$wxOrderData->SetNotify_url(Config::get('http').'/index/Wx/notify');
//这个是我又封装的一个生成签名的方法
$payInfo = array(
"paySgin"=>$this->getPaySignature($wxOrderData),
);
echo json_encode($payInfo);
}
private function getPaySignature($wxOrderData){
$wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
// 失败时不会返回result_code
if($wxOrder['return_code'] != 'SUCCESS' || $wxOrder['result_code'] !='SUCCESS'){
$file = fopen('./Log/wxPaylog.txt', 'a+');
fwrite($file,var_export($wxOrder,true));
}
$signature = $this->sign($wxOrder);
return $signature;
}
private function sign($wxOrder){
$jsApiPayData = new \WxPayJsApiPay();
//传入小程序appid
$jsApiPayData->SetAppid(\WxPayConfig::APPID);
//按照文档,要求是字符串类型
$jsApiPayData->SetTimeStamp((string)time());
//生成随机字符串
$rand = md5(time().mt_rand(0,1000));
$jsApiPayData->SetNonceStr($rand);
//拼接prepay_id,要注意拼接
$jsApiPayData->SetPackage('prepay_id='.$wxOrder['prepay_id']);
//签名方式md5
$jsApiPayData->SetSignType('md5');
//然后调用sdk自带的MakeSign方法生成签名
$sign = $jsApiPayData->MakeSign();
//然后在使用sdk自带方法获取到上面的我们赋值到成员属性生成的数组
$rawValues = $jsApiPayData->GetValues();
//然后我们在数组上加上生成的签名
$rawValues['paySign'] = $sign;
//删除appid,因为返回给客户端没有用,所以消除
unset($rawValues['appId']);
//返回
return $rawValues;
}
//支付成功,异步通知
public function notify(){
//接收微信返回的数据数据,返回的xml格式
$xmlData = file_get_contents('php://input');
//将xml格式转换为数组
$data = $this->FromXml($xmlData);
//用日志记录检查数据是否接受成功,验证成功一次之后,可删除。
$file = fopen('./Log/wxPaylog.txt', 'a+');
fwrite($file,var_export($data,true));
//记录一下,返回回来的签名,生成签名的时候,必须剔除sign字段。
$sign = $data['sign'];
unset($data['sign']);
if ($data['result_code'] == 'SUCCESS'){
//支付成功 变更订单信息业务代码
echo 'SUCCESS';
}else{
$file = fopen('./Log/wxPaylog.txt', 'a+');
fwrite($file,"错误信息:".$data['return_msg'].date("Y-m-d H:i:s"),time()."\r\n");
//支付失败
}
}
public function FromXml($xml){
if(!$xml){
echo "xml数据异常!";
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $data;
}
}
解析:
makeWxPreOrder函数传入订单号,申请人openid,总价。支付成功会异步调用notify函数。在notify函数中进行业务处理。处理完成,要输出 echo ‘SUCCESS’;(否则微信会一直请求此接口)
3微信生成二维码
public function demo(){
Vendor('WxpayV3.WxPayPubHelper');
$notify = new \NativePay();
$input = new \WxPayUnifiedOrder();
$input->SetBody("test");
$input->SetAttach("test");
$input->SetOut_trade_no('***********'.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/example/notify.php");//回调地址
$input->SetTrade_type("NATIVE");
$input->SetProduct_id("123456789");
$result = $notify->GetPayUrl($input);
$url2 = $result["code_url"];
echo 'http://paysdk.weixin.qq.com/example/qrcode.php?data='.urlencode($url2);//最终二维码
}
3.微信申请退款
public function adminBackWxPreOrder(){
$orderData = $this->request->param();
$file = fopen('./Log/wxPayBacklog.txt', 'a+');
fwrite($file,var_export($orderData,true));
if( empty($orderData['orderNo']) ){
// echo "订单号为空";exit;
$file = fopen('./Log/wxPayBacklog.txt', 'a+');
fwrite($file,var_export("订单号为空",true));
}
if( empty($orderData['totalPrice']) ){
// echo "订单金额为空";exit;
$file = fopen('./Log/wxPayBacklog.txt', 'a+');
fwrite($file,var_export("订单金额为空",true));
}
$wxOrderData = new \WxPayRefund();
//原订单号
$wxOrderData->SetOut_trade_no($orderData['orderNo']);
// 价格,单位为分
$wxOrderData->SetTotal_fee($orderData['totalPrice'] * 100); // 订单总价
$wxOrderData->SetRefund_fee($orderData["refund_fee"] * 100); // 退款金额
$wxOrderData->SetOp_user_id($wxOrderData->GetMch_id()); // 操作员 用户ID
// 退款订单号
$out_refund_no = create_cancel_num();
$wxOrderData->SetOut_refund_no($out_refund_no);
$wxOrder = \WxPayApi::refund($wxOrderData);
$file = fopen('./Log/wxPayBacklog.txt', 'a+');
fwrite($file,var_export($wxOrder,true));
$where["order_no"] = $orderData['orderNo'];
//查询订单信息
if( $wxOrder['result_code'] !='SUCCESS' ){
// 退款失败
}else{
// 退款成功
}
echo 'SUCCESS';exit;
}