ThinkPHP使用Paypal支付接口的模块开发

<?php
/**
 * 
 * PaypalAction.class.php
 * 
 * ThinkPHP Paypal支付接口模块
 * 
**/


class PaymentAction extends Action { 

/** 
* 自己的paypal账号 
*/ 
private $account = 'admin@gmail.com';

/** 
* paypal支付网关地址 
*/ 
private $gateway = 'https://www.paypal.com/cgi-bin/webscr?'; 

public function index() { 
	echo '<a href="'.U('Payment/order').'">Payment this order.</a>'; 
} 

/** 
  * 生成订单并跳转到Paypal进行支付 
  */ 
public function order() { 
	/** 
	* 自己的逻辑代码 
	* 判断是否登录、购买的哪个商品、购物车等等逻辑 
	* 当然可以调用Model更简单点 
	* 这里不在赘述 
	*/ 
	/** ...... **/ 

	$order_info	= array();	// 初始化订单数据 
	$order_id	= uniqid();	// 按照自己的规则生成订单号入库 

	/** 
	* 订单包含哪几种商品、谁买的、什么时间、几件 
	*/ 
	$order_info['order_id']		= $order_id; 
	$order_info['member_id']	= Session::get('member_id'); 
	/** .... **/ 

	$order = D('Order'); 

	if( $order->createOrder($order_info) ) { 
		unset($order,$order_info); 
		// 初始化准备提交到Paypal的数据 
		$pp_info = array();
		// 告诉Paypal,我的网站是用的我自己的购物车系统 
		$pp_info['cmd']			= '_xclick';
		// 告诉paypal,我的(商城的商户)Paypal账号,就是这钱是付给谁的 
		$pp_info['business']	= $this->account;
		// 用户将会在Paypal的支付页面看到购买的是什么东西,只做显示,没有什么特殊用途,
		// 如果是多件商品,则直接告诉用户,只支付某个订单就可以了 
		$pp_info['item_name']	= "支付订单:{$order_id}";
		$pp_info['amount']		= '13'; // 告诉Paypal,我要收多少钱 
		// 告诉Paypal,我要用什么货币。这里需要注意的是,由于汇率问题,
		// 如果网站提供了更改货币的功能,那么上面的amount也要做适当更改,
		// paypal是不会智能的根据汇率更改总额的 
		$pp_info['currency_code']	= 'USD';
		// 当用户成功付款后paypal会将用户自动引导到此页面。
		// 如果为空或不传递该参数,则不会跳转 
		$pp_info['return']		= 'http#//www.sjolzy.cn/index.php/payment/finish';	
		$pp_info['invoice']	= $order_id; 
		$pp_info['charset']	= 'utf-8'; 
		$pp_info['no_shipping']	= '1'; 
		$pp_info['no_note']		= '1'; 
		// 当跳转到paypal付款页面时,用户又突然不想买了。则会跳转到此页面 
		$pp_info['cancel_return']	= 'http#//www.sjolzy.com/index.php/product/view/pid/3';	
		// Paypal会将指定 invoice 的订单的状态定时发送到此URL 
		// (Paypal的此操作,是paypal的服务器和我方商城的服务器点对点的通信,用户感觉不到)
		$pp_info['notify_url']	= 'http#//www.sjolzy.com/index.php/payment/notify/orderid/'.$order_id; 
		$pp_info['rm']	= '2'; 
		$paypal_payment_url = $this->gateway.http_build_query($pp_info); 
		echo "<a href='{$paypal_payment_url}'>Go Paypal!</a>"; 
		unset($pp_info); 
	} else { 
		$this->error(L('order_create_fail')); 
	} 
} 

public function finish() { 
	$this->success('购买成功'); 
} 

public function notify() { 
	// 由于这个文件只有被Paypal的服务器访问,所以无需考虑做什么页面什么的,
	// 这个页面不是给人看的,是给机器看的 
	$order_id = (int) $_GET['orderid']; 
	$order_info = D('Order')->getOrderDetail($order_id); 

	// 由于该URL不仅仅只有Paypal的服务器能访问,其他任何服务器都可以向该方法发起请求。
	// 所以要判断请求发起的合法性,也就是要判断请求是否是paypal官方服务器发起的 

	// 拼凑 post 请求数据 
	$req = 'cmd=_notify-validate';// 验证请求 
	foreach ($_POST as $k=>$v){ 
		$v = urlencode(stripslashes($v)); 
		$req .= "&{$k}={$v}"; 
	} 

	$ch = curl_init(); 
	curl_setopt($ch,CURLOPT_URL,'http://www.paypal.com/cgi-bin/webscr'); 
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 
	curl_setopt($ch,CURLOPT_POST,1); 
	curl_setopt($ch,CURLOPT_POSTFIELDS,$req); 
	$res = curl_exec($ch); 
	curl_close($ch); 

	if( $res && !emptyempty($order_info) ) { 
		// 本次请求是否由Paypal官方的服务器发出的请求 
		if(strcmp($res, 'VERIFIED') == 0) { 
			/** 
			* 判断订单的状态 
			* 判断订单的收款人 
			* 判断订单金额 
			* 判断货币类型 
			*/ 
			if(($_POST['payment_status'] != 'Completed' && $_POST['payment_status'] != 'Pending')
			 OR ($_POST['receiver_email'] != $this->account)
			  OR ($_POST['mc_gross'] != 13)
			   OR ('USD' != $_POST['mc_currency'])) { 
			// 如果有任意一项成立,则终止执行。由于是给机器看的,所以不用考虑什么页面。直接输出即可 
				exit('fail'); 
			} else {// 如果验证通过,则证明本次请求是合法的 
				D('Order')->finishOrder($order_id);// 更改订单状态 
				exit('success'); 
			} 
		} else { 
			exit('fail'); 
		} 
	} 
} 
} 

?>

更多Paypal参数的使用参考:PayPal支付接口的PHP开发方式

js - 刷新框架及页面的方法总结

看一个简单的例子:

下面以三个页面分别命名为frame.html
top.html
bottom.html
为例来具体说明如何做。

frame.html 由上(top.html)下(bottom.html)两个页面组成,代码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> frame </TITLE>
</HEAD>
<frameset rows="50%,50%">
<frame name=top  src="top.html">
<frame name=bottom  src="bottom.html">
</frameset>
</HTML>

现在假设top.html (即上面的页面) 有七个button来实现对bottom.html (即下面的页面) 的刷新,可以用以下七种语句,哪个好用自己看着办了。

语句1. window.parent.frames[1].location.reload();
语句2. window.parent.frames.bottom.location.reload();
语句3. window.parent.frames["bottom"].location.reload();
语句4. window.parent.frames.item(1).location.reload();
语句5. window.parent.frames.item('bottom').location.reload();
语句6. window.parent.bottom.location.reload();
语句7. window.parent['bottom'].location.reload();

top.html 页面的代码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> top.html </TITLE>
 </HEAD>
<BODY>
<input type=button value="刷新1" onclick="window.parent.frames[1].location.reload()"><br>
<input type=button value="刷新2" onclick="window.parent.frames.bottom.location.reload()"><br>
<input type=button value="刷新3" onclick="window.parent.frames['bottom'].location.reload()"><br>
<input type=button value="刷新4" onclick="window.parent.frames.item(1).location.reload()"><br>
<input type=button value="刷新5" onclick="window.parent.frames.item('bottom').location.reload()"><br>
<input type=button value="刷新6" onclick="window.parent.bottom.location.reload()"><br>
<input type=button value="刷新7" onclick="window.parent['bottom'].location.reload()"><br>
</BODY>
</HTML>

下面是bottom.html页面源代码,为了证明下方页面的确被刷新了,在装载完页面弹出一个对话框。

bottom.html 页面的代码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> bottom.html </TITLE>
 </HEAD>
<BODY onload="alert('我被加载了!')">
<h1>This is the content in bottom.html.</h1>
</BODY>
</HTML>

释一下:
1.window指代的是当前页面,例如对于此例它指的是top.html页面。
2.parent指的是当前页面的父页面,也就是包含它的框架页面。例如对于此例它指的是framedemo.html。
3.frames是window对象,是一个数组。代表着该框架内所有子页面。
4.item是方法。返回数组里面的元素。
5.如果子页面也是个框架页面,里面还是其它的子页面,那么上面的有些方法可能不行。
 

Javascript刷新页面的几种方法

1   history.go(0)
2   location.reload()
3   location=location
4   location.assign(location)
5   document.execCommand('Refresh')
6   window.navigate(location)
7   location.replace(location)
8   document.URL=location.href

自动刷新页面的方法:

1.页面自动刷新:把如下代码加入<head>区域中
<meta http-equiv="refresh" content="20">
其中20指每隔20秒刷新一次页面.

2.页面自动跳转:把如下代码加入<head>区域中
<meta http-equiv="refresh" content="20;url=http://www.wyxg.com">
其中20指隔20秒后跳转到http://www.wyxg.com页面

3.页面自动刷新js版
<script language="JavaScript">
 function myrefresh()
 {
      window.location.reload();
 }
 setTimeout('myrefresh()',1000); //指定1秒刷新一次
</script>

ASP.NET如何输出刷新父窗口脚本语句

1.  this.response.write("<script>opener.location.reload();</script>"); 

2.  this.response.write("<script>opener.window.location.href = opener.window.location.href;</script>");  

3.  Response.Write("<script language=javascript>opener.window.navigate(''你要刷新的页.asp'');< /script>")


JS刷新框架的脚本语句

//如何刷新包含该框架的页面
用   
<script language=JavaScript>
  parent.location.reload();
</script>  

//子窗口刷新父窗口
<script language=JavaScript>
   self.opener.location.reload();
</script>

( 或 <a href="javascript:opener.location.reload()">
刷新
</a>  
)

//如何刷新另一个框架的页面
用   
<script language=JavaScript>
  parent.另一FrameID.location.reload();

</script>

如果想关闭窗口时刷新或者想开窗时刷新的话,在 <body> 中调用以下语句即 可。
<body onload="opener.location.reload()"> 开 窗时刷新
<body onUnload="opener.location.reload()"> 关 闭时刷新
<script language="javascript">
window.opener.document.location.reload()
</script>

电子商务知识扫盲

电子商务介绍

概念:电子商务,英文名ElectronicCommerce,简称EC。

电子商务模式(常见类):

B2B模式,BusinesstoBusiness-企业对企业,例子:阿里巴巴,生意宝(网盛科技)、慧聪网。

B2C模式,BusinesstoCustomer-企业对个人,例子:亚马逊,当当,凡客,时尚起义,走秀网。

C2C模式,CustomertoCustomer-个人对个人,例子:ebay,淘宝,拍拍,易趣。

电子商务专业名词(常见类)

SEM:SearchEngineMarketing的缩写,意即搜索引擎营销。

EDM:ElectronicDirectMarketing的缩写,就是电子邮件营销。

CPS:CostPerSales的缩写,即销售分成。

CPA:CostPerAction,每次动作成本,即根据每个访问者对网络广告所采取的行动收费的定价模式。对于用户行动有特别的定义,包括形成一次交易、获得一个注册用户、或者对网络广告的一次点击等。

CPM:(CostPerMille,或者CostPerThousand;CostPerImpressions)每千人成本。

CPC:(CostPerClick;CostPerThousandClick-Through)每点击成本。

ROI:ReturnOnInvestment的缩写,投资报酬率。

SEO:SearchEngineOptimization的缩写,搜索引擎优化。

转化率:ConversionRate的缩写,是指访问某一网站访客中,转化的访客占全部访客的比例。

UV:UniqueVister的缩写,独立访客。

AdWords:Google的关键词竞价广告。

Alexa:Alexa.com是专门发布网站世界排名的网站,网站排名有两种:综合排名和分类排名。

二跳率:二跳率,由99click最先提出,网站页面展开后,用户在页面上产生的首次点击被称为“二跳”,二跳的次数即为”二跳量”。二跳量与浏览量的比值称为页面的二跳率。

跳出率:跳出率是指浏览了一个页面就离开的用户占一组页面或一个页面访问次数的百分比。

人均访问页面:PV总和除以IP,即可获得每个人平均访问的页面数量。至少人均访问页面需要超过10个以上,才算是优质的用户。

电子商务商务常见营销方式

1.网络媒体:门户网站广告,客户端软件广告。

2.SEM:竞价排名,联盟广告。

3.EDM邮件营销:内部邮件群发,第三方平台,数据库整合营销等方式。

4.社区营销:BBS推广(发帖和活动)SNS。

5.CPS\代销:销售分成(一起发,成果网,创盟)。

6.SEO:搜索引擎优化。

7.积分营销:积分兑换,积分打折,积分购买等。

8.DM目录:传统单张目录,如麦考林,红孩子,凡客,PPG。

9.线下活动:会展,体验店等。

10.传统媒体:电视电台,报刊杂志。

网络营销主要机构

3大在线媒体广告代理服务商:好耶,华扬联众,龙拓。

3大在线营销创意服务商:奥美互动,阳狮互动Digitas,安瑞索思。

3大网络联盟广告服务商:亿码(一起发),linkTech,alimama。

3大小企业的基础性在线营销服务商:中企动力,上海火速,深圳时代赢客。

3大网络公关公司:蓝色光标,宣亚公关,新华美通。

3大SEO服务商:王通,点石团队,新竞争力。

3大营销2.0机构:陈格雷,陈墨网络推广机构,浪兄推广机构。

用数字衡量网络营销效果

--网络营销效果可以100%以数字来衡量

1.访问页面:网络推广的访问者访问5个页面以上才是有效流量。访问10个页面以上是高质量的流量,访问2个以下页面是垃圾流量。

2.停留时间:超过3分钟才是有效流量;超过6分钟是高质量流量;小于1分钟的是垃圾流量。

3.二跳率数据:推广来主页二跳率70%以上是高质量流量。

4.转化率数据:推广购买转化率为1%以上为高质量流量。

网络营销需要辩别好:真实流量与流量,有效流量与流量,自然流量与购买流量,PV高的流量与PV低的流量,商业流量与娱乐流量。

如何用数字判断一个网站

1.访问量:alexa,chinaz查询工具。

2.网络流行度:搜索网站名,搜索结果越多相对来说越流行。

3.行业排名:查询艾瑞的排名。

4.网络新闻曝光率:用baidu新闻搜索。

5.SEO表现:收录与PR,排名。

6.百度指数:百度指数是用以反映关键词在过去30天内的网络曝光率及用户关注度。

7.每天新增注册用户数=UV*1%=80000*1%=80

8.活跃用户=注册用户/10=100000*10%=10000

9.最高同时在线=活跃用户*20%=10000*20%=2000

10.收费交易客户数=活跃用户*5%=10000*5%=500

11.销售额:收费交易客户数*商品平均价格200=10000

Magento错误 - 缓存不足的解决方法

在货品处或者其他部分页面出现了一下几种错误提示:

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 30720 bytes) in /home/XXXXX/public_html/lib/Varien/Io/File.php on line 361

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 72897 bytes) in /home/XXXXX/public_html/lib/Varien/Image/Adapter/Gd2.php on line 155

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/XXXXX/public_html/lib/Varien/Image/Adapter/Gd2.php on line 332

这些报错乃是缓存不足导致,只要将缓存设置大一点就ok啦。

修改根目录下的,php.ini
.htaccess
文件里的memory_limit = 64M项,改为memory_limit = 128M.保存后上传覆盖。

到这个步骤后看看问题是否解决。

如是Magento系统如问题依旧。到Magento后台的缓存设置里勾选缓存选项下的:

【设置,布局,区块 HTML 输出,翻译,集合(Collections)数据,EAV 类型与属性以及,网络服务配置选项。】

到此问题就应该解决了。

如果你的问题非常的顽固。有的模版还会在页面的最底部出现报错信息。

甚至有网页打开报错,或是直接是空白。找到根目录下的 index.php 修改如下:

require_once $mageFilename;

#Varien_Profiler::enable();

#Mage::setIsDeveloperMode(true);

#ini_set(’display_errors’, 1);

ini_set(“memory_limit”,”128M”); <——————————————— 在此加入这一行。

umask(0);

Mage::run();

至此问题99%解决。

解决magento1.4.0.1使用gspay接口用ie8浏览器报错不能跳转的问题

目前公司站群magentog使用spay支付接口有两大大问题还未解决:

1. 初次注册用户下单不能采集用户信息到支付页面

2. 用ie8或ie系列浏览器使用gspay支付接口下单的时候,在跳转页面会报错:Notice: Undefined index:  HTTP_REFERER  in /app/code/local/Mage/Gspay/Block/Standard/Redirect.php on line 97

第一个问题尚在研究,第二个问题在下午闲下来的时候给解决了

起因:magento1.4.0.1 在下单页面选择gspay付款方式的时候,在跳转页面/Gspay/standard/redirect/
如果使用的是ie系列浏览器,会出现notice级别的错误:Notice: Undefined index:  HTTP_REFERER  in /app/code/local/Mage/Gspay/Block/Standard/Redirect.php on line 97

跟踪代码发现在app/code/local/Mage/Gspay/Block/Standard/Redirect.php 第97行gspay获取url并解析是采用:$host=parse_url($_SERVER['HTTP_REFERER']);这样的方式,这样在火狐完全可以正常,但用ie8的时候就取不到HTTP_REFERER
的值了(貌似是bug),最后动手完善代码,经测试正常可用!

把第97行的$host=parse_url($_SERVER['HTTP_REFERER']);替换成如下代码:

$http    = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') ? 'https' : 'http';
if( empty($_SERVER['HTTP_REFERER']) ){
    $host    = array(
            'scheme'    => $http,
            'host'        => $_SERVER['HTTP_HOST']
        );
}else{
    $host    = parse_url($_SERVER['HTTP_REFERER']);
}

留此帮助其他遇到相同情况的朋友,嘿嘿·~