Files
CompanyProject/金壶/ydyd_service/application/common/WxPay.php
2024-09-27 01:32:49 +08:00

339 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\common;
use Exception;
use think\Db;
use think\facade\Cache;
use think\facade\Config;
use think\facade\Env;
use think\facade\Log;
require_once Env::get('extend_path').'wxpay/lib/WxPay.Api.php';
require_once Env::get('extend_path').'wxpay/lib/WxPay.Notify.php';
//require_once Env::get('extend_path').'wxpay/base/WxPay.NativePay.php';
require_once Env::get('extend_path').'wxpay/base/log.php';
require_once Env::get('extend_path').'wxpay/lib/WxPay.Config.Interface.php';
class WxPay
{
public function __construct()
{
//初始化日志,微信支付方面的日志单独存放
$logHandler= new \CLogFileHandler(Env::get('app_path')."WxPayLog/".date('Y-m-d').'.log');
$log = \Log::Init($logHandler, 15);
}
public function nativePay($pay_data) {
$notify = new NativePay();
//模式二
/**
* 流程:
* 1、调用统一下单取得code_url生成二维码
* 2、用户扫描二维码进行支付
* 3、支付完成之后微信服务器会通知支付成功
* 4、在支付成功通知中需要查单确认是否真正支付成功notify.php
*/
$input = new \WxPayUnifiedOrder();
$input->SetBody("医点医滴-单号:".$pay_data['order_sn']);
$input->SetAttach("自定义业务参数");
$input->SetOut_trade_no($pay_data['pay_no']);
$input->SetTotal_fee(number_format($pay_data['total_amount']*100,0,'.',''));
$input->SetTime_start(date("YmdHis"));
//$input->SetTime_expire(date("YmdHis", time() + 600));
//$input->SetGoods_tag("test");
$input->SetNotify_url(Config::get("WEB_ACCESS_CONFIG")["WXPAY_NOTIFY_URL"]);
$input->SetTrade_type("NATIVE");
$input->SetProduct_id($pay_data["order_sn"]);
$result = $notify->GetPayUrl($input);
$pay_url = '';
if (isset($result["code_url"])) {
$pay_url = $result["code_url"];
} else {
\Log::ERROR(json_encode($result));
}
if(substr($pay_url, 0, 6) == "weixin") {
return $pay_url;
}else{
return false;
//header('HTTP/1.1 404 Not Found');
}
}
public function makeQrcode($pay_url) {
require_once Env::get('extend_path').'wxpay/base/phpqrcode/phpqrcode.php';
return \QRcode::png($pay_url);
}
public function nativeNotify() {
$config = new WxPayConfig();
\Log::DEBUG("扫码支付回调信息");
$notify = new NativeNotifyCallBack();
$notify->Handle($config, true);
//为阻止TP发送调试信息
exit;
}
}
class NativePay
{
/**
*
* 生成扫描支付URL,模式一
* @param BizPayUrlInput $bizUrlInfo
*/
public function GetPrePayUrl($productId)
{
$biz = new \WxPayBizPayUrl();
$biz->SetProduct_id($productId);
try{
$config = new WxPayConfig();
$values = \WxpayApi::bizpayurl($config, $biz);
} catch(Exception $e) {
\Log::ERROR(json_encode($e));
}
$url = "weixin://wxpay/bizpayurl?" . $this->ToUrlParams($values);
return $url;
}
/**
*
* 参数数组转换为url参数
* @param array $urlObj
*/
private function ToUrlParams($urlObj)
{
$buff = "";
foreach ($urlObj as $k => $v)
{
$buff .= $k . "=" . $v . "&";
}
$buff = trim($buff, "&");
return $buff;
}
/**
*
* 生成直接支付url支付url有效期为2小时,模式二
* @param UnifiedOrderInput $input
*/
public function GetPayUrl($input)
{
if($input->GetTrade_type() == "NATIVE")
{
try{
$config = new WxPayConfig();
$result = \WxPayApi::unifiedOrder($config, $input);
return $result;
} catch(Exception $e) {
\Log::ERROR($e->getTraceAsString());
\Log::ERROR($e->errorMessage());
}
}
return false;
}
}
class WxPayConfig extends \WxPayConfigInterface
{
//=======【基本信息设置】=====================================
public function GetAppId()
{
return 'wxb537be7613530d10';
}
public function GetMerchantId()
{
return '1523746531';
}
//=======【支付相关配置:支付成功回调地址/签名方式】===================================
/**
* TODO:支付回调url
* 签名和验证签名方式, 支持md5和sha256方式
**/
public function GetNotifyUrl()
{
return "";
}
public function GetSignType()
{
return "HMAC-SHA256";
}
//=======【curl代理设置】===================================
/**
* TODO这里设置代理机器只有需要代理的时候才设置不需要代理请设置为0.0.0.0和0
* 本例程通过curl使用HTTP POST方法此处可修改代理服务器
* 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0此时不开启代理如有需要才设置
* @var unknown_type
*/
public function GetProxy(&$proxyHost, &$proxyPort)
{
$proxyHost = "0.0.0.0";
$proxyPort = 0;
}
//=======【上报信息配置】===================================
/**
* TODO接口调用上报等级默认紧错误上报注意上报超时间为【1s】上报无论成败【永不抛出异常】
* 不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少
* 开启错误上报。
* 上报等级0.关闭上报; 1.仅错误出错上报; 2.全量上报
* @var int
*/
public function GetReportLevenl()
{
return 1;
}
//=======【商户密钥信息-需要业务方继承】===================================
/*
* KEY商户支付密钥参考开户邮件设置必须配置登录商户平台自行设置, 请妥善保管, 避免密钥泄露
* 设置地址https://pay.weixin.qq.com/index.php/account/api_cert
*
* APPSECRET公众帐号secert仅JSAPI支付的时候需要配置 登录公众平台,进入开发者中心可设置), 请妥善保管, 避免密钥泄露
* 获取地址https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
* @var string
*/
public function GetKey()
{
return 'ad6abfe6e0fb3319f96e866fe7e33282';
}
public function GetAppSecret()
{
return '817855ea57fdb7bfc1d60fc3b4a4aaa3';
}
//=======【证书路径设置-需要业务方继承】=====================================
/**
* TODO设置商户证书路径
* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,
* API证书下载地址https://pay.weixin.qq.com/index.php/account/api_cert下载之前需要安装商户操作证书
* 注意:
* 1.证书文件不能放在web服务器虚拟目录应放在有访问权限控制的目录中防止被他人下载
* 2.建议将证书文件名改为复杂且不容易猜测的文件名;
* 3.商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。
* @var path
*/
public function GetSSLCertPath(&$sslCertPath, &$sslKeyPath)
{
$sslCertPath = Env::get('extend_path') . 'wxpay/cert/apiclient_cert.pem';
$sslKeyPath = Env::get('extend_path') . 'wxpay/cert/apiclient_key.pem';
}
}
class NativeNotifyCallBack extends \WxPayNotify
{
public function unifiedorder($openId, $product_id)
{
//统一下单
$config = new WxPayConfig();
$input = new \WxPayUnifiedOrder();
$input->SetBody("test");
$input->SetAttach("test");
$input->SetOut_trade_no($config->GetMerchantId().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("NATIVE");
$input->SetOpenid($openId);
//$input->SetProduct_id($product_id);
try {
$result = \WxPayApi::unifiedOrder($config, $input);
\Log::DEBUG("unifiedorder:" . json_encode($result));
} catch(Exception $e) {
\Log::ERROR(json_encode($e));
}
return $result;
}
/**
*
* 回包前的回调方法
* 业务可以继承该方法,打印日志方便定位
* @param string $xmlData 返回的xml参数
*
**/
public function LogAfterProcess($xmlData)
{
\Log::DEBUG("返回响应数据, return xml:" . $xmlData);
return;
}
/**
* @param WxPayNotifyResults $objData 回调解释出的参数
* @param WxPayConfigInterface $config
* @param string $msg 如果回调处理失败,可以将错误信息输出到该方法
* @return true回调出来完成不需要继续回调false回调处理未完成需要继续回调
*/
public function NotifyProcess($objData, $config, &$msg)
{
$data = $objData->GetValues();
//echo "处理回调";
//TODO 1、进行参数校验
//if(!array_key_exists("openid", $data) ||!array_key_exists("product_id", $data))
if(!array_key_exists("openid", $data) || !array_key_exists("out_trade_no", $data))
{
$msg = "回调数据异常";
\Log::DEBUG($msg . json_encode($data));
return false;
}
//TODO 2、进行签名验证
try {
$checkResult = $objData->CheckSign($config);
if($checkResult == false){
//签名错误
\Log::ERROR("签名错误...");
return false;
}
} catch(Exception $e) {
\Log::ERROR(json_encode($e));
}
Log::info('回调返回数据'.json_encode($data));
//处理业务逻辑
$this->SetData("result_code", "SUCCESS");
$this->SetData("err_code_des", "OK");
//$openid = $data["openid"];
//$product_id = $data["product_id"];
//TODO 3、处理业务逻辑
/*//统一下单,不知道样例里在做什么,响应参数里不需要这些值了
$result = $this->unifiedorder($openid, $product_id);
\Log::DEBUG('回调结果数据'. json_encode($data));
if(!array_key_exists("appid", $result) ||
!array_key_exists("mch_id", $result) ||
!array_key_exists("prepay_id", $result))
{
$msg = "统一下单失败";
\Log::DEBUG($msg . json_encode($data));
return false;
}
$this->SetData("appid", $result["appid"]);
$this->SetData("mch_id", $result["mch_id"]);
$this->SetData("nonce_str", \WxPayApi::getNonceStr());
$this->SetData("prepay_id", $result["prepay_id"]);
$this->SetData("result_code", "SUCCESS");
$this->SetData("err_code_des", "OK");
return true;*/
}
}