首页 文章详情

ECSHOP PC 端微信扫码支付插件 支持 ecshop2.7.3 utf8 版本

| 1524 2018-01-11 02:03 0 0 0
UniSMS (合一短信)

根目录/includes/modules/payment/wxpay.php 主文件
<?php

/**

  • ECSHOP 微信扫码支付插件(模式二) V3.3版本
  • ============================================================================
  • 版权所有 2005-2014 麦穗网络 版权所有
  • 网站地址: http://www.maisui.net.cn
    */

if (!defined('IN_ECS')){
die('Hacking attempt');
}
$payment_lang = ROOT_PATH . 'languages/' .$GLOBALS['_CFG']['lang']. '/payment/wxpay.php';
$phpqrcode = ROOT_PATH . 'includes/modules/payment/phpqrcode/phpqrcode.php';
include("$phpqrcode");
if (file_exists($payment_lang))
{
global $_LANG;

include_once($payment_lang);

}

/ 模块的基本信息 /
if (isset($set_modules) && $set_modules == TRUE)
{
$i = isset($modules) ? count($modules) : 0;

/* 代码 */
$modules[$i]['code']    = basename(__FILE__, '.php');

/* 描述对应的语言项 */
$modules[$i]['desc']    = 'wxpay_desc';

/* 是否支持货到付款 */
$modules[$i]['is_cod']  = '0';

/* 是否支持在线支付 */
$modules[$i]['is_online']  = '1';

/* 作者 */
$modules[$i]['author']  = '麦穗网络';

/* 网址 */
$modules[$i]['website'] = 'http://mp.weixin.qq.com/';

/* 版本号 */
$modules[$i]['version'] = '3.3';

/* 配置信息 */
$modules[$i]['config']  = array(
    array('name' => 'wxpay_appid',           'type' => 'text',   'value' => 'wxca93dccf7f945c0c'),
    array('name' => 'wxpay_appsecret',       'type' => 'text',   'value' => '2a1d71868657ae6134208'),
    array('name' => 'wxpay_mchid',      'type' => 'text',   'value' => 'wd9'),      
    array('name' => 'wxpay_key',      'type' => 'text', 'value' => 'a79e4484bb8577618a7c5f11036249f1'),
    array('name' => 'wxpay_signtype',      'type' => 'text', 'value' => 'sha1')
);

return;

}

/**


  • */

class wxpay
{

/**
 * 构造函数
 *
 * @access  public
 * @param
 *
 * @return void
 */
var $parameters; //cft 参数
var $payments; //配置信息
function wxpay()
{
}

function __construct()
{
    $this->wxpay();
}

/**
 * 生成支付代码
 * @param   array   $order      订单信息
 * @param   array   $payment    支付方式信息
 */
function get_code($order, $payment)
{
    if (!defined('EC_CHARSET'))
    {
        $charset = 'utf-8';
    }
    else
    {
        $charset = EC_CHARSET;
    }
    $charset = strtoupper($charset);

    //配置参数
    $this->payments = $payment;
    //根目录url
    $root_url = str_replace('/', '/', $GLOBALS['ecs']->url());          
    echo $root_url;
    //商品描述
    $this->setParameter("body", "订单号".$order['order_sn']);
    //商品ID
    $this->setParameter("product_id", $order['order_sn']);      
    //商户订单号
    $this->setParameter("out_trade_no", $order['order_sn'] .'O'. $order['log_id']);
    //订单总金额
    $this->setParameter("total_fee", $order['order_amount'] * 100);
    //支付币种
    $this->setParameter("fee_type", "CNY");
    //通知URL
    $this->setParameter("notify_url", $root_url.'/notify/wxpay_wap.php');
    //订单生成的机器IP
    $this->setParameter("spbill_create_ip", real_ip());
    //交易类型
    $this->setParameter("trade_type", "NATIVE");

    //传入参数字符编码
    $this->setParameter("input_charset", $charset);
    //生成支付二维码url
    $codeurl = $this->GetPayUrl();      
    //生成支付二维码
    $mm = $this->getCode($codeurl); 
    $js = '<script type="text/javascript" language="javascript">
    var timer = window.setInterval(show, 3000); 
    function show() {
        Ajax.call("user.php?act=check_wxpay", "order_sn=" + '.$order['order_sn'].', check_wxpay_response, "POST","JSON");   
    }
    function check_wxpay_response(result)
    {
        if(result.message==1)
        {
            location=("http://'.$_SERVER['SERVER_NAME'].'/user.php");
        }       
    }</script>';    
    $button = $js.'<div style="text-align:center"><img src="http://'.$_SERVER['SERVER_NAME'] .'/qrcode.png" ></img></div>';     
    return $button;

}

/**
 * 响应操作
 */
function respond()
{
    if($_GET['status'] == 1){
        return true;
    }
    else{
        return false;
    }
}

// 设置请求参数
function setParameter($parameter, $parameterValue) {
    $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
}

// 生成扫描支付URL,模式二     
function GetPayUrl()
{   
    $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    $inputObj["appid"] = $this->payments['wxpay_appid']; //公众号ID
    $inputObj["mch_id"] = $this->payments['wxpay_mchid'];//商户号
    $inputObj["body"] = $this->parameters['body'];
    $inputObj["product_id"] = $this->parameters['product_id'];
    $inputObj["out_trade_no"] = $this->parameters['out_trade_no'];
    $inputObj["total_fee"] = $this->parameters['total_fee'];
    $inputObj["fee_type"] = $this->parameters['fee_type'];
    $inputObj["notify_url"] = $this->parameters['notify_url'];
    $inputObj["spbill_create_ip"] = $this->parameters['spbill_create_ip'];
    $inputObj["trade_type"] = $this->parameters['trade_type'];      
    $inputObj["nonce_str"] = $this->create_noncestr();      
    $inputObj["sign"] = $this->MakeSign($inputObj);
    $this->setParameter("sign", $this->MakeSign($inputObj));

    $xml = $this->ToXml($inputObj);
    $startTimeStamp = $this->getMillisecond();//请求开始时间
    $timeOut = 6;
    $response = $this->postXmlCurl($xml, $url, false, $timeOut);
    $result = $this->Init($response);
    $codeurl = $result["code_url"];
    return $codeurl;        
}

//生成随机数
function create_noncestr( $length = 32 ) {  
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  
    $str ="";  
    for ( $i = 0; $i < $length; $i++ )  {  
        $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);           
    }  
    return $str;  
}
//生成签名
function MakeSign($value)
{
    //签名步骤一:按字典序排序参数
    ksort($value);
    $string = $this->ToUrlParams($value);
    //签名步骤二:在string后加入KEY
    $string = $string . "&key=".$this->payments['wxpay_key'];
    //签名步骤三:MD5加密
    $string = md5($string);
    //签名步骤四:所有字符转为大写
    $result = strtoupper($string);
    return $result;
}
//参数数组转换为url参数
function ToUrlParams($urlObj)
{
    $buff = "";
    foreach ($urlObj as $k => $v)
    {
        $buff .= $k . "=" . $v . "&";
    }

    $buff = trim($buff, "&");
    return $buff;
}

// 设置参数时需要用到的字符处理函数 
function trimString($value){
    $ret = null;
    if (null != $value) {
        $ret = $value;
        if (strlen($ret) == 0) {
            $ret = null;
        }
    }
    return $ret;
}

function ToXml($value)
{
    if(!is_array($value) 
        || count($value) <= 0)
    {
        echo "数组数据异常!";
    }

    $xml = "<xml>";
    foreach ($value as $key=>$val)
    {
        if (is_numeric($val)){
            $xml.="<".$key.">".$val."</".$key.">";
        }else{
            $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
        }
    }
    $xml.="</xml>";
    return $xml; 
}
//获取毫秒级别的时间戳
function getMillisecond()
{
    //获取毫秒的时间戳
    $time = explode ( " ", microtime () );
    $time = $time[1] . ($time[0] * 1000);
    $time2 = explode( ".", $time );
    $time = $time2[0];
    return $time;
}
//以post方式提交xml到对应的接口url
function postXmlCurl($xml, $url, $useCert = false, $second = 30)
{       
    $ch = curl_init();
    //设置超时
    curl_setopt($ch, CURLOPT_TIMEOUT, $second);     

    curl_setopt($ch,CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
    //设置header
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    //要求结果为字符串且输出到屏幕上
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    if($useCert == true){
        //设置证书
        //使用证书:cert 与 key 分别属于两个.pem文件
        curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
        curl_setopt($ch,CURLOPT_SSLCERT, '../cert/apiclient_cert.pem');
        curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
        curl_setopt($ch,CURLOPT_SSLKEY, '../cert/apiclient_key.pem');
    }
    //post提交方式
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    //运行curl
    $data = curl_exec($ch);
    //返回结果
    if($data){
        curl_close($ch);
        return $data;
    } else { 
        $error = curl_errno($ch);
        curl_close($ch);
        echo "curl出错,错误码:$error";
    }
}

//将xml转为array
function Init($xml)
{           
    $value = $this->FromXml($xml);
    $this->CheckSign($value);
    return $value;
}
function FromXml($xml)
{   
    if(!$xml){
        echo "xml数据异常!";
    }
    //将XML转为array 
    $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);      
    return $values;
}
//检测签名
function CheckSign($value)
{
    if(!$this->IsSignSet($value)){
        return true;
    }

    $sign = $this->MakeSign($value);
    if($this->parameters['sign'] == $sign){
        return true;
    }       
}

//判断签名,详见签名生成算法是否存在 
function IsSignSet($value)
{
    return array_key_exists('sign', $value);
}

function getCode($value)
{
    $errorCorrectionLevel = 'L';//容错级别   
    $matrixPointSize = 6;//生成图片大小   
    //生成二维码图片   
    QRcode::png($value, 'qrcode.png', $errorCorrectionLevel, $matrixPointSize, 2);      
}   

}

?>
根目录/languages/zh_cn/payment/wxpay.php 语言文件
<?php

/**

  • ECSHOP 微信扫码支付(模式一)语言文件
  • ============================================================================
  • 版权所有 2005-2014 麦穗网络 版权所有
  • 网站地址: http://www.maisui.net.cn
  • ============================================================================
    */

global $_LANG;

$_LANG['wxpay'] = '微信扫码支付';
$_LANG['wxpay_desc'] = '微信支付,是基于客户端提供的服务功能。同时向商户提供销售经营分析、账户和资金管理的功能支持。用户通过扫描二维码、微信内打开商品页面购买等多种方式调起微信支付模块完成支付。';
$_LANG['wxpay_appid'] = '微信公众号AppId';
$_LANG['wxpay_appsecret'] = '微信公众号AppSecret';
$_LANG['wxpay_mchid'] = '商户号MCHID';
$_LANG['wxpay_key'] = '初始密钥Key';
$_LANG['wxpay_signtype'] = '签名方式';
$_LANG['wxpay_button'] = '立即用微信支付';
?>
根目录/notify/wxpay.php 支付回调文件
<?php

/**

  • V3.3版 微信支付异步响应操作 麦穗工作室 2015.02.09
    */

define('IN_ECS', true);
require(dirname(FILE) . '/../includes/init.php');
require(ROOT_PATH . 'includes/lib_payment.php');
require(ROOT_PATH . 'includes/lib_order.php');

/ 支付方式代码 /
$pay_code = 'wxpay';
/ 支付信息 /
$payment = get_payment($pay_code);

//存储微信的回调
$xml = $GLOBALS['HTTP_RAW_POST_DATA'];
$data = saveData($xml);
//验证签名,并回应微信
if(checkSign($data,$payment) == FALSE){
$returnParameters1=setReturnParameter("return_code","FAIL");//返回状态码
$returnParameters2=setReturnParameter("return_msg","签名失败");//返回信息
$returnParameters = array_merge($returnParameters1,$returnParameters2);
}else{
$returnParameters = setReturnParameter("return_code","SUCCESS");//设置返回码
}
$returnXml = returnXml($payment,$returnParameters);
echo $returnXml;
//以log文件形式记录回调信息
$log_name="./wxpay.log";//log文件路径
log_result($log_name,"【接收到的notify通知】:\n".$xml."\n");

if(checkSign($data,$payment) == TRUE)
{
if ($data["return_code"] == "FAIL") {
//此处应该更新一下订单状态,商户自行增删操作
log_result($log_name,"【通信出错】:\n".$xml."\n");
}
elseif($data["result_code"] == "FAIL"){
//此处应该更新一下订单状态,商户自行增删操作
log_result($log_name,"【业务出错】:\n".$xml."\n");
}
else{
$wxsn = $data["out_trade_no"] ;
$wxsn_arr = explode('O',$wxsn);
$order_sn = $wxsn_arr[0];
$log_id = $wxsn_arr[1];
order_paid($log_id,2);
$sql = 'UPDATE ' . $GLOBALS['ecs']->table('order_info') .
" SET order_status = '1', " .
" confirm_time = '" . gmtime() . "', " .
" pay_status = '2', " .
" pay_time = '".gmtime()."', " .
" money_paid = order_amount," .
" order_amount = 0 ".
"WHERE order_sn = '$order_sn'";
$GLOBALS['db']->query($sql);
log_result($log_name,"【支付成功】:\n".$xml."\n");
}
}

// 设置参数时需要用到的字符处理函数
function trimString($value){
$ret = null;
if (null != $value) {
$ret = $value;
if (strlen($ret) == 0) {
$ret = null;
}
}
return $ret;
}

function checkSign($data,$payment)
{
$tmpData = $data;
unset($tmpData['sign']);
$sign = getSign($tmpData,$payment);//本地签名
if ($data['sign'] == $sign) {
return TRUE;
}
return FALSE;
}
function getSign($Obj,$payment)
{
foreach ($Obj as $k => $v)
{
$Parameters[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = formatBizQueryParaMap($Parameters, false);
//echo '【string1】'.$String.'</br>';
//签名步骤二:在string后加入KEY
$String = $String."&key=".$payment['wxpaykey'];
//echo "【string2】".$String."</br>";
//签名步骤三:MD5加密
$String = md5($String);
//echo "【string3】 ".$String."</br>";
//签名步骤四:所有字符转为大写
$result
= strtoupper($String);
//echo "【result】 ".$result."</br>";
return $result
;
}
/**

  • 将微信的请求xml转换成关联数组,以方便数据处理
    */
    function saveData($xml)
    {
    $data = xmlToArray($xml);
    return $data;
    }
    /**

    • 作用:格式化参数,签名过程需要使用
      */
      function formatBizQueryParaMap($paraMap, $urlencode)
      {
      $buff = "";
      ksort($paraMap);
      foreach ($paraMap as $k => $v)
      {
      if($urlencode)
      {
      $v = urlencode($v);
      }
      //$buff .= strtolower($k) . "=" . $v . "&";
      $buff .= $k . "=" . $v . "&";
      }
      $reqPar;
      if (strlen($buff) > 0)
      {
      $reqPar = substr($buff, 0, strlen($buff)-1);
      }
      return $reqPar;
      }
      /**
    • 设置返回微信的xml数据
      */
      function setReturnParameter($parameter, $parameterValue)
      {
      $returnParameters[trimString($parameter)] = trimString($parameterValue);
      return $returnParameters;
      }
      /**
    • 将xml数据返回微信
      */
      function returnXml($payment,$returnParameters)
      {
      $returnXml = createXml($payment,$returnParameters);
      return $returnXml;
      }
      /**
    • 生成接口参数xml
      */
      function createXml($payment,$returnParameters)
      {
      if($returnParameters["return_code"] == "SUCCESS"){
      $returnParameters["appid"] = $payment['wxpay_appid'];//公众账号ID
      $returnParameters["mch_id"] = $payment['wxpay_mchid'];//商户号
      $returnParameters["nonce_str"] = create_noncestr();//随机字符串
      $returnParameters["sign"] = getSign($returnParameters);//签名
      }
      return arrayToXml($returnParameters);
      }
      /**
    • 作用:array转xml
      */
      function arrayToXml($arr)
      {
      $xml = "<xml>";
      foreach ($arr as $key=>$val)
      {
      if (is_numeric($val))
      {
      $xml.="<".$key.">".$val."</".$key.">";

      }
      else
      $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
      }
      $xml.="</xml>";
      return $xml;
      }
      /**

    • 作用:将xml转为array
      */
      function xmlToArray($xml)
      {
      //将XML转为array
      $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
      return $array_data;
      }
      //生成随机数
      function create_noncestr( $length = 32 ) {
      $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
      $str ="";
      for ( $i = 0; $i < $length; $i++ ) {
      $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
      }
      return $str;
      }
      // 打印log
      function log_result($file,$word)
      {
      $fp = fopen($file,"a");
      flock($fp, LOCK_EX) ;
      fwrite($fp,"执行日期:".strftime("%Y-%m-%d-%H:%M:%S",time())."\n".$word."\n\n");
      flock($fp, LOCK_UN);
      fclose($fp);
      }
      ?>
      注意:

根目录/includes/modules/payment/phpqrcode下面引入生成二维码的插件

扫码支付完成客户端浏览器并不知道,需要通过ajax轮询订单,在user.php加入
elseif($action == 'check_wxpay')elseif($action == 'check_wxpay'){    include_once('includes/cls_json.php'); $order_sn = $_POST['order_sn']; $result = array('error' => 0, 'message' => '0');    $json  = new JSON; if($order_sn != '') { $sql = "SELECT pay_status FROM". $ecs->table('order_info') ."WHERE order_sn = '$order_sn'"; $status = $db->getOne($sql); } if($status == 2) { $result['message'] = 1; } else { $result['message'] = 0; } die($json->encode($result));}
整个插件下载链接: https://pan.baidu.com/s/1sl3AiwH 密码: bpj1

good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter