基于PHP的微信支付教程
准备工作
关于微信支付
下载SDK



文件说明

文件夹-phpqrode存放了二维码功能相关文件 jsapi.php"网页调起支付页面;" notify.php"网页支付后的回调的页面;" native.php"付款二维码信息组装页面;" qrcode.php"生成二维码的页面" native_notify.php"扫描所生成二维码进入的页面;" notify.php"网页支付后的回调页面;" orderquery.php"订单查询页面;" download.php"查退款单页面;" refund.php"退款的页面;" refundquery.php"退款单查询的页面;" WxPay.JsApiPay.php"网页支付核心类;" WxPay.NativePay.php和WxPay.MicroPay.php"是刷卡支付类"
WxPay.Api.php"接口访问类,包含所有微信支付API列表的封装" WxPay.Config.php"配置信息所在文件"
WxPay.Data.php"签名相关类,含签名生成" WxPay.Exception.php"异常类" WxPay.Notify.php"回调函数的父类"
lib文件夹下的WxPay.Config.php

const APPID = ‘wx426b3015555a46be‘;//这个是微信提供的测试AppId,我们学习用它足以 const APPSECRET = ‘01c6d59a3f9024db6336662ac95c8e74‘; //也是微信提供的测试AppSecret
lib文件夹下的WxPay.Config.php
const MCHID = ‘1225312702‘; //这个也是微信提供的测试商户号

const KEY = ‘e10adc3949ba59abbe56e057f20f883e‘; //微信提供的测试支付密钥

const SSLCERT_PATH = ‘../cert/apiclient_cert.pem‘; //测试提供的私钥 const SSLKEY_PATH = ‘../cert/apiclient_key.pem‘; //测试提供的公钥
const CURL_PROXY_HOST = "0.0.0.0"; // 代理的IP,不需要代理,请设置为0.0.0.0和0 const CURL_PROXY_PORT = 0; //代理的端口,此时不开启代理(如有需要才设置) const REPORT_LEVENL = 1; //错误信息上报等级,0.关闭上报; 1.仅错误出错上报; 2.全量上报
网页设置







example文件夹下的 WxPay.JsApiPay.php
$input->SetOut_trade_no("32个字符内、可包含字母的商户订单号");
$input = new WxPayUnifiedOrder(); $input->SetOut_trade_no("32个字符内、可包含字母的商户订单号"); //其他的设置 $order = WxPayApi::unifiedOrder($input);
$input->SetOut_trade_no("对应下单时的订单号");
$input = new WxPayRefund(); $input->SetOut_trade_no("下单时的商户订单号"); //其他的设置 $order = WxPayApi::refund($input);
$input->SetOut_trade_no("下单时的商户订单号");
$input = new WxPayMicroPay(); $input->SetOut_trade_no("下单时的订单号"); //其他的设置 $microPay = new MicroPay(); $order = $microPay->pay($input);
$input->SetOut_trade_no("对应下单时的订单号");
$input = new WxPayOrderQuery(); $input->SetOut_trade_no("下单时的商户订单号"); //其他的设置 $order = WxPayApi::orderQuery($input);
$input->SetOut_trade_no("下单时的商户订单号");
$input = new WxPayRefundQuery(); $input->SetOut_trade_no("下单时的订单号"); //其他的设置 $order = WxPayApi::refundQuery($input);
注意事项
在JavaScript处理支付结果
//获取用户地址 function editAddress() { WeixinJSBridge.invoke( ‘editAddress‘, <?php echo $editAddress; ?>, function(res) { var value1 = res.proviceFirstStageName; var value2 = res.addressCitySecondStageName; var value3 = res.addressCountiesThirdStageName; var value4 = res.addressDetailInfo; var tel = res.telNumber; alert(value1 + value2 + value3 + value4 + ":" + tel); } ); }
//调用微信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); // 使用以上方式判断前端返回,微信团队郑重提示: // res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 if(res.err_msg == "get_brand_wcpay_request:ok" ) { // 支付成功 }else if((res.err_msg =="get_brand_wcpay_request:fail"){ // 支付失败 }else if((res.err_msg =="get_brand_wcpay_request:cancel"){ // 支付过程中用户取消 } } ); }
在回调链接中处理结果的入口
$input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");
require_once "../lib/WxPay.Api.php"; require_once ‘../lib/WxPay.Notify.php‘;
$notify = new PayNotifyCallBack(); $notify->Handle(false);
/** * 回调入口 * @param bool $needSign 是否需要签名输出 */ final public function Handle($needSign = true) { $msg = "OK"; //当返回false的时候,表示notify中调用NotifyCallBack回调失败 //若传入需要签名即传入true,获取签名校验失败,此时直接返回失败 //notify函数里面传入了NotifyCallBack回调函数名,这时候它会被调用 //$msg作为变量也传入了NotifyCallBack回调函数里面,$msg包含有支付信息 $result = WxpayApi::notify(array($this, ‘NotifyCallBack‘), $msg); if($result == false) { $this->SetReturn_code("FAIL"); $this->SetReturn_msg($msg); $this->ReplyNotify(false); return; } else { //该分支在成功回调到NotifyCallBack方法,处理完成之后流程 $this->SetReturn_code("SUCCESS"); $this->SetReturn_msg("OK"); } $this->ReplyNotify($needSign); }
重写回调函数自定义处理
/** * notify的回调方法,该方法中需要赋值需要输出的参数 * @param array $data * @return true回调出来完成不需要继续回调,false回调处理未完成需要继续回调 */ final public function NotifyCallBack($data) // $msg传进来 { $msg = "OK"; "//NotifyProcess就是我们要重写的函数" $result = $this->NotifyProcess($data, $msg); if($result == true){ $this->SetReturn_code("SUCCESS"); $this->SetReturn_msg("OK"); } else { $this->SetReturn_code("FAIL"); $this->SetReturn_msg($msg); } return $result; }
class PayNotifyCallBack extends WxPayNotify { //查询订单 public function Queryorder($transaction_id) { $input = new WxPayOrderQuery(); $input->SetTransaction_id($transaction_id); $result = WxPayApi::orderQuery($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; } //重写回调处理函数 public function NotifyProcess($data,&$msg) { //"$data" 是NotifyCallBack函数传进来的含有支付信息的参数 $notfiyOutput = array(); // 下面这句判断支付参数中是否含有微信订单号transaction_id if(!array_key_exists("transaction_id", $data)){ $msg = "输入参数不正确"; return false; } //查询订单,判断订单真实性,二重判断 if(!$this->Queryorder($data["transaction_id"])){ $msg = "订单查询失败"; return false; } // "这里返回真,证明支付成功了" // "我们也可以直接在这里做支付成功后的操作" return true; } }
订单查询
require_once "../lib/WxPay.Api.php";
require_once ‘log.php‘;
$tradeId = $_GET["out_trade_no"];
if(isset($tradeId) && $tradeId != "") { $input = new WxPayOrderQuery(); $input->SetOut_trade_no($tradeId); // 设置好要查询的订单 $order = WxPayApi::orderQuery($input)); // 进行查询 var_dump($order); // 打印出订单信息 }
if($order[‘err_code_des‘] =="order not exist"){ // 订单不存在 }else{ $money = $order[‘total_fee‘]; //所付款数,单位分 if($order[‘trade_state‘] =="SUCCESS"){ //支付成功 }else if($order[‘trade_state‘] =="REFUND"){ //已退款 }else if($order[‘trade_state‘] =="NOTPAY"){ //用户还没支付 }else if($order[‘trade_state‘] =="CLOSED"){ //订单关闭 }else if($order[‘trade_state‘] =="REVOKED"){ //已撤销(刷卡支付) }else if($order[‘trade_state‘] =="USERPAYING"){ //用户支付中 }else if($order[‘trade_state‘] =="PAYERROR"){ //支付失败(其他原因,例如银行返回失败) } }
$wxId = $_GET["transaction_id"];
if(isset($wxId) && $wxId != "") { $input = new WxPayOrderQuery(); $input->SetOut_trade_no($wxId); // 设置好要查询的订单 $order = WxPayApi::orderQuery($input)); // 进行查询 var_dump($order); // 打印出订单信息 }
申请退款
require_once "../lib/WxPay.Api.php";
require_once ‘log.php‘;
if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){ $out_trade_no = $_REQUEST["out_trade_no"]; // 要退款的订单的商户订单号 $total_fee = $_REQUEST["total_fee"]; // 该订单的一共支付总额 $refund_fee = $_REQUEST["refund_fee"]; // 要退款的钱数 $input = new WxPayRefund(); /** SetOut_trade_no 设置该订单的商户订单号,凭借这个唯一确定 */ $input->SetOut_trade_no($out_trade_no); /** SetTotal_fee 设置订单的当时支付的总额 */ $input->SetTotal_fee($total_fee); /** SetRefund_fee 设置要退款多少钱 */ $input->SetRefund_fee($refund_fee); /** SetOut_refund_no 设置此次商户退款的单号,它不是商户订单号 */ $input->SetOut_refund_no(WxPayConfig::MCHID.date("YmdHis")); /** SetOp_user_id 设置商户号 */ $input->SetOp_user_id(WxPayConfig::MCHID); /** 发起退款 */ $order = WxPayApi::refund($input); /** 在返回的数组中,我们能够获取键名return_code */ if($order["return_code"]=="SUCCESS"){ // 退款申请成功 }else if($order["return_code"]=="FAIL"){ // 退款申请失败 }else{ // 未知状态 } var_dump($order); }
查询退款
require_once "../lib/WxPay.Api.php";
require_once ‘log.php‘;
if(isset($_REQUEST["transaction_id"]) && $_REQUEST["transaction_id"] != ""){ $transaction_id = $_REQUEST["transaction_id"]; $input = new WxPayRefundQuery(); $input->SetTransaction_id($transaction_id); $order = WxPayApi::refundQuery($input); var_dump($order)$order; };
if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){ $out_trade_no = $_REQUEST["out_trade_no"]; $input = new WxPayRefundQuery(); $input->SetOut_trade_no($out_trade_no); $order = WxPayApi::refundQuery($input); var_dump($order)$order; }
/** SetOut_refund_no 设置此次退款的商户单号,它不是商户订单号 */ $input->SetOut_refund_no(WxPayConfig::MCHID.date("YmdHis"));
if(isset($_REQUEST["out_refund_no"]) && $_REQUEST["out_refund_no"] != ""){ $out_refund_no = $_REQUEST["out_refund_no"]; $input = new WxPayRefundQuery(); $input->SetOut_refund_no($out_refund_no); $order = WxPayApi::refundQuery($input); var_dump($order)$order; }
if(isset($_REQUEST["refund_id"]) && $_REQUEST["refund_id"] != ""){ $refund_id = $_REQUEST["refund_id"]; $input = new WxPayRefundQuery(); $input->SetRefund_id($refund_id); $order = WxPayApi::refundQuery($input); var_dump($order)$order; }
使用环境
支付凭据


获取 OpenId
lib文件夹下的 WxPay.Api.php 函数 public function GetOpenid($userName,$userSex) { //通过code获得openid //code在微信服务处理完成之后重定向时带回来的 if (!isset($_GET[‘code‘])) { // 假设现在我的支付代码文件的链接是: // http://hubwiz.com/WeChatPay/example/jsapi.php,那么下面就是 $baseUrl = urlencode("http://hubwiz.com/WeChatPay/example/jsapi.php?userName=".$userName."&userSex=".$userSex); $url = $this->__CreateOauthUrlForCode($baseUrl); Header("Location: $url"); // 重定向 exit(); } else { //获取code码,以获取openid $code = $_GET[‘code‘]; $openid = $this->getOpenidFromMp($code); return $openid;// 返回OpenId } }
确保已下订单
if(isset($tradeId) && $tradeId != "") { $input = new WxPayOrderQuery(); $input->SetOut_trade_no($tradeId); // 设置好要查询的订单 $order = WxPayApi::orderQuery($input)); // 进行查询 if($order[‘err_code_des‘] =="order not exist"){ // 订单不存在 }else{ $money = $order[‘total_fee‘]; //所付款数,单位分 if($order[‘trade_state‘] =="SUCCESS"){ //支付成功 //数据库操作 //两者对比 //若数据库中没记录,就恢复订单 }else if($order[‘trade_state‘] =="REFUND"){ //已退款 }else if($order[‘trade_state‘] =="NOTPAY"){ //用户还没支付 }else if($order[‘trade_state‘] =="CLOSED"){ //订单关闭 }else if($order[‘trade_state‘] =="REVOKED"){ //已撤销(刷卡支付) }else if($order[‘trade_state‘] =="USERPAYING"){ //用户支付中 }else if($order[‘trade_state‘] =="PAYERROR"){ //支付失败(其他原因,例如银行返回失败) } } }
基于SDK修改的Demo

<?php /** 请在下面设置你服务器的路径,默认是测试的,如果您没有自己的服务器,可以使用测试的 */ $jsApiPay = "http://paysdk.weixin.qq.com/example/jsapi.php"; /** 刷卡支付 */ $micropyPay = "http://paysdk.weixin.qq.com/example/micropay.php"; /** 扫码支付 */ $nativePay = "http://paysdk.weixin.qq.com/example/native.php"; /** 订单查询 */ $orderQuery = "http://paysdk.weixin.qq.com/example/orderquery.php"; /** 退款 */ $refundPay = "http://paysdk.weixin.qq.com/example/refund.php"; /** 退款查询 */ $refundQueryPay = "http://paysdk.weixin.qq.com/example/refundquery.php"; ?>
基于PHP的微信支付教程
原文:https://www.cnblogs.com/zdalongren/p/14481523.html