Ecshop微信支付JSAPI的接口 – 千丝海阁

首页 » Ecshop » Ecshop微信支付JSAPI的接口

Ecshop微信支付JSAPI的接口

3116 3

话说微信自从和支付宝大战之后,微信支付被逼得上线了,不然微信浏览器里是无法正常完成支付宝支付的,特别是做过授权登录的网站,如果想用第三方浏览器打开链接去调用支付宝支付的话,可能还会出现各种奇葩问题。而且一旦这些问题和钱搭上关系后,处理起来就必须谨慎再谨慎了。

被逼无奈下,加上手机版的微信支付接口,下面给出接口文件源码,其他文件,例如语言包啊,就自己写写吧。

<?php
/* 微信支付        */
/* V 1.0               */
/* by tiandi           */
/* www.tiandiyoyo.com  */
/* 2015.3.23          */

if (!defined('IN_ECTOUCH'))
{
    die('Hacking attempt');
}

$payment_lang = ROOT_PATH . 'lang/' .$GLOBALS['_CFG']['lang']. '/payment/wxpay.php';

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_online']  = '1';

    /* 作者 */
    $modules[$i]['author']  = 'tiandi';

    /* 网址 */
    $modules[$i]['website'] = 'http://www.tiandiyoyo.com';

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

    /* 配置信息 */
    $modules[$i]['config']  = array(
        array('name' => 'wxpay_appid',           'type' => 'text',   'value' => ''),
        array('name' => 'wxpay_mchid',            'type' => 'text',   'value' => ''),
        array('name' => 'wxpay_apikey',           'type' => 'text',   'value' => '')
    );

    return;
}


class wxpay {
	var $para;
	var $openid;
	
	function wxpay() 
	{
	}

	function __construct()
	{
	}

	function set_para($key,$value){
		$this->para[$key] = $value;
	}

	function get_code($order, $payment){
		$sql = "SELECT wxid FROM " .$GLOBALS['ecs']->table('users'). " WHERE user_id = ".$_SESSION['user_id'];
		$wxid = $GLOBALS['db']->getOne($sql);
		$apikey = $payment['wxpay_apikey'];
		$appid = $payment['wxpay_appid'];
		$callback_url = $GLOBALS['ecs']->url() . 'respond.php?code=wxpay';

		$ip = getIPaddress();
		$timestamp = time();
		$noncestr =  $this->create_noncestr();
		$this->set_para("nonce_str", $noncestr); //随机字符串
		$this->set_para("appid", $appid); //公众号
		$this->set_para("mch_id", $payment['wxpay_mchid']); //商户号
		//$this->set_para("device_info", 'WEB'); //终端设备号(商户的门店号或设备ID),注意:PC网页或公众号内支付请传"WEB"
		$this->set_para("body", $order['order_sn']); //商品或支付单简要描述
		$this->set_para("out_trade_no", $order['order_sn'] . 'O' . $order['log_id']); //商户订单号
		$this->set_para("total_fee", floor($order['order_amount']*100)); //付款金额,单位分
		$this->set_para("spbill_create_ip", $ip); // 终端地址
		$this->set_para("notify_url", $callback_url); //异步通知地址
		$this->set_para("trade_type", 'JSAPI'); //交易类型 JSAPI,NATIVE,APP
		$this->set_para("openid", $wxid); //用户openid

		$postxml = $this->create_xml($apikey); 

		$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
		$response = $this->curl_post_ssl($url, $postxml);

		$responseObj = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA);

		//print_r($responseObj);
		$prepay_id = "prepay_id=".$responseObj->prepay_id;
		$signkey = getkey($noncestr,$prepay_id,$timestamp,$appid,$apikey);


		$button = '<div style="text-align:center"><input type="button" onclick="onBridgeReady()" value="' .$GLOBALS['_LANG']['pay_button']. '" class="c-btn3" /></div>';
		$js = "<script>function onBridgeReady(){".
				"WeixinJSBridge.invoke(".
				"'getBrandWCPayRequest', {".
				"'appId' : '".$payment['wxpay_appid']."', ".   
                "'timeStamp':'".$timestamp."',".             
				"'nonceStr' : '".$noncestr."',".   
				"'package': '".$prepay_id."',".
				"'signType' : 'MD5',".          
				"'paySign' : '".$signkey."'".
			"},".
			"function(res){    ". 
           "if(res.err_msg == 'get_brand_wcpay_request:ok' ) ".
			   "{".
			   "alert('支付成功!');".
			   "window.location.href='user.php?act=order_list';". 
			   "}".
		   "else {".
			   "alert('支付失败!');".
		         "} });} ".
			" </script>";

        return $button.$js;	
	}

	function respond($postStr) {
		$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
		$responseObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
		$json = json_encode($responseObj);
		$res = json_decode($json, true);


		if($this->check_respond_date($res)) {
			$out_trade_no = $res['out_trade_no'];
			$out_trade_no = explode('O', $out_trade_no);
			$order_sn = $out_trade_no[0];//订单号
			$log_id = $out_trade_no[1];//订单号log_id

			if($res['return_code'] == 'SUCCESS' && $res['result_code'] == 'SUCCESS') {	
				// by tiandi 改变子订单状态 
				sub_order_paid($order_sn, $log_id, 2);
				/* 改变订单状态 */
				order_paid($order_sn, $log_id, 2);
				echo "success";
			} else {
				echo "fail";
			}
		}
		else 
			echo "fail";
	}

	function check_respond_date($res) {
		$sql = "SELECT pay_config FROM " .$GLOBALS['ecs']->table('touch_payment'). " WHERE pay_code = '".$res['code']."'";
		$result = $GLOBALS['db']->getOne($sql);
		$config = $this->unserialize_config($result);

		$apikey = $config['wxpay_apikey'];

		ksort($res);
		$tempsign = "";
		foreach ($res as $k => $v){
			if (null != $v && "null" != $v && "sign" != $k && "code" != $k) {
				$tempsign .= $k . "=" . $v . "&";
			}
		}
		$tempsign = substr($tempsign, 0, strlen($tempsign)-1); //去掉最后的&
		$tempsign .="&key=". $apikey;  //拼接APIKEY
		$sign = strtoupper(md5($tempsign));

		if($sign == $res['sign']) {
			
			return true; 
		}
		else {
			
			return false;
		}
	}

	function unserialize_config($cfg){
		if (is_string($cfg) && ($arr = unserialize($cfg)) !== false)
		{
			$config = array();
	        foreach ($arr AS $key => $val)
		    {
			    $config[$val['name']] = $val['value'];
			}
	        return $config;
		}
		else
		{
			return false;
		}
	}

	function create_noncestr( $length = 24 ) {  
		$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  
		$str ="";  
		for ( $i = 0; $i < $length; $i++ )  {  
			$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);   
		}  
		return $str;  
	}

	function check_sign_para(){
		
		if($this->para["appid"] == null || 
//			$this->para["device_info"] == null || 
			$this->para["mch_id"] == null || 
			$this->para["nonce_str"] == null || 
			$this->para["body"] == null || 
			$this->para["out_trade_no"] == null ||
			$this->para["total_fee"] == null || 
			$this->para["spbill_create_ip"] == null || 
			$this->para["notify_url"] == null || 
			$this->para["trade_type"] == null || 
			$this->para["openid"] == null 
			)
		{
			return false;
		}
		return true;

	}

	function create_sign($apikey){
		if($this->check_sign_para() == false) {
			echo "签名参数错误!";
		}
		ksort($this->para);
		$tempsign = "";
		foreach ($this->para as $k => $v){
			if (null != $v && "null" != $v && "sign" != $k) {
				$tempsign .= $k . "=" . $v . "&";
			}
		}
		$tempsign = substr($tempsign, 0, strlen($tempsign)-1); //去掉最后的&
		$tempsign .="&key=". $apikey;  //拼接APIKEY
		return strtoupper(md5($tempsign));
	}

	function create_xml($apikey){ 
		$this->set_para('sign', $this->create_sign($apikey));
		return $this->ArrayToXml($this->para);
	}

	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; 
    }

	function curl_post_ssl($url, $vars, $second=30)
	{
		$ch = curl_init();
		//超时时间
		curl_setopt($ch,CURLOPT_TIMEOUT,$second);
		curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);

		curl_setopt($ch,CURLOPT_URL,$url);
		curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
		curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
	
	 
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
	 
		curl_setopt($ch,CURLOPT_POST, 1);
		curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);
		
		$data = curl_exec($ch);
		if($data){
			curl_close($ch);
			return $data;
		}
		else { 
			$error = curl_errno($ch);
			curl_close($ch);
			return false;
		}
	}
}

function getIPaddress()
	{
    $IPaddress='';
    if (isset($_SERVER)){
        if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])){
            $IPaddress = $_SERVER["HTTP_X_FORWARDED_FOR"];
        } else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
            $IPaddress = $_SERVER["HTTP_CLIENT_IP"];
        } else {
            $IPaddress = $_SERVER["REMOTE_ADDR"];
        }
    } else {
        if (getenv("HTTP_X_FORWARDED_FOR")){
            $IPaddress = getenv("HTTP_X_FORWARDED_FOR");
        } else if (getenv("HTTP_CLIENT_IP")) {
            $IPaddress = getenv("HTTP_CLIENT_IP");
        } else {
            $IPaddress = getenv("REMOTE_ADDR");
        }
    }
    return $IPaddress;
}

function getkey($noncestr,$prepay_id,$timestamp,$appid,$apikey) {
	$tempsign = "appId=".$appid."&nonceStr=".$noncestr."&package=".$prepay_id."&signType=MD5&timeStamp=".$timestamp."&key=".$apikey;
	return strtoupper(md5($tempsign));
}
文章评分4次,平均分5.0

本文原始地址:https://www.tiandiyoyo.com/2015/04/wxpay_for_ecshop_by_php/
本站所有文章,除了特别注明外,均为本站原创,转载请注明出处来自www.tiandiyoyo.com

您可能还会对以下文章感兴趣:

评论前先开启评论开关:


3 Comments

  1. 10086 :

    明明支付成功了,看日志是失败的,貌似证书的原因,证书到底怎么用呢?

载入分页评论...