* @version : HUOSDK 8.0 */ namespace huolib\pay\driver; use think\Exception; use think\Log; require_once EXTEND_PATH."pay/wxpay/WxPay.Api.php"; require_once EXTEND_PATH."pay/wxpay/WxPay.Notify.php"; class WxNotifyCallBack extends \WxPayNotify { private $config = [ 'app_id' => '', /* 绑定支付的APPID(必须配置,开户邮件中可查看)*/ 'mch_id' => '', /* 商户号(必须配置,开户邮件中可查看) */ 'key' => '', /* 商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置) */ 'app_secret' => '', /* 公众帐号secert */ 'curl_proxy_host' => '0.0.0.0', 'curl_proxy_port' => '0', 'report_levenl' => '1', 'device_info' => 'WEB', /* 终端设备号(门店号或收银设备ID),默认请传"WEB" */ 'sslcert_path' => '', 'sslkey_path' => '', ]; function __construct() { $_conf_file = GLOBAL_CONF_PATH.'extra/pay/wxpay/config.php'; if (file_exists($_conf_file)) { $_config = include $_conf_file; } else { $_config = array(); } $this->config = array_merge($this->config, $_config); $this->config['sslcert_path'] = GLOBAL_CONF_PATH.'extra/pay/wxpay/cert/apiclient_cert.pem'; $this->config['sslkey_path'] = GLOBAL_CONF_PATH.'extra/pay/wxpay/cert/apiclient_key.pem'; } /** * 设置配置 * * @param array $config */ public function setConf($config = []) { $this->config['app_id'] = $config['app_id']; $this->config['mch_id'] = $config['mch_id']; $this->config['key'] = $config['key']; $this->config['app_secret'] = $config['app_secret']; } /** * @param string $order_id 订单号 * @param float $real_amount 浮点 * @param string $ip 下单IP地址 * @param string $product_id 商品ID * @param string $product_desc 商品描述 * @param string $notify_url 通知地址 * @param string $trade_type 交易类型 * * @param string $open_id * * @return bool|string|array * @throws \WxPayException */ public function unifiedOrder( $order_id, $real_amount, $ip, $product_id, $product_desc, $notify_url, $trade_type = 'APP', $open_id = '' ) { if (empty($notify_url)) { $notify_url = get_val($this->config, 'notify_url', ''); } // if ('JSAPI' == $trade_type) { // $this->config['app_id'] = $this->config['js_app_id']; // unset($this->config['js_app_id']); // $this->config['app_secret'] = $this->config['js_app_secret']; // unset($this->config['js_app_secret']); // } if ('MPAPI' == $trade_type) { $trade_type = 'JSAPI'; } //统一下单 $_input = new \WxPayUnifiedOrder(); $_input->SetAppid($this->config['app_id']);//公众账号ID $_input->SetMch_id($this->config['mch_id']);//商户号 $_input->SetDevice_info($this->config['device_info']);//设备号 $_input->SetBody($product_desc); /* 商品描述 */ $_input->SetAttach($product_id); /* 商品描述 */ $_input->SetOut_trade_no($order_id); /* 商户订单号 */ $_input->SetTotal_fee((int)($real_amount * 100)); /* 总金额 */ $_input->SetSpbill_create_ip($ip); /* 终端ip */ $_input->SetTime_start(date("YmdHis")); /* 交易起始时间 */ $_input->SetTime_expire(date("YmdHis", time() + 600)); /* 交易结束时间 */ $_input->SetNotify_url($notify_url); /* 通知地址 */ $_input->SetTrade_type($trade_type); /* 交易类型 */ $_input->setKey($this->config['key']); /* 商户支付密钥 */ if ('JSAPI' == $trade_type) { $_input->SetOpenid($open_id);//微信用户在商户对应appid下的唯一标识 } $result = \WxPayApi::unifiedOrder($_input, 6, $this->config); // Log::error('$result'.json_encode($result)); if ('FAIL' == $result['return_code']) { \think\Log::write($result, Log::ERROR); } if ('APP' == $trade_type) { /* APP--app支付 */ return $this->setRData($result); } else if ('MWEB' == $trade_type) { /* MWEB H5支付 */ return $result; } else if ('NATIVE' == $trade_type) { /* NATIVE 扫码支付 */ return $result; } else if ('JSAPI' == $trade_type) { /* JSAPI 微信内支付 */ return $this->setJsapiData($result); } return false; } /** * app支付参数设置 * * @param $result * * @return string */ public function setRData($result) { $_input = new \WxPayUnifiedOrder(); $_token['appid'] = $result['appid']; $_token['partnerid'] = $result['mch_id']; $_token['prepayid'] = $result['prepay_id']; $_token['package'] = 'Sign=WXPay'; $_token['noncestr'] = $result['nonce_str']; $_token['timestamp'] = time(); $_input->setKey($this->config['key']); $_input->FromArray($_token); $_token['sign'] = $_input->SetSign(); return json_encode($_token); } /** * JSAPI参数设置 * * @param $result * * @return bool|string */ public function setJsapiData($result) { if (!array_key_exists("appid", $result) || !array_key_exists("prepay_id", $result) || empty($result['prepay_id'])) { return false; } $_jsapi_class = new \WxPayJsApiPay(); $_jsapi_class->SetAppid($result["appid"]); $_ts = time(); $_jsapi_class->setKey($this->config['key']); $_jsapi_class->SetTimeStamp("$_ts"); $_jsapi_class->SetNonceStr(\WxPayApi::getNonceStr()); $_jsapi_class->SetPackage("prepay_id=".$result['prepay_id']); $_jsapi_class->SetSignType("MD5"); $_jsapi_class->SetPaySign($_jsapi_class->MakeSign()); $_parameters = json_encode($_jsapi_class->GetValues()); return $_parameters; } /** * @param string $order_id 商户系统内部订单号 * @param string $transaction_id 微信的订单号 * * @return bool|array */ public function orderQuery($order_id, $transaction_id = '', $trade_type = '') { //查询订单 $_input = new \WxPayOrderQuery(); $_input->SetOut_trade_no($order_id); /* 商户系统内部订单号 */ // $_input->SetTransaction_id($transaction_id); /* 微信的订单号,建议优先使用 */ if ('JSAPI' == $trade_type) { $this->config['app_id'] = $this->config['js_app_id']; unset($this->config['js_app_id']); $this->config['app_secret'] = $this->config['js_app_secret']; unset($this->config['js_app_secret']); } else { unset($this->config['js_app_id']); unset($this->config['js_app_secret']); } try { $_result = \WxPayApi::orderQuery($_input, 6, $this->config); if (isset($_result['trade_state'])) { return $_result['trade_state']; } } catch (\WxPayException $e) { return false; } return false; } /** * @param array $data * @param string $msg * * @return bool 回调出来完成不需要继续回调,false回调处理未完成需要继续回调 */ public function NotifyProcess($data, &$msg) { if (!array_key_exists("openid", $data) || !array_key_exists("mch_id", $data)) { $msg = "回调数据异常"; return false; } /* 商品ID */ $_product_id = $data['attach']; /* 商户订单号 */ $_out_trade_no = $data['out_trade_no']; /* 微信支付订单号 */ $_trade_no = $data['transaction_id']; /* 交易金额 */ $_amount = number_format($data['total_fee'] / 100, 2, '.', ''); try { $_class = $data['huo_order_class']; $_func = $data['huo_func']; if (class_exists($_class)) { $_order = new $_class(); $_rs = $_order->$_func($_product_id, $_out_trade_no, $_trade_no, $_amount, 'wxpay'); if (true == $_rs) { $msg = '支付通知成功'; return true; } } else { Log::write( "func=".__FUNCTION__."&class=".__CLASS__."&order_class=".$_class ."&func=".$_func, LOG::ERROR ); } $msg = '支付通知成功,内部处理失败'; return true; } catch (Exception $_e) { Log::write( "func=".__FUNCTION__."&class=".__CLASS__."&order_class=".$_class ."&func=".$_func."&err=".$_e->getMessage()."&errCode=".$_e->getCode(), LOG::ERROR ); $msg = '支付通知成功,内部处理失败'; return false; } } public function selfHandle($needSign = true, $order_class, $func) { $this->config['huo_order_class'] = $order_class; $this->config['huo_func'] = $func; $this->Handle($needSign, $this->config); } }